diff --git a/sys/fs/nfs/nfs_commonsubs.c.vvroot b/sys/fs/nfs/nfs_commonsubs.c --- a/sys/fs/nfs/nfs_commonsubs.c.vvroot +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -2661,7 +2661,7 @@ struct timespec temptime; NFSACL_T *aclp, *naclp = NULL; size_t atsiz; - bool xattrsupp; + bool has_hiddensystem, has_namedattr, locked_vp, xattrsupp; short irflag; long has_pathconf; #ifdef QUOTA @@ -2714,6 +2714,12 @@ if (fs->f_ffree < 0) fs->f_ffree = 0; } + + /* These cases for the NFSv4 server need the vnode locked. */ + locked_vp = false; + if (vp != NULL && cred != NULL && p != NULL && + NFSVOPLOCK(vp, LK_SHARED) == 0) + locked_vp = true; /* * And the NFSv4 ACL... @@ -2728,12 +2734,11 @@ supports_nfsv4acls == 0)) { NFSCLRBIT_ATTRBIT(retbitp, NFSATTRBIT_ACL); } else if (naclp != NULL) { - if (NFSVOPLOCK(vp, LK_SHARED) == 0) { + if (locked_vp) { error = VOP_ACCESSX(vp, VREAD_ACL, cred, p); if (error == 0) error = VOP_GETACL(vp, ACL_TYPE_NFS4, naclp, cred, p); - NFSVOPUNLOCK(vp); } else error = NFSERR_PERM; if (error != 0) { @@ -2750,15 +2755,30 @@ /* Check to see if Extended Attributes are supported. */ xattrsupp = false; if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_XATTRSUPPORT)) { - if (NFSVOPLOCK(vp, LK_SHARED) == 0) { + if (locked_vp) { error = VOP_GETEXTATTR(vp, EXTATTR_NAMESPACE_USER, "xxx", NULL, &atsiz, cred, p); - NFSVOPUNLOCK(vp); if (error != EOPNOTSUPP) xattrsupp = true; } } + /* Check for has_hiddensystem and has_namedattr. */ + has_hiddensystem = false; + has_namedattr = false; + if (locked_vp) { + if (VOP_PATHCONF(vp, _PC_HAS_HIDDENSYSTEM, &has_pathconf) != 0) + has_pathconf = 0; + if (has_pathconf == 1) + has_hiddensystem = true; + if (VOP_PATHCONF(vp, _PC_HAS_NAMEDATTR, &has_pathconf) != 0) + has_pathconf = 0; + if (has_pathconf == 1) + has_namedattr = true; + NFSVOPUNLOCK(vp); + locked_vp = false; + } + /* * Put out the attribute bitmap for the ones being filled in * and get the field for the number of attributes returned. @@ -2780,11 +2800,7 @@ NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACLSUPPORT); NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACL); } - if (cred == NULL || p == NULL || vp == NULL || - VOP_PATHCONF(vp, _PC_HAS_HIDDENSYSTEM, - &has_pathconf) != 0) - has_pathconf = 0; - if (has_pathconf == 0) { + if (!has_hiddensystem) { NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_HIDDEN); NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_SYSTEM); } @@ -2828,10 +2844,7 @@ break; case NFSATTRBIT_NAMEDATTR: NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - if (VOP_PATHCONF(vp, _PC_HAS_NAMEDATTR, - &has_pathconf) != 0) - has_pathconf = 0; - if (has_pathconf != 0) + if (has_namedattr) *tl = newnfs_true; else *tl = newnfs_false;