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/...

gk at FreeBSD.org gk at FreeBSD.org
Sun Jul 3 14:06:48 UTC 2011


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 ***


More information about the svn-soc-all mailing list