Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Jan 2011 01:26:49 +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: r217567 - stable/8/sys/fs/nfsserver
Message-ID:  <201101190126.p0J1Qnam058351@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Wed Jan 19 01:26:49 2011
New Revision: 217567
URL: http://svn.freebsd.org/changeset/base/217567

Log:
  MFC: r217176
  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.

Modified:
  stable/8/sys/fs/nfsserver/nfs_nfsdport.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/nfsserver/nfs_nfsdport.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdport.c	Wed Jan 19 00:57:58 2011	(r217566)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdport.c	Wed Jan 19 01:26:49 2011	(r217567)
@@ -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?201101190126.p0J1Qnam058351>