Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Apr 2011 18:17:01 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r221213 - in stable/8/sys/fs: nfs nfsclient nfsserver
Message-ID:  <201104291817.p3TIH1ix009753@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Fri Apr 29 18:17:01 2011
New Revision: 221213
URL: http://svn.freebsd.org/changeset/base/221213

Log:
  MFC: r220645
  Modify the experimental NFSv4 server so that it handles
  crossing of server mount points properly. The functions
  nfsvno_fillattr() and nfsv4_fillattr() were modified to
  take the extra arguments that are the mount point, a flag
  to indicate that it is a file system root and the mounted
  on fileno. The mount point argument needs to be busy when
  nfsvno_fillattr() is called, since the vp argument is not
  locked.

Modified:
  stable/8/sys/fs/nfs/nfs_commonsubs.c
  stable/8/sys/fs/nfs/nfs_var.h
  stable/8/sys/fs/nfsclient/nfs_clport.c
  stable/8/sys/fs/nfsclient/nfs_clrpcops.c
  stable/8/sys/fs/nfsclient/nfs_clstate.c
  stable/8/sys/fs/nfsserver/nfs_nfsdport.c
  stable/8/sys/fs/nfsserver/nfs_nfsdserv.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- stable/8/sys/fs/nfs/nfs_commonsubs.c	Fri Apr 29 17:57:35 2011	(r221212)
+++ stable/8/sys/fs/nfs/nfs_commonsubs.c	Fri Apr 29 18:17:01 2011	(r221213)
@@ -1916,9 +1916,10 @@ nfsrv_mtostr(struct nfsrv_descript *nd, 
  * Fill in the attributes as marked by the bitmap (V4).
  */
 APPLESTATIC int
-nfsv4_fillattr(struct nfsrv_descript *nd, vnode_t vp, NFSACL_T *saclp,
-    struct vattr *vap, fhandle_t *fhp, int rderror, nfsattrbit_t *attrbitp,
-    struct ucred *cred, NFSPROC_T *p, int isdgram, int reterr)
+nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp,
+    NFSACL_T *saclp, struct vattr *vap, fhandle_t *fhp, int rderror,
+    nfsattrbit_t *attrbitp, struct ucred *cred, NFSPROC_T *p, int isdgram,
+    int reterr, int at_root, uint64_t mounted_on_fileno)
 {
 	int bitpos, retnum = 0;
 	u_int32_t *tl;
@@ -1928,7 +1929,6 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 	nfsattrbit_t *retbitp = &retbits;
 	u_int32_t freenum, *retnump;
 	u_int64_t uquad;
-	long fid;
 	struct statfs fs;
 	struct nfsfsinfo fsinf;
 	struct timespec temptime;
@@ -1958,7 +1958,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 	 * Get the VFS_STATFS(), since some attributes need them.
 	 */
 	if (NFSISSETSTATFS_ATTRBIT(retbitp)) {
-		error = VFS_STATFS(vnode_mount(vp), &fs);
+		error = VFS_STATFS(mp, &fs);
 		if (error != 0) {
 			if (reterr) {
 				nd->nd_repstat = NFSERR_ACCES;
@@ -1974,12 +1974,12 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 	 */
 	if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_ACLSUPPORT) &&
 	    (nfsrv_useacl == 0 || ((cred != NULL || p != NULL) &&
-		!NFSHASNFS4ACL(vnode_mount(vp))))) {
+		!NFSHASNFS4ACL(mp)))) {
 		NFSCLRBIT_ATTRBIT(retbitp, NFSATTRBIT_ACLSUPPORT);
 	}
 	if (NFSISSET_ATTRBIT(retbitp, NFSATTRBIT_ACL)) {
 		if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL) &&
-		    !NFSHASNFS4ACL(vnode_mount(vp)))) {
+		    !NFSHASNFS4ACL(mp))) {
 			NFSCLRBIT_ATTRBIT(retbitp, NFSATTRBIT_ACL);
 		} else if (naclp != NULL) {
 			if (vn_lock(vp, LK_SHARED) == 0) {
@@ -2016,7 +2016,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 		case NFSATTRBIT_SUPPORTEDATTRS:
 			NFSSETSUPP_ATTRBIT(&attrbits);
 			if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL)
-			    && !NFSHASNFS4ACL(vnode_mount(vp)))) {
+			    && !NFSHASNFS4ACL(mp))) {
 			    NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACLSUPPORT);
 			    NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACL);
 			}
