svn commit: r216633 - head/sys/nfsserver

Pawel Jakub Dawidek pjd at FreeBSD.org
Tue Dec 21 23:15:41 UTC 2010


Author: pjd
Date: Tue Dec 21 23:15:40 2010
New Revision: 216633
URL: http://svn.freebsd.org/changeset/base/216633

Log:
  Use newly added NFSRV_FLAG_BUSY flag for nfsrv_fhtovp() to keep mount point
  busy. This fixes a race where we can pass invalid mount point to VFS_VGET()
  via vp->v_mount when exported file system was forcibly unmounted between
  nfsrv_fhtovp() and VFS_VGET().
  
  Reviewed by:	kib
  MFC after:	5 days

Modified:
  head/sys/nfsserver/nfs_serv.c

Modified: head/sys/nfsserver/nfs_serv.c
==============================================================================
--- head/sys/nfsserver/nfs_serv.c	Tue Dec 21 23:12:45 2010	(r216632)
+++ head/sys/nfsserver/nfs_serv.c	Tue Dec 21 23:15:40 2010	(r216633)
@@ -3036,9 +3036,11 @@ nfsrv_readdirplus(struct nfsrv_descript 
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
 	int usevget = 1, vfslocked;
 	struct componentname cn;
+	struct mount *mntp = NULL;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	vfslocked = 0;
+	vp_locked = 0;
 	if (!v3)
 		panic("nfsrv_readdirplus: v3 proc called on a v2 connection");
 	fhp = &nfh.fh_generic;
@@ -3058,14 +3060,17 @@ nfsrv_readdirplus(struct nfsrv_descript 
 	if (siz > xfer)
 		siz = xfer;
 	fullsiz = siz;
-	error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp,
-	    nam, &rdonly, TRUE);
-	vp_locked = 1;
-	if (!error && vp->v_type != VDIR) {
-		error = ENOTDIR;
-		vput(vp);
-		vp = NULL;
-		vp_locked = 0;
+	error = nfsrv_fhtovp(fhp, NFSRV_FLAG_BUSY, &vp, &vfslocked, nfsd, slp,
+	    nam, &rdonly);
+	if (!error) {
+		vp_locked = 1;
+		mntp = vp->v_mount;
+		if (vp->v_type != VDIR) {
+			error = ENOTDIR;
+			vput(vp);
+			vp = NULL;
+			vp_locked = 0;
+		}
 	}
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
@@ -3207,8 +3212,8 @@ again:
 				 * For readdir_and_lookup get the vnode using
 				 * the file number.
 				 */
-				error = VFS_VGET(vp->v_mount, dp->d_fileno,
-				    LK_SHARED, &nvp);
+				error = VFS_VGET(mntp, dp->d_fileno, LK_SHARED,
+				    &nvp);
 				if (error != 0 && error != EOPNOTSUPP) {
 					error = 0;
 					goto invalid;


More information about the svn-src-head mailing list