Author: pjd
Date: Tue Dec 28 21:12:15 2010
New Revision: 216774
URL: http://svn.freebsd.org/changeset/base/216774

Log:
  ZFS might not return monotonically increasing directory offset cookies,
  so turn off UFS-specific hack that assumes so in ZFS case.
  Before the change we can miss returning some directory entries to a
  NFS client.
  
  I believe that the hack should be moved to ufs_readdir(), but until we find
  somebody who will do it, turn it off for ZFS in NFS server code.
  
  Submitted by: rmacklem
  Discussed with:       rmacklem, mckusick
  MFC after:    3 days

Modified:
  head/sys/nfsserver/nfs_serv.c

Modified: head/sys/nfsserver/nfs_serv.c
==============================================================================
--- head/sys/nfsserver/nfs_serv.c       Tue Dec 28 20:11:54 2010        
(r216773)
+++ head/sys/nfsserver/nfs_serv.c       Tue Dec 28 21:12:15 2010        
(r216774)
@@ -2737,7 +2737,7 @@ nfsrv_readdir(struct nfsrv_descript *nfs
        int v3 = (nfsd->nd_flag & ND_NFSV3);
        u_quad_t off, toff, verf;
        u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
-       int vfslocked;
+       int vfslocked, not_zfs;
 
        nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
        vfslocked = 0;
@@ -2801,6 +2801,7 @@ nfsrv_readdir(struct nfsrv_descript *nfs
                error = 0;
                goto nfsmout;
        }
+       not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
        VOP_UNLOCK(vp, 0);
 
        /*
@@ -2887,10 +2888,12 @@ again:
         * skip over the records that precede the requested offset. This
         * requires the assumption that file offset cookies monotonically
         * increase.
+        * Since the offset cookies don't monotonically increase for ZFS,
+        * this is not done when ZFS is the file system.
         */
        while (cpos < cend && ncookies > 0 &&
                (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
-                ((u_quad_t)(*cookiep)) <= toff)) {
+                (not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
                cpos += dp->d_reclen;
                dp = (struct dirent *)cpos;
                cookiep++;
@@ -3037,6 +3040,7 @@ nfsrv_readdirplus(struct nfsrv_descript 
        int usevget = 1, vfslocked;
        struct componentname cn;
        struct mount *mntp = NULL;
+       int not_zfs;
 
        nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
        vfslocked = 0;
@@ -3097,6 +3101,7 @@ nfsrv_readdirplus(struct nfsrv_descript 
                error = 0;
                goto nfsmout;
        }
+       not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs") != 0;
        VOP_UNLOCK(vp, 0);
        vp_locked = 0;
        rbuf = malloc(siz, M_TEMP, M_WAITOK);
@@ -3176,10 +3181,12 @@ again:
         * skip over the records that precede the requested offset. This
         * requires the assumption that file offset cookies monotonically
         * increase.
+        * Since the offset cookies don't monotonically increase for ZFS,
+        * this is not done when ZFS is the file system.
         */
        while (cpos < cend && ncookies > 0 &&
                (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
-                ((u_quad_t)(*cookiep)) <= toff)) {
+                (not_zfs != 0 && ((u_quad_t)(*cookiep)) <= toff))) {
                cpos += dp->d_reclen;
                dp = (struct dirent *)cpos;
                cookiep++;
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to