@@ -2066,9 +2066,9 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 		case NFSATTRBIT_FSID:
 			NFSM_BUILD(tl, u_int32_t *, NFSX_V4FSID);
 			*tl++ = 0;
-			*tl++=txdr_unsigned(vfs_statfs(vnode_mount(vp))->f_fsid.val[0]);
+			*tl++ = txdr_unsigned(mp->mnt_stat.f_fsid.val[0]);
 			*tl++ = 0;
-			*tl=txdr_unsigned(vfs_statfs(vnode_mount(vp))->f_fsid.val[1]);
+			*tl = txdr_unsigned(mp->mnt_stat.f_fsid.val[1]);
 			retnum += NFSX_V4FSID;
 			break;
 		case NFSATTRBIT_UNIQUEHANDLES:
@@ -2142,7 +2142,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 			 */
 			savuid = p->p_cred->p_ruid;
 			p->p_cred->p_ruid = cred->cr_uid;
-			if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA),
+			if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQUOTA),
 			    cred->cr_uid, (caddr_t)&dqb))
 			    freenum = min(dqb.dqb_isoftlimit-dqb.dqb_curinodes,
 				freenum);
@@ -2249,7 +2249,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 			 */
 			savuid = p->p_cred->p_ruid;
 			p->p_cred->p_ruid = cred->cr_uid;
-			if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA),
+			if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQUOTA),
 			    cred->cr_uid, (caddr_t)&dqb))
 			    freenum = min(dqb.dqb_bhardlimit, freenum);
 			p->p_cred->p_ruid = savuid;
@@ -2273,7 +2273,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 			 */
 			savuid = p->p_cred->p_ruid;
 			p->p_cred->p_ruid = cred->cr_uid;
-			if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA),
+			if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQUOTA),
 			    cred->cr_uid, (caddr_t)&dqb))
 			    freenum = min(dqb.dqb_bsoftlimit, freenum);
 			p->p_cred->p_ruid = savuid;
@@ -2294,7 +2294,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 			 */
 			savuid = p->p_cred->p_ruid;
 			p->p_cred->p_ruid = cred->cr_uid;
-			if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA),
+			if (!VFS_QUOTACTL(mp, QCMD(Q_GETQUOTA,USRQUOTA),
 			    cred->cr_uid, (caddr_t)&dqb))
 			    freenum = dqb.dqb_curblocks;
 			p->p_cred->p_ruid = savuid;
@@ -2390,11 +2390,11 @@ nfsv4_fillattr(struct nfsrv_descript *nd
 			break;
 		case NFSATTRBIT_MOUNTEDONFILEID:
 			NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
-			*tl++ = 0;
-			if (nfsrv_atroot(vp, &fid))
-				*tl = txdr_unsigned(fid);
+			if (at_root != 0)
+				uquad = mounted_on_fileno;
 			else
-				*tl = txdr_unsigned(vap->va_fileid);
+				uquad = (u_int64_t)vap->va_fileid;
+			txdr_hyper(uquad, tl);
 			retnum += NFSX_HYPER;
 			break;
 		default:

Modified: stable/8/sys/fs/nfs/nfs_var.h
==============================================================================
--- stable/8/sys/fs/nfs/nfs_var.h	Fri Apr 29 17:57:35 2011	(r221212)
+++ stable/8/sys/fs/nfs/nfs_var.h	Fri Apr 29 18:17:01 2011	(r221213)
@@ -288,9 +288,9 @@ int nfsrv_mtofh(struct nfsrv_descript *,
 int nfsrv_putattrbit(struct nfsrv_descript *, nfsattrbit_t *);
 void nfsrv_wcc(struct nfsrv_descript *, int, struct nfsvattr *, int,
     struct nfsvattr *);
-int nfsv4_fillattr(struct nfsrv_descript *, vnode_t, NFSACL_T *,
+int nfsv4_fillattr(struct nfsrv_descript *, struct mount *, vnode_t, NFSACL_T *,
     struct vattr *, fhandle_t *, int, nfsattrbit_t *,
-    struct ucred *, NFSPROC_T *, int, int);
+    struct ucred *, NFSPROC_T *, int, int, int, uint64_t);
 void nfsrv_fillattr(struct nfsrv_descript *, struct nfsvattr *);
 void nfsrv_adj(mbuf_t, int, int);
 void nfsrv_postopattr(struct nfsrv_descript *, int, struct nfsvattr *);
@@ -556,9 +556,9 @@ void nfsvno_open(struct nfsrv_descript *
     struct nfsexstuff *, vnode_t *);
 void nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *,
     NFSPROC_T *);
-int nfsvno_fillattr(struct nfsrv_descript *, vnode_t,
+int nfsvno_fillattr(struct nfsrv_descript *, struct mount *, vnode_t,
     struct nfsvattr *, fhandle_t *, int, nfsattrbit_t *,
-    struct ucred *, NFSPROC_T *, int, int);
+    struct ucred *, NFSPROC_T *, int, int, int, uint64_t);
 int nfsrv_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,
     NFSACL_T *, NFSPROC_T *);
 int nfsv4_sattr(struct nfsrv_descript *, struct nfsvattr *, nfsattrbit_t *,

Modified: stable/8/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- stable/8/sys/fs/nfsclient/nfs_clport.c	Fri Apr 29 17:57:35 2011	(r221212)
+++ stable/8/sys/fs/nfsclient/nfs_clport.c	Fri Apr 29 18:17:01 2011	(r221213)
@@ -803,8 +803,8 @@ nfscl_fillsattr(struct nfsrv_descript *n
 			NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESSSET);
 		if (vap->va_mtime.tv_sec != VNOVAL)
 			NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEMODIFYSET);
