Date: Sun, 03 Jul 2011 14:06:46 +0000 From: gk@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r223908 - in soc2011/gk/ino64-head/sys: cddl/contrib/opensolaris/uts/common/fs cddl/contrib/opensolaris/uts/common/fs/zfs cddl/contrib/opensolaris/uts/common/sys compat/linux compat/... Message-ID: <20110703140646.8434A106564A@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gk Date: Sun Jul 3 14:06:46 2011 New Revision: 223908 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=223908 Log: Remove readdir cookies, use directory seek offset from struct dirent Add d_off field to struct dirent. Field name is misleading because d_off represents seek offset of the next directory entry but not current one. Darwin has d_seekoff, but d_off is more widespread (Linux, OpenSolaris). Traditionally current directory offset was returned by VOP_READDIR in cookies array. All actual cookies users had off by one error and thus always skipped first entry at non zero offset: if (cookies) { /* * When using cookies, the vfs has the option of reading from * a different offset than that supplied (UFS truncates the * offset to a block boundary to make sure that it never reads * partway through a directory entry, even if the directory * has been compacted). */ while (len > 0 && ncookies > 0 && *cookiep <= off) { ^^^^^^^^^^^^^^^ (skip first entry with *cookiep == off) } } This code snippet also assumes that directory offsets monotonically increase which is incorrect at least for ZFS and tmpfs. Change all filesystems to set dirent.d_off value in VOP_READDIR. Simplify linux, svr4 and ibcs2 compat shims by using d_off. Modified: soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/sys/gfs.h soc2011/gk/ino64-head/sys/compat/linux/linux_file.c soc2011/gk/ino64-head/sys/compat/linux/linux_getcwd.c soc2011/gk/ino64-head/sys/compat/svr4/svr4_misc.c soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c soc2011/gk/ino64-head/sys/fs/coda/coda_vnops.c soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c soc2011/gk/ino64-head/sys/fs/fdescfs/fdesc_vnops.c soc2011/gk/ino64-head/sys/fs/hpfs/hpfs_vnops.c soc2011/gk/ino64-head/sys/fs/msdosfs/msdosfs_vnops.c soc2011/gk/ino64-head/sys/fs/ntfs/ntfs_vnops.c soc2011/gk/ino64-head/sys/fs/nwfs/nwfs_io.c soc2011/gk/ino64-head/sys/fs/nwfs/nwfs_vnops.c soc2011/gk/ino64-head/sys/fs/portalfs/portal_vnops.c soc2011/gk/ino64-head/sys/fs/pseudofs/pseudofs_vnops.c soc2011/gk/ino64-head/sys/fs/smbfs/smbfs_io.c soc2011/gk/ino64-head/sys/fs/smbfs/smbfs_vnops.c soc2011/gk/ino64-head/sys/fs/tmpfs/tmpfs_subr.c soc2011/gk/ino64-head/sys/fs/tmpfs/tmpfs_vnops.c soc2011/gk/ino64-head/sys/fs/udf/udf_vnops.c soc2011/gk/ino64-head/sys/fs/unionfs/union_subr.c soc2011/gk/ino64-head/sys/fs/unionfs/union_vnops.c soc2011/gk/ino64-head/sys/i386/ibcs2/ibcs2_misc.c soc2011/gk/ino64-head/sys/kern/vfs_default.c soc2011/gk/ino64-head/sys/kern/vfs_subr.c soc2011/gk/ino64-head/sys/kern/vfs_syscalls.c soc2011/gk/ino64-head/sys/kern/vnode_if.src soc2011/gk/ino64-head/sys/sys/dirent.h soc2011/gk/ino64-head/sys/sys/vnode.h soc2011/gk/ino64-head/sys/ufs/ufs/ufs_extattr.c soc2011/gk/ino64-head/sys/ufs/ufs/ufs_vnops.c Modified: soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c ============================================================================== --- soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c Sun Jul 3 14:06:46 2011 (r223908) @@ -258,8 +258,7 @@ * next - the offset of the next entry */ static int -gfs_readdir_emit_int(gfs_readdir_state_t *st, uio_t *uiop, offset_t next, - int *ncookies, u_long **cookies) +gfs_readdir_emit_int(gfs_readdir_state_t *st, uio_t *uiop, offset_t next) { int reclen, namlen; dirent64_t *dp; @@ -289,6 +288,7 @@ edp->ed_reclen = (ushort_t)reclen; } else { /* XXX: This can change in the future. */ + dp->d_off = next; dp->d_reclen = (ushort_t)reclen; dp->d_type = DT_DIR; dp->d_namlen = namlen; @@ -298,12 +298,6 @@ return (EFAULT); uiop->uio_loffset = next; - if (*cookies != NULL) { - **cookies = next; - (*cookies)++; - (*ncookies)--; - KASSERT(*ncookies >= 0, ("ncookies=%d", *ncookies)); - } return (0); } @@ -322,7 +316,7 @@ */ int gfs_readdir_emit(gfs_readdir_state_t *st, uio_t *uiop, offset_t voff, - ino64_t ino, const char *name, int eflags, int *ncookies, u_long **cookies) + ino64_t ino, const char *name, int eflags) { offset_t off = (voff + 2) * st->grd_ureclen; @@ -343,8 +337,7 @@ * Inter-entry offsets are invalid, so we assume a record size of * grd_ureclen and explicitly set the offset appropriately. */ - return (gfs_readdir_emit_int(st, uiop, off + st->grd_ureclen, ncookies, - cookies)); + return (gfs_readdir_emit_int(st, uiop, off + st->grd_ureclen)); } #ifdef sun @@ -373,8 +366,7 @@ * gfs_readdir_fini(). */ int -gfs_readdir_pred(gfs_readdir_state_t *st, uio_t *uiop, offset_t *voffp, - int *ncookies, u_long **cookies) +gfs_readdir_pred(gfs_readdir_state_t *st, uio_t *uiop, offset_t *voffp) { offset_t off, voff; int error; @@ -387,11 +379,11 @@ voff = off - 2; if (off == 0) { if ((error = gfs_readdir_emit(st, uiop, voff, st->grd_self, - ".", 0, ncookies, cookies)) == 0) + ".", 0)) == 0) goto top; } else if (off == 1) { if ((error = gfs_readdir_emit(st, uiop, voff, st->grd_parent, - "..", 0, ncookies, cookies)) == 0) + "..", 0)) == 0) goto top; } else { *voffp = voff; @@ -1014,8 +1006,8 @@ * Return 0 on success, or error on failure. */ int -gfs_dir_readdir(vnode_t *dvp, uio_t *uiop, int *eofp, int *ncookies, - u_long **cookies, void *data, cred_t *cr, int flags) +gfs_dir_readdir(vnode_t *dvp, uio_t *uiop, int *eofp, void *data, cred_t *cr, + int flags) { gfs_readdir_state_t gstate; int error, eof = 0; @@ -1031,15 +1023,15 @@ pino, ino, flags)) != 0) return (error); - while ((error = gfs_readdir_pred(&gstate, uiop, &off, ncookies, - cookies)) == 0 && !eof) { + while ((error = gfs_readdir_pred(&gstate, uiop, &off)) == 0 && + !eof) { if (off >= 0 && off < dp->gfsd_nstatic) { ino = dp->gfsd_inode(dvp, off); if ((error = gfs_readdir_emit(&gstate, uiop, - off, ino, dp->gfsd_static[off].gfse_name, 0, - ncookies, cookies)) != 0) + off, ino, dp->gfsd_static[off].gfse_name, 0)) + != 0) break; } else if (dp->gfsd_readdir) { @@ -1054,7 +1046,7 @@ next += dp->gfsd_nstatic + 2; if ((error = gfs_readdir_emit_int(&gstate, uiop, - next, ncookies, cookies)) != 0) + next)) != 0) break; } else { /* @@ -1098,42 +1090,14 @@ struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - int *ncookies; - u_long **a_cookies; } */ *ap; { vnode_t *vp = ap->a_vp; uio_t *uiop = ap->a_uio; cred_t *cr = ap->a_cred; int *eofp = ap->a_eofflag; - int ncookies = 0; - u_long *cookies = NULL; - int error; - if (ap->a_ncookies) { - /* - * Minimum entry size is dirent size and 1 byte for a file name. - */ - ncookies = uiop->uio_resid / (sizeof(struct dirent) - sizeof(((struct dirent *)NULL)->d_name) + 1); - cookies = malloc(ncookies * sizeof(u_long), M_TEMP, M_WAITOK); - *ap->a_cookies = cookies; - *ap->a_ncookies = ncookies; - } - - error = gfs_dir_readdir(vp, uiop, eofp, &ncookies, &cookies, NULL, - cr, 0); - - if (error == 0) { - /* Subtract unused cookies */ - if (ap->a_ncookies) - *ap->a_ncookies -= ncookies; - } else if (ap->a_ncookies) { - free(*ap->a_cookies, M_TEMP); - *ap->a_cookies = NULL; - *ap->a_ncookies = 0; - } - - return (error); + return (gfs_dir_readdir(vp, uiop, eofp, NULL, cr, 0)); } Modified: soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c ============================================================================== --- soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c Sun Jul 3 14:06:46 2011 (r223908) @@ -1168,8 +1168,6 @@ struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; } */ *ap; { vnode_t *vp = ap->a_vp; @@ -1188,7 +1186,7 @@ } if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) { vn_lock(ZTOV(dzp), LK_SHARED | LK_RETRY); - error = VOP_READDIR(ZTOV(dzp), uiop, cr, eofp, ap->a_ncookies, ap->a_cookies); + error = VOP_READDIR(ZTOV(dzp), uiop, cr, eofp); VN_URELE(ZTOV(dzp)); } else { *eofp = 1; Modified: soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c ============================================================================== --- soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Sun Jul 3 14:06:46 2011 (r223908) @@ -2297,7 +2297,7 @@ */ /* ARGSUSED */ static int -zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, int *ncookies, u_long **cookies) +zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp) { znode_t *zp = VTOZ(vp); iovec_t *iovp; @@ -2318,8 +2318,6 @@ uint8_t prefetch; boolean_t check_sysattrs; uint8_t type; - int ncooks; - u_long *cooks = NULL; int flags = 0; ZFS_ENTER(zfsvfs); @@ -2389,15 +2387,6 @@ } eodp = (struct edirent *)odp; - if (ncookies != NULL) { - /* - * Minimum entry size is dirent size and 1 byte for a file name. - */ - ncooks = uio->uio_resid / (sizeof(struct dirent) - sizeof(((struct dirent *)NULL)->d_name) + 1); - cooks = malloc(ncooks * sizeof(u_long), M_TEMP, M_WAITOK); - *cookies = cooks; - *ncookies = ncooks; - } /* * If this VFS supports the system attribute view interface; and * we're looking at an extended attribute directory; and we care @@ -2529,6 +2518,8 @@ */ odp->d_ino = objnum; odp->d_reclen = reclen; + /* NOTE: d_off is the offset for the *next* entry */ + next = &(odp->d_off); odp->d_namlen = strlen(zap.za_name); (void) strlcpy(odp->d_name, zap.za_name, odp->d_namlen + 1); odp->d_type = type; @@ -2553,18 +2544,11 @@ offset += 1; } - if (cooks != NULL) { - *cooks++ = offset; - ncooks--; - KASSERT(ncooks >= 0, ("ncookies=%d", ncooks)); - } + if (next) + *next = offset; } zp->z_zn_prefetch = B_FALSE; /* a lookup will re-enable pre-fetching */ - /* Subtract unused cookies */ - if (ncookies != NULL) - *ncookies -= ncooks; - if (uio->uio_segflg == UIO_SYSSPACE && uio->uio_iovcnt == 1) { iovp->iov_base += outcount; iovp->iov_len -= outcount; @@ -2588,11 +2572,6 @@ uio->uio_loffset = offset; ZFS_EXIT(zfsvfs); - if (error != 0 && cookies != NULL) { - free(*cookies, M_TEMP); - *cookies = NULL; - *ncookies = 0; - } return (error); } @@ -5825,13 +5804,10 @@ struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; } */ *ap; { - return (zfs_readdir(ap->a_vp, ap->a_uio, ap->a_cred, ap->a_eofflag, - ap->a_ncookies, ap->a_cookies)); + return (zfs_readdir(ap->a_vp, ap->a_uio, ap->a_cred, ap->a_eofflag)); } static int @@ -6550,7 +6526,7 @@ aiov.iov_base = (void *)dirbuf; aiov.iov_len = sizeof(dirbuf); auio.uio_resid = sizeof(dirbuf); - error = VOP_READDIR(vp, &auio, ap->a_cred, &eof, NULL, NULL); + error = VOP_READDIR(vp, &auio, ap->a_cred, &eof); done = sizeof(dirbuf) - auio.uio_resid; if (error != 0) break; Modified: soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/sys/gfs.h ============================================================================== --- soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/sys/gfs.h Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/cddl/contrib/opensolaris/uts/common/sys/gfs.h Sun Jul 3 14:06:46 2011 (r223908) @@ -102,8 +102,8 @@ int, int *, pathname_t *); extern int gfs_vop_lookup(vnode_t *, char *, vnode_t **, pathname_t *, int, vnode_t *, cred_t *, caller_context_t *, int *, pathname_t *); -extern int gfs_dir_readdir(vnode_t *, uio_t *, int *, int *, u_long **, void *, - cred_t *, int flags); +extern int gfs_dir_readdir(vnode_t *, uio_t *, int *, void *, cred_t *, + int flags); #define gfs_dir_lock(gd) mutex_enter(&(gd)->gfsd_lock) #define gfs_dir_unlock(gd) mutex_exit(&(gd)->gfsd_lock) @@ -132,9 +132,8 @@ extern int gfs_readdir_init(gfs_readdir_state_t *, int, int, uio_t *, ino64_t, ino64_t, int); extern int gfs_readdir_emit(gfs_readdir_state_t *, uio_t *, offset_t, ino64_t, - const char *, int, int *, u_long **); -extern int gfs_readdir_pred(gfs_readdir_state_t *, uio_t *, offset_t *, int *, - u_long **); + const char *, int); +extern int gfs_readdir_pred(gfs_readdir_state_t *, uio_t *, offset_t *); extern int gfs_readdir_fini(gfs_readdir_state_t *, int, int *, int); extern int gfs_get_parent_ino(vnode_t *, cred_t *, caller_context_t *, ino64_t *, ino64_t *); Modified: soc2011/gk/ino64-head/sys/compat/linux/linux_file.c ============================================================================== --- soc2011/gk/ino64-head/sys/compat/linux/linux_file.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/compat/linux/linux_file.c Sun Jul 3 14:06:46 2011 (r223908) @@ -332,8 +332,7 @@ struct l_dirent *linux_dirent; struct l_dirent64 *linux_dirent64; int buflen, error, eofflag, nbytes, justone; - u_long *cookies = NULL, *cookiep; - int ncookies, vfslocked; + int vfslocked; nbytes = args->count; if (nbytes == 1) { @@ -379,11 +378,6 @@ auio.uio_resid = buflen; auio.uio_offset = off; - if (cookies) { - free(cookies, M_TEMP); - cookies = NULL; - } - #ifdef MAC /* * Do directory search MAC check using non-cached credentials. @@ -391,8 +385,7 @@ if ((error = mac_vnode_check_readdir(td->td_ucred, vp))) goto out; #endif /* MAC */ - if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, - &cookies))) + if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag))) goto out; inp = buf; @@ -401,28 +394,7 @@ if ((len = buflen - auio.uio_resid) <= 0) goto eof; - cookiep = cookies; - - if (cookies) { - /* - * When using cookies, the vfs has the option of reading from - * a different offset than that supplied (UFS truncates the - * offset to a block boundary to make sure that it never reads - * partway through a directory entry, even if the directory - * has been compacted). - */ - while (len > 0 && ncookies > 0 && *cookiep <= off) { - bdp = (struct dirent *) inp; - len -= bdp->d_reclen; - inp += bdp->d_reclen; - cookiep++; - ncookies--; - } - } - while (len > 0) { - if (cookiep && ncookies == 0) - break; bdp = (struct dirent *) inp; reclen = bdp->d_reclen; if (reclen & 3) { @@ -432,12 +404,7 @@ if (bdp->d_fileno == 0) { inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += reclen; - + off = bdp->d_off; len -= reclen; continue; } @@ -464,9 +431,7 @@ if (is64bit) { linux_dirent64 = (struct l_dirent64*)lbuf; linux_dirent64->d_ino = bdp->d_fileno; - linux_dirent64->d_off = (cookiep) - ? (l_off_t)*cookiep - : (l_off_t)(off + reclen); + linux_dirent64->d_off = bdp->d_off; linux_dirent64->d_reclen = (l_ushort)linuxreclen; linux_dirent64->d_type = bdp->d_type; strlcpy(linux_dirent64->d_name, bdp->d_name, @@ -475,9 +440,7 @@ } else if (!justone) { linux_dirent = (struct l_dirent*)lbuf; linux_dirent->d_ino = bdp->d_fileno; - linux_dirent->d_off = (cookiep) - ? (l_off_t)*cookiep - : (l_off_t)(off + reclen); + linux_dirent->d_off = bdp->d_off; linux_dirent->d_reclen = (l_ushort)linuxreclen; /* * Copy d_type to last byte of l_dirent buffer @@ -492,12 +455,7 @@ goto out; inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += reclen; - + off = bdp->d_off; outp += linuxreclen; resid -= linuxreclen; len -= reclen; @@ -518,9 +476,6 @@ td->td_retval[0] = nbytes - resid; out: - if (cookies) - free(cookies, M_TEMP); - VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); Modified: soc2011/gk/ino64-head/sys/compat/linux/linux_getcwd.c ============================================================================== --- soc2011/gk/ino64-head/sys/compat/linux/linux_getcwd.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/compat/linux/linux_getcwd.c Sun Jul 3 14:06:46 2011 (r223908) @@ -211,8 +211,7 @@ error = mac_vnode_check_readdir(td->td_ucred, uvp); if (error == 0) #endif /* MAC */ - error = VOP_READDIR(uvp, &uio, td->td_ucred, &eofflag, - 0, 0); + error = VOP_READDIR(uvp, &uio, td->td_ucred, &eofflag); off = uio.uio_offset; Modified: soc2011/gk/ino64-head/sys/compat/svr4/svr4_misc.c ============================================================================== --- soc2011/gk/ino64-head/sys/compat/svr4/svr4_misc.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/compat/svr4/svr4_misc.c Sun Jul 3 14:06:46 2011 (r223908) @@ -241,8 +241,6 @@ off_t off; struct svr4_dirent64 svr4_dirent; int buflen, error, eofflag, nbytes, justone, vfslocked; - u_long *cookies = NULL, *cookiep; - int ncookies; DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n", uap->fd, uap->nbytes)); @@ -288,19 +286,13 @@ auio.uio_resid = buflen; auio.uio_offset = off; - if (cookies) { - free(cookies, M_TEMP); - cookies = NULL; - } - #ifdef MAC error = mac_vnode_check_readdir(td->td_ucred, vp); if (error) goto out; #endif - error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, - &ncookies, &cookies); + error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag); if (error) { goto out; } @@ -312,28 +304,7 @@ goto eof; } - cookiep = cookies; - - if (cookies) { - /* - * When using cookies, the vfs has the option of reading from - * a different offset than that supplied (UFS truncates the - * offset to a block boundary to make sure that it never reads - * partway through a directory entry, even if the directory - * has been compacted). - */ - while (len > 0 && ncookies > 0 && *cookiep <= off) { - bdp = (struct dirent *) inp; - len -= bdp->d_reclen; - inp += bdp->d_reclen; - cookiep++; - ncookies--; - } - } - while (len > 0) { - if (cookiep && ncookies == 0) - break; bdp = (struct dirent *) inp; reclen = bdp->d_reclen; if (reclen & 3) { @@ -344,11 +315,7 @@ if (bdp->d_fileno == 0) { inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += reclen; + off = bdp->d_off; len -= reclen; continue; } @@ -365,18 +332,14 @@ svr4_dirent.d_off = (svr4_off_t) svr4reclen; svr4_dirent.d_reclen = (u_short) bdp->d_namlen; } else { - svr4_dirent.d_off = (svr4_off_t)(off + reclen); + svr4_dirent.d_off = (svr4_off_t) bdp->d_off; svr4_dirent.d_reclen = (u_short) svr4reclen; } strlcpy(svr4_dirent.d_name, bdp->d_name, sizeof(svr4_dirent.d_name)); if ((error = copyout((caddr_t)&svr4_dirent, outp, svr4reclen))) goto out; inp += reclen; - if (cookiep) { - off = *cookiep++; - ncookies--; - } else - off += reclen; + off = bdp->d_off; outp += svr4reclen; resid -= svr4reclen; len -= reclen; @@ -397,8 +360,6 @@ VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); - if (cookies) - free(cookies, M_TEMP); free(buf, M_TEMP); return error; } @@ -421,8 +382,7 @@ struct svr4_dirent idb; off_t off; /* true file offset */ int buflen, error, eofflag, vfslocked; - u_long *cookiebuf = NULL, *cookie; - int ncookies = 0, *retval = td->td_retval; + int *retval = td->td_retval; if (uap->nbytes < 0) return (EINVAL); @@ -468,8 +428,7 @@ * First we read into the malloc'ed buffer, then * we massage it into user space, one record at a time. */ - error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, - &cookiebuf); + error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag); if (error) { goto out; } @@ -480,22 +439,19 @@ if ((len = buflen - auio.uio_resid) == 0) goto eof; - for (cookie = cookiebuf; len > 0; len -= reclen) { + for (; len > 0; len -= reclen) { bdp = (struct dirent *)inp; reclen = bdp->d_reclen; if (reclen & 3) panic("svr4_sys_getdents64: bad reclen"); - if (cookie) - off = *cookie++; /* each entry points to the next */ - else - off += reclen; - if ((off >> 32) != 0) { + if ((bdp->d_off >> 32) != 0) { uprintf("svr4_sys_getdents64: dir offset too large for emulated program"); error = EINVAL; goto out; } if (bdp->d_fileno == 0) { inp += reclen; /* it is a hole; squish it out */ + off = bdp->d_off; continue; } svr4_reclen = SVR4_RECLEN(&idb, bdp->d_namlen); @@ -510,13 +466,14 @@ * the copyout() call). */ idb.d_ino = (svr4_ino_t)bdp->d_fileno; - idb.d_off = (svr4_off_t)off; + idb.d_off = (svr4_off_t)bdp->d_off; idb.d_reclen = (u_short)svr4_reclen; strlcpy(idb.d_name, bdp->d_name, sizeof(idb.d_name)); if ((error = copyout((caddr_t)&idb, outp, svr4_reclen))) goto out; /* advance past this real entry */ inp += reclen; + off = dbp->d_off; /* advance output past SVR4-shaped entry */ outp += svr4_reclen; resid -= svr4_reclen; @@ -533,8 +490,6 @@ VOP_UNLOCK(vp, 0); VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); - if (cookiebuf) - free(cookiebuf, M_TEMP); free(buf, M_TEMP); return error; } Modified: soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c ============================================================================== --- soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/fs/cd9660/cd9660_vnops.c Sun Jul 3 14:06:46 2011 (r223908) @@ -368,8 +368,6 @@ struct uio *uio; off_t uio_off; int eofflag; - u_long *cookies; - int ncookies; }; static int @@ -382,22 +380,13 @@ dp->d_name[dp->d_namlen] = 0; dp->d_reclen = GENERIC_DIRSIZ(dp); + dp->d_off = off; if (idp->uio->uio_resid < dp->d_reclen) { idp->eofflag = 0; return (-1); } - if (idp->cookies) { - if (idp->ncookies <= 0) { - idp->eofflag = 0; - return (-1); - } - - *idp->cookies++ = off; - --idp->ncookies; - } - if ((error = uiomove(dp, dp->d_reclen, idp->uio)) != 0) return (error); idp->uio_off = off; @@ -464,8 +453,6 @@ struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; } */ *ap; { struct uio *uio = ap->a_uio; @@ -482,8 +469,6 @@ int error = 0; int reclen; u_short namelen; - int ncookies = 0; - u_long *cookies = NULL; dp = VTOI(vdp); imp = dp->i_mnt; @@ -498,18 +483,6 @@ idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = DT_UNKNOWN; idp->uio = uio; - if (ap->a_ncookies == NULL) { - idp->cookies = NULL; - } else { - /* - * Guess the number of cookies needed. - */ - ncookies = uio->uio_resid / 16; - cookies = malloc(ncookies * sizeof(u_long), - M_TEMP, M_WAITOK); - idp->cookies = cookies; - idp->ncookies = ncookies; - } idp->eofflag = 1; idp->curroff = uio->uio_offset; idp->uio_off = uio->uio_offset; @@ -622,23 +595,12 @@ if (error < 0) error = 0; - if (ap->a_ncookies != NULL) { - if (error) - free(cookies, M_TEMP); - else { - /* - * Work out the number of cookies actually used. - */ - *ap->a_ncookies = ncookies - idp->ncookies; - *ap->a_cookies = cookies; - } - } - if (bp) brelse (bp); uio->uio_offset = idp->uio_off; - *ap->a_eofflag = idp->eofflag; + if (ap->a_eofflag != NULL) + *ap->a_eofflag = idp->eofflag; free(idp, M_TEMP); Modified: soc2011/gk/ino64-head/sys/fs/coda/coda_vnops.c ============================================================================== --- soc2011/gk/ino64-head/sys/fs/coda/coda_vnops.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/fs/coda/coda_vnops.c Sun Jul 3 14:06:46 2011 (r223908) @@ -1462,8 +1462,6 @@ struct uio *uiop = ap->a_uio; struct ucred *cred = ap->a_cred; int *eofflag = ap->a_eofflag; - u_long **cookies = ap->a_cookies; - int *ncookies = ap->a_ncookies; struct thread *td = ap->a_uio->uio_td; /* upcall decl */ /* locals */ @@ -1508,8 +1506,7 @@ CODADEBUG(CODA_READDIR, myprintf(("indirect readdir: fid = %s, " "refcnt = %d\n", coda_f2s(&cp->c_fid), vp->v_usecount));); vn_lock(cp->c_ovp, LK_SHARED | LK_RETRY); - error = VOP_READDIR(cp->c_ovp, uiop, cred, eofflag, ncookies, - cookies); + error = VOP_READDIR(cp->c_ovp, uiop, cred, eofflag); VOP_UNLOCK(cp->c_ovp, 0); if (error) MARK_INT_FAIL(CODA_READDIR_STATS); Modified: soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c ============================================================================== --- soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/fs/devfs/devfs_vnops.c Sun Jul 3 14:06:46 2011 (r223908) @@ -1171,7 +1171,6 @@ struct devfs_dirent *de; struct devfs_mount *dmp; off_t off; - int *tmp_ncookies = NULL; if (ap->a_vp->v_type != VDIR) return (ENOTDIR); @@ -1180,27 +1179,9 @@ if (uio->uio_offset < 0) return (EINVAL); - /* - * XXX: This is a temporary hack to get around this filesystem not - * supporting cookies. We store the location of the ncookies pointer - * in a temporary variable before calling vfs_subr.c:vfs_read_dirent() - * and set the number of cookies to 0. We then set the pointer to - * NULL so that vfs_read_dirent doesn't try to call realloc() on - * ap->a_cookies. Later in this function, we restore the ap->a_ncookies - * pointer to its original location before returning to the caller. - */ - if (ap->a_ncookies != NULL) { - tmp_ncookies = ap->a_ncookies; - *ap->a_ncookies = 0; - ap->a_ncookies = NULL; - } - dmp = VFSTODEVFS(ap->a_vp->v_mount); - if (devfs_populate_vp(ap->a_vp) != 0) { - if (tmp_ncookies != NULL) - ap->a_ncookies = tmp_ncookies; + if (devfs_populate_vp(ap->a_vp) != 0) return (EIO); - } error = 0; de = ap->a_vp->v_data; off = 0; @@ -1215,26 +1196,21 @@ else de = dd; dp = dd->de_dirent; - if (dp->d_reclen > uio->uio_resid) - break; dp->d_fileno = de->de_inode; + dp->d_off = off + dp->d_reclen; if (off >= uio->uio_offset) { - error = vfs_read_dirent(ap, dp, off); - if (error) + error = vfs_read_dirent(ap, dp); + if (error != 0) { + if (error < 0) + error = 0; break; + } } off += dp->d_reclen; } sx_xunlock(&dmp->dm_lock); uio->uio_offset = off; - /* - * Restore ap->a_ncookies if it wasn't originally NULL in the first - * place. - */ - if (tmp_ncookies != NULL) - ap->a_ncookies = tmp_ncookies; - return (error); } @@ -1429,7 +1405,7 @@ if (ap->a_vp->v_type != VDIR) return (EINVAL); - return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL, NULL, NULL)); + return (VOP_READDIR(ap->a_vp, ap->a_uio, ap->a_cred, NULL)); } static int Modified: soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c ============================================================================== --- soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/fs/ext2fs/ext2_lookup.c Sun Jul 3 14:06:46 2011 (r223908) @@ -140,7 +140,6 @@ int count, error; struct ext2fs_direct_2 *edp, *dp; - int ncookies; struct dirent dstdp; struct uio auio; struct iovec aiov; @@ -148,6 +147,7 @@ int DIRBLKSIZ = VTOI(ap->a_vp)->i_e2fs->e2fs_bsize; int readcnt; off_t startoffset = uio->uio_offset; + off_t offset; count = uio->uio_resid; /* @@ -161,6 +161,8 @@ count -= (uio->uio_offset + count) & (DIRBLKSIZ -1); if (count <= 0) count += DIRBLKSIZ; + else if (count > MAXBSIZE) + count = MAXBSIZE; auio = *uio; auio.uio_iov = &aiov; auio.uio_iovcnt = 1; @@ -172,8 +174,8 @@ error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred); if (error == 0) { readcnt = count - auio.uio_resid; + offset = startoffset; edp = (struct ext2fs_direct_2 *)&dirbuf[readcnt]; - ncookies = 0; bzero(&dstdp, offsetof(struct dirent, d_name)); for (dp = (struct ext2fs_direct_2 *)dirbuf; !error && uio->uio_resid > 0 && dp < edp; ) { @@ -197,22 +199,23 @@ dstdp.d_type = FTTODT(dp->e2d_type); dstdp.d_namlen = dp->e2d_namlen; dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp); + dstdp.d_off = offset + dp->e2d_reclen; bcopy(dp->e2d_name, dstdp.d_name, dstdp.d_namlen); bzero(dstdp.d_name + dstdp.d_namlen, dstdp.d_reclen - offsetof(struct dirent, d_name) - dstdp.d_namlen); if (dp->e2d_reclen > 0) { - if(dstdp.d_reclen <= uio->uio_resid) { - /* advance dp */ - dp = (struct ext2fs_direct_2 *) - ((char *)dp + dp->e2d_reclen); - error = - uiomove(&dstdp, dstdp.d_reclen, uio); - if (!error) - ncookies++; - } else + error = vfs_read_dirent(ap, &dstdp); + if (error != 0) { + if (error < 0) + error = 0; break; + } + /* advance dp */ + offset += dp->e2d_reclen; + dp = (struct ext2fs_direct_2 *) + ((char *)dp + dp->e2d_reclen); } else { error = EIO; break; @@ -220,26 +223,7 @@ } /* we need to correct uio_offset */ uio->uio_offset = startoffset + (caddr_t)dp - dirbuf; - - if (!error && ap->a_ncookies != NULL) { - u_long *cookiep, *cookies, *ecookies; - off_t off; - - if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) - panic("ext2_readdir: unexpected uio from NFS server"); - cookies = malloc(ncookies * sizeof(u_long), M_TEMP, - M_WAITOK); - off = startoffset; - for (dp = (struct ext2fs_direct_2 *)dirbuf, - cookiep = cookies, ecookies = cookies + ncookies; - cookiep < ecookies; - dp = (struct ext2fs_direct_2 *)((caddr_t) dp + dp->e2d_reclen)) { - off += dp->e2d_reclen; - *cookiep++ = (u_long) off; - } - *ap->a_ncookies = ncookies; - *ap->a_cookies = cookies; - } + MPASS(offset == uio->uio_offset); } free(dirbuf, M_TEMP); if (ap->a_eofflag) Modified: soc2011/gk/ino64-head/sys/fs/fdescfs/fdesc_vnops.c ============================================================================== --- soc2011/gk/ino64-head/sys/fs/fdescfs/fdesc_vnops.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/fs/fdescfs/fdesc_vnops.c Sun Jul 3 14:06:46 2011 (r223908) @@ -490,8 +490,6 @@ struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - u_long *a_cookies; - int a_ncookies; } */ *ap; { struct uio *uio = ap->a_uio; @@ -503,9 +501,6 @@ if (VTOFDESC(ap->a_vp)->fd_type != Froot) panic("fdesc_readdir: not dir"); - if (ap->a_ncookies != NULL) - *ap->a_ncookies = 0; - off = (int)uio->uio_offset; if (off != uio->uio_offset || off < 0 || (u_int)off % UIO_MX != 0 || uio->uio_resid < UIO_MX) @@ -528,6 +523,7 @@ bcopy("..", dp->d_name, dp->d_namlen); dp->d_name[i + 1] = '\0'; dp->d_type = DT_DIR; + dp->d_off = (i + 1) * UIO_MX; break; default: if (fdp->fd_ofiles[fcnt] == NULL) @@ -536,6 +532,7 @@ dp->d_reclen = UIO_MX; dp->d_type = DT_UNKNOWN; dp->d_fileno = i + FD_DESC; + dp->d_off = (i + 1) * UIO_MX; break; } if (dp->d_namlen != 0) { Modified: soc2011/gk/ino64-head/sys/fs/hpfs/hpfs_vnops.c ============================================================================== --- soc2011/gk/ino64-head/sys/fs/hpfs/hpfs_vnops.c Sun Jul 3 13:27:23 2011 (r223907) +++ soc2011/gk/ino64-head/sys/fs/hpfs/hpfs_vnops.c Sun Jul 3 14:06:46 2011 (r223908) @@ -58,7 +58,7 @@ #include <fs/hpfs/hpfs_ioctl.h> static int hpfs_de_uiomove(struct hpfsmount *, struct hpfsdirent *, - struct uio *); + int num, struct uio *); static vop_ioctl_t hpfs_ioctl; static vop_read_t hpfs_read; static vop_write_t hpfs_write; @@ -769,6 +769,7 @@ hpfs_de_uiomove ( struct hpfsmount *hpmp, struct hpfsdirent *dep, + int num, struct uio *uio) { struct dirent cde; @@ -787,6 +788,7 @@ cde.d_fileno = dep->de_fnode; cde.d_type = (dep->de_flag & DE_DIR) ? DT_DIR : DT_REG; cde.d_reclen = sizeof(struct dirent); + cde.d_off = (num + 1) * sizeof(struct dirent); error = uiomove((char *)&cde, sizeof(struct dirent), uio); if (error) @@ -799,6 +801,7 @@ static struct dirent hpfs_de_dot = { .d_fileno = 0, + .d_off = sizeof(struct dirent), .d_reclen = sizeof(struct dirent), .d_type = DT_DIR, .d_namlen = 1, @@ -806,6 +809,7 @@ }; static struct dirent hpfs_de_dotdot = { .d_fileno = 0, + .d_off = sizeof(struct dirent) * 2, .d_reclen = sizeof(struct dirent), .d_type = DT_DIR, .d_namlen = 2, @@ -817,15 +821,14 @@ struct vnode *a_vp; struct uio *a_uio; struct ucred *a_cred; - int *a_ncookies; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110703140646.8434A106564A>