Author: rmacklem
Date: Fri Aug 17 12:32:38 2018
New Revision: 337962
URL: https://svnweb.freebsd.org/changeset/base/337962

Log:
  Don't set a file's size for the MDS file of a pNFS service.
  
  When a pNFS service is running, the size of the files created on the MDS
  are normally 0, since the data is written to the data files on the DS(s).
  However, without this patch, if a Setattr with a non-zero size was done by
  a client, the MDS file was set to that size.  This was thought to be benign,
  but it turns out that files with a non-zero size plus extended attributes
  can cause a "ffs_truncate3" panic in UFS. Although the exact cause of this
  panic() has not been isolated, this patch avoids the panic() and leaves
  the MDS files in a consistent state of always having a size == 0.
  Note that these MDS files never store data. The patch also includes an
  unnecessary initialization of savsize in case some compiler or static
  analyser complains it might not be initialized.
  This patch only affects the NFS server when pNFS is enabled via the "-p"
  command line option on nfsd.

Modified:
  head/sys/fs/nfsserver/nfs_nfsdport.c

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c        Fri Aug 17 10:18:45 2018        
(r337961)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c        Fri Aug 17 12:32:38 2018        
(r337962)
@@ -442,9 +442,33 @@ int
 nfsvno_setattr(struct vnode *vp, struct nfsvattr *nvap, struct ucred *cred,
     struct thread *p, struct nfsexstuff *exp)
 {
-       int error;
+       u_quad_t savsize = 0;
+       int error, savedit;
 
-       error = VOP_SETATTR(vp, &nvap->na_vattr, cred);
+       /*
+        * If this is an exported file system and a pNFS service is running,
+        * don't VOP_SETATTR() of size for the MDS file system.
+        */
+       savedit = 0;
+       error = 0;
+       if (vp->v_type == VREG && (vp->v_mount->mnt_flag & MNT_EXPORTED) != 0 &&
+           nfsrv_devidcnt != 0 && nvap->na_vattr.va_size != VNOVAL &&
+           nvap->na_vattr.va_size > 0) {
+               savsize = nvap->na_vattr.va_size;
+               nvap->na_vattr.va_size = VNOVAL;
+               if (nvap->na_vattr.va_uid != (uid_t)VNOVAL ||
+                   nvap->na_vattr.va_gid != (gid_t)VNOVAL ||
+                   nvap->na_vattr.va_mode != (mode_t)VNOVAL ||
+                   nvap->na_vattr.va_atime.tv_sec != VNOVAL ||
+                   nvap->na_vattr.va_mtime.tv_sec != VNOVAL)
+                       savedit = 1;
+               else
+                       savedit = 2;
+       }
+       if (savedit != 2)
+               error = VOP_SETATTR(vp, &nvap->na_vattr, cred);
+       if (savedit != 0)
+               nvap->na_vattr.va_size = savsize;
        if (error == 0 && (nvap->na_vattr.va_uid != (uid_t)VNOVAL ||
            nvap->na_vattr.va_gid != (gid_t)VNOVAL ||
            nvap->na_vattr.va_size != VNOVAL ||
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to