-		(void) nfsv4_fillattr(nd, vp, NULL, vap, NULL, 0, &attrbits,
-		    NULL, NULL, 0, 0);
+		(void) nfsv4_fillattr(nd, vp->v_mount, vp, NULL, vap, NULL, 0,
+		    &attrbits, NULL, NULL, 0, 0, 0, (uint64_t)0);
 		break;
 	};
 }

Modified: stable/8/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- stable/8/sys/fs/nfsclient/nfs_clrpcops.c	Fri Apr 29 17:57:35 2011	(r221212)
+++ stable/8/sys/fs/nfsclient/nfs_clrpcops.c	Fri Apr 29 18:17:01 2011	(r221213)
@@ -4176,8 +4176,8 @@ nfsrpc_setaclrpc(vnode_t vp, struct ucre
 	nfsm_stateidtom(nd, stateidp, NFSSTATEID_PUTSTATEID);
 	NFSZERO_ATTRBIT(&attrbits);
 	NFSSETBIT_ATTRBIT(&attrbits, NFSATTRBIT_ACL);
-	(void) nfsv4_fillattr(nd, vp, aclp, NULL, NULL, 0, &attrbits,
-	    NULL, NULL, 0, 0);
+	(void) nfsv4_fillattr(nd, vnode_mount(vp), vp, aclp, NULL, NULL, 0,
+	    &attrbits, NULL, NULL, 0, 0, 0, (uint64_t)0);
 	error = nfscl_request(nd, vp, p, cred, stuff);
 	if (error)
 		return (error);

Modified: stable/8/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- stable/8/sys/fs/nfsclient/nfs_clstate.c	Fri Apr 29 17:57:35 2011	(r221212)
+++ stable/8/sys/fs/nfsclient/nfs_clstate.c	Fri Apr 29 18:17:01 2011	(r221213)
@@ -3061,8 +3061,9 @@ nfscl_docb(struct nfsrv_descript *nd, NF
 					NFSSETBIT_ATTRBIT(&rattrbits,
 					    NFSATTRBIT_CHANGE);
 				}
-				(void) nfsv4_fillattr(nd, NULL, NULL, &va,
-				    NULL, 0, &rattrbits, NULL, NULL, 0, 0);
+				(void) nfsv4_fillattr(nd, NULL, NULL, NULL, &va,
+				    NULL, 0, &rattrbits, NULL, NULL, 0, 0, 0,
+				    (uint64_t)0);
 				if (!ret)
 					vrele(vp);
 			}

Modified: stable/8/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdport.c	Fri Apr 29 17:57:35 2011	(r221212)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdport.c	Fri Apr 29 18:17:01 2011	(r221213)
@@ -68,15 +68,15 @@ static uint32_t nfsv4_sysid = 0;
 static int nfssvc_srvcall(struct thread *, struct nfssvc_args *,
     struct ucred *);
 
-static int enable_crossmntpt = 1;
+int nfsrv_enable_crossmntpt = 1;
 static int nfs_commit_blks;
 static int nfs_commit_miss;
 extern int nfsrv_issuedelegs;
 extern int nfsrv_dolocallocks;
 
 SYSCTL_DECL(_vfs_newnfs);
