Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Jan 2011 02:10:54 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r217176 - head/sys/fs/nfsserver
Message-ID:  <201101090210.p092AsOn023875@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Sun Jan  9 02:10:54 2011
New Revision: 217176
URL: http://svn.freebsd.org/changeset/base/217176

Log:
  Modify readdirplus in the experimental NFS server in a
  manner analogous to r216633 for the regular server. This
  change busies the file system so that VFS_VGET() is
  guaranteed to be using the correct mount point even
  during a forced dismount attempt. Since nfsd_fhtovp() is
  not called immediately before readdirplus, the patch is
  actually a clone of pjd@'s nfs_serv.c.4.patch instead of
  the one committed in r216633.
  
  Reviewed by:	kib
  MFC after:	10 days

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

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c	Sat Jan  8 23:08:13 2011	(r217175)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c	Sun Jan  9 02:10:54 2011	(r217176)
@@ -1685,6 +1685,7 @@ nfsrvd_readdirplus(struct nfsrv_descript
 	struct iovec iv;
 	struct componentname cn;
 	int not_zfs;
+	struct mount *mp;
 
 	if (nd->nd_repstat) {
 		nfsrv_postopattr(nd, getret, &at);
@@ -1854,7 +1855,24 @@ again:
 		toff = off;
 		goto again;
 	}
+
+	/*
+	 * Busy the file system so that the mount point won't go away
+	 * and, as such, VFS_VGET() can be used safely.
+	 */
+	mp = vp->v_mount;
+	vfs_ref(mp);
 	VOP_UNLOCK(vp, 0);
+	nd->nd_repstat = vfs_busy(mp, 0);
+	vfs_rel(mp);
+	if (nd->nd_repstat != 0) {
+		vrele(vp);
+		free(cookies, M_TEMP);
+		free(rbuf, M_TEMP);
+		if (nd->nd_flag & ND_NFSV3)
+			nfsrv_postopattr(nd, getret, &at);
+		return (0);
+	}
 
 	/*
 	 * Save this position, in case there is an error before one entry
@@ -1914,9 +1932,8 @@ again:
 					    vp, dp->d_fileno);
 				if (refp == NULL) {
 					if (usevget)
-						r = VFS_VGET(vp->v_mount,
-						    dp->d_fileno, LK_SHARED,
-						    &nvp);
+						r = VFS_VGET(mp, dp->d_fileno,
+						    LK_SHARED, &nvp);
 					else
 						r = EOPNOTSUPP;
 					if (r == EOPNOTSUPP) {
@@ -2035,6 +2052,7 @@ again:
 		ncookies--;
 	}
 	vrele(vp);
+	vfs_unbusy(mp);
 
 	/*
 	 * If dirlen > cnt, we must strip off the last entry. If that



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