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"