-SYSCTL_INT(_vfs_newnfs, OID_AUTO, mirrormnt, CTLFLAG_RW, &enable_crossmntpt,
-    0, "Enable nfsd to cross mount points");
+SYSCTL_INT(_vfs_newnfs, OID_AUTO, mirrormnt, CTLFLAG_RW,
+    &nfsrv_enable_crossmntpt, 0, "Enable nfsd to cross mount points");
 SYSCTL_INT(_vfs_newnfs, OID_AUTO, commit_blks, CTLFLAG_RW, &nfs_commit_blks,
     0, "");
 SYSCTL_INT(_vfs_newnfs, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss,
@@ -306,12 +306,12 @@ nfsvno_namei(struct nfsrv_descript *nd, 
 			dp = rootvnode;
 			VREF(dp);
 		}
-	} else if ((enable_crossmntpt == 0 && NFSVNO_EXPORTED(exp)) ||
+	} else if ((nfsrv_enable_crossmntpt == 0 && NFSVNO_EXPORTED(exp)) ||
 	    (nd->nd_flag & ND_NFSV4) == 0) {
 		/*
 		 * Only cross mount points for NFSv4 when doing a
 		 * mount while traversing the file system above
-		 * the mount point, unless enable_crossmntpt is set.
+		 * the mount point, unless nfsrv_enable_crossmntpt is set.
 		 */
 		cnp->cn_flags |= NOCROSSMOUNT;
 		crossmnt = 0;
@@ -1391,14 +1391,15 @@ nfsvno_updfilerev(struct vnode *vp, stru
  * Glue routine to nfsv4_fillattr().
  */
 int
-nfsvno_fillattr(struct nfsrv_descript *nd, struct vnode *vp,
+nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
     struct nfsvattr *nvap, fhandle_t *fhp, int rderror, nfsattrbit_t *attrbitp,
-    struct ucred *cred, struct thread *p, int isdgram, int reterr)
+    struct ucred *cred, struct thread *p, int isdgram, int reterr, int at_root,
+    uint64_t mounted_on_fileno)
 {
 	int error;
 
-	error = nfsv4_fillattr(nd, vp, NULL, &nvap->na_vattr, fhp, rderror,
-	    attrbitp, cred, p, isdgram, reterr);
+	error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror,
+	    attrbitp, cred, p, isdgram, reterr, at_root, mounted_on_fileno);
 	return (error);
 }
 
@@ -1688,8 +1689,9 @@ nfsrvd_readdirplus(struct nfsrv_descript
 	struct uio io;
 	struct iovec iv;
 	struct componentname cn;
-	int not_zfs;
-	struct mount *mp;
+	int at_root, needs_unbusy, not_zfs;
+	struct mount *mp, *new_mp;
+	uint64_t mounted_on_fileno;
 
 	if (nd->nd_repstat) {
 		nfsrv_postopattr(nd, getret, &at);
@@ -1929,6 +1931,10 @@ again:
 			nvp = NULL;
 			refp = NULL;
 			r = 0;
+			at_root = 0;
+			needs_unbusy = 0;
+			new_mp = mp;
+			mounted_on_fileno = (uint64_t)dp->d_fileno;
 			if ((nd->nd_flag & ND_NFSV3) ||
 			    NFSNONZERO_ATTRBIT(&savbits)) {
 				if (nd->nd_flag & ND_NFSV4)
@@ -1980,6 +1986,29 @@ again:
 								    0);
 						}
 					}
+
+					/*
+					 * For NFSv4, check to see if nvp is
+					 * a mount point and get the mount
+					 * point vnode, as required.
+					 */
+					if (r == 0 &&
+					    nfsrv_enable_crossmntpt != 0 &&
+					    (nd->nd_flag & ND_NFSV4) != 0 &&
+					    nvp->v_type == VDIR &&
+					    nvp->v_mountedhere != NULL) {
+						new_mp = nvp->v_mountedhere;
+						r = vfs_busy(new_mp, 0);
+						vput(nvp);
+						nvp = NULL;
+						if (r == 0) {
+							r = VFS_ROOT(new_mp,
+							    LK_SHARED, &nvp);
+							needs_unbusy = 1;
+							if (r == 0)
+								at_root = 1;
+						}
+					}
 				}
 				if (!r) {
 				    if (refp == NULL &&
@@ -1998,6 +2027,8 @@ again:
 					    NFSATTRBIT_RDATTRERROR)) {
 						if (nvp != NULL)
 							vput(nvp);
+						if (needs_unbusy != 0)
+							vfs_unbusy(new_mp);
 						nd->nd_repstat = r;
 						break;
 					}
