linux ls fails on DEVFS /dev because linux_getdents fails because

linux_getdents uses VOP_READDIR( ..., &ncookies, &cookies ) instead of
     VOP_READDIR( ..., NULL, NULL ) because it seems to need the offsets for
     linux_dirent and sizeof(dirent) != sizeof(linux_dirent)...

PR:	29467
Submitted by:	Michael Reifenberger <root@nihil.plaut.de>
Reviewed by:	phk
This commit is contained in:
Poul-Henning Kamp 2001-08-14 06:42:32 +00:00
parent dd6ba956da
commit 12d1aec26f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81620

View File

@ -499,14 +499,14 @@ devfs_readdir(ap)
struct devfs_dirent *dd;
struct devfs_dirent *de;
struct devfs_mount *dmp;
off_t off;
off_t off, oldoff;
int ncookies = 0;
u_long *cookiebuf, *cookiep;
struct dirent *dps, *dpe;
if (ap->a_vp->v_type != VDIR)
return (ENOTDIR);
if (ap->a_ncookies)
return (EOPNOTSUPP);
uio = ap->a_uio;
if (uio->uio_offset < 0)
return (EINVAL);
@ -517,6 +517,7 @@ devfs_readdir(ap)
error = 0;
de = ap->a_vp->v_data;
off = 0;
oldoff = uio->uio_offset;
TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
if (dd->de_flags & DE_WHITEOUT)
continue;
@ -529,12 +530,29 @@ devfs_readdir(ap)
break;
dp->d_fileno = de->de_inode;
if (off >= uio->uio_offset) {
ncookies++;
error = uiomove((caddr_t)dp, dp->d_reclen, uio);
if (error)
break;
}
off += dp->d_reclen;
}
if( !error && ap->a_ncookies != NULL && ap->a_cookies != NULL ) {
MALLOC(cookiebuf, u_long *, ncookies * sizeof(u_long),
M_TEMP, M_WAITOK);
cookiep = cookiebuf;
dps = (struct dirent *)
(uio->uio_iov->iov_base - (uio->uio_offset - oldoff));
dpe = (struct dirent *) uio->uio_iov->iov_base;
for( dp = dps;
dp < dpe;
dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
oldoff += dp->d_reclen;
*cookiep++ = (u_long) oldoff;
}
*ap->a_ncookies = ncookies;
*ap->a_cookies = cookiebuf;
}
lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curproc);
uio->uio_offset = off;
return (error);