@@ -2036,21 +2067,27 @@ again:
 					if (nd->nd_repstat) {
 						if (nvp != NULL)
 							vrele(nvp);
+						if (needs_unbusy != 0)
+							vfs_unbusy(new_mp);
 						break;
 					}
 				} else if (r) {
-					dirlen += nfsvno_fillattr(nd, nvp, nvap,
-					    &nfh, r, &rderrbits, nd->nd_cred,
-					    p, isdgram, 0);
+					dirlen += nfsvno_fillattr(nd, new_mp,
+					    nvp, nvap, &nfh, r, &rderrbits,
+					    nd->nd_cred, p, isdgram, 0, at_root,
+					    mounted_on_fileno);
 				} else {
-					dirlen += nfsvno_fillattr(nd, nvp, nvap,
-					    &nfh, r, &attrbits, nd->nd_cred,
-					    p, isdgram, 0);
+					dirlen += nfsvno_fillattr(nd, new_mp,
+					    nvp, nvap, &nfh, r, &attrbits,
+					    nd->nd_cred, p, isdgram, 0, at_root,
+					    mounted_on_fileno);
 				}
 				if (nvp != NULL)
 					vrele(nvp);
 				dirlen += (3 * NFSX_UNSIGNED);
 			}
+			if (needs_unbusy != 0)
+				vfs_unbusy(new_mp);
 			if (dirlen <= cnt)
 				entrycnt++;
 		}

Modified: stable/8/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdserv.c	Fri Apr 29 17:57:35 2011	(r221212)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdserv.c	Fri Apr 29 18:17:01 2011	(r221213)
@@ -52,6 +52,7 @@ extern u_int32_t newnfs_false, newnfs_tr
 extern enum vtype nv34tov_type[8];
 extern struct timeval nfsboottime;
 extern int nfs_rootfhset;
+extern int nfsrv_enable_crossmntpt;
 #endif	/* !APPLEKEXT */
 
 /*
@@ -169,9 +170,13 @@ nfsrvd_getattr(struct nfsrv_descript *nd
 {
 	struct nfsvattr nva;
 	fhandle_t fh;
-	int error = 0;
+	int at_root = 0, error = 0;
 	struct nfsreferral *refp;
 	nfsattrbit_t attrbits;
+	struct mount *mp;
+	struct vnode *tvp = NULL;
+	struct vattr va;
+	uint64_t mounted_on_fileno = 0;
 
 	if (nd->nd_repstat)
 		return (0);
@@ -207,11 +212,46 @@ nfsrvd_getattr(struct nfsrv_descript *nd
 			if (!nd->nd_repstat)
 				nd->nd_repstat = nfsrv_checkgetattr(nd, vp,
 				    &nva, &attrbits, nd->nd_cred, p);
-			NFSVOPUNLOCK(vp, 0, p);
-			if (!nd->nd_repstat)
-				(void) nfsvno_fillattr(nd, vp, &nva, &fh,
-				    0, &attrbits, nd->nd_cred, p, isdgram, 1);
-			vrele(vp);
+			if (nd->nd_repstat == 0) {
+				mp = vp->v_mount;
+				if (nfsrv_enable_crossmntpt != 0 &&
+				    vp->v_type == VDIR &&
+				    (vp->v_vflag & VV_ROOT) != 0 &&
+				    vp != rootvnode) {
+					tvp = mp->mnt_vnodecovered;
+					VREF(tvp);
+					at_root = 1;
+				} else
+					at_root = 0;
+				vfs_ref(mp);
+				VOP_UNLOCK(vp, 0);
+				if (at_root != 0) {
+					if ((nd->nd_repstat =
+					     vn_lock(tvp, LK_SHARED)) == 0) {
+						nd->nd_repstat = VOP_GETATTR(
+						    tvp, &va, nd->nd_cred);
+						vput(tvp);
+					} else
+						vrele(tvp);
+					if (nd->nd_repstat == 0)
+						mounted_on_fileno = (uint64_t)
+						    va.va_fileid;
+					else
+						at_root = 0;
+				}
+				if (nd->nd_repstat == 0)
+					nd->nd_repstat = vfs_busy(mp, 0);
+				vfs_rel(mp);
+				if (nd->nd_repstat == 0) {
+					(void)nfsvno_fillattr(nd, mp, vp, &nva,
+					    &fh, 0, &attrbits, nd->nd_cred, p,
+					    isdgram, 1, at_root,
+					    mounted_on_fileno);
+					vfs_unbusy(mp);
+				}
+				vrele(vp);
+			} else
+				vput(vp);
 		} else {
 			nfsrv_fillattr(nd, &nva);
 			vput(vp);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104291817.p3TIH1ix009753>