Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Jun 2009 14:10:18 +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: r194363 - head/sys/fs/nfsclient
Message-ID:  <200906171410.n5HEAImS077939@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Wed Jun 17 14:10:18 2009
New Revision: 194363
URL: http://svn.freebsd.org/changeset/base/194363

Log:
  Fix handling of ".." in nfs_lookup() for the forced dismount case
  by cribbing the change made to the regular nfs client in r194358.
  
  Approved by:	kib (mentor)

Modified:
  head/sys/fs/nfsclient/nfs_clvnops.c

Modified: head/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c	Wed Jun 17 14:00:56 2009	(r194362)
+++ head/sys/fs/nfsclient/nfs_clvnops.c	Wed Jun 17 14:10:18 2009	(r194363)
@@ -992,22 +992,23 @@ nfs_lookup(struct vop_lookup_args *ap)
 	struct componentname *cnp = ap->a_cnp;
 	struct vnode *dvp = ap->a_dvp;
 	struct vnode **vpp = ap->a_vpp;
+	struct mount *mp = dvp->v_mount;
 	int flags = cnp->cn_flags;
 	struct vnode *newvp;
 	struct nfsmount *nmp;
 	struct nfsnode *np;
-	int error = 0, attrflag, dattrflag;
+	int error = 0, attrflag, dattrflag, ltype;
 	struct thread *td = cnp->cn_thread;
 	struct nfsfh *nfhp;
 	struct nfsvattr dnfsva, nfsva;
 	
 	*vpp = NULLVP;
-	if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
+	if ((flags & ISLASTCN) && (mp->mnt_flag & MNT_RDONLY) &&
 	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
 		return (EROFS);
 	if (dvp->v_type != VDIR)
 		return (ENOTDIR);
-	nmp = VFSTONFS(dvp->v_mount);
+	nmp = VFSTONFS(mp);
 	np = VTONFS(dvp);
 
 	/* For NFSv4, wait until any remove is done. */
@@ -1073,7 +1074,7 @@ nfs_lookup(struct vop_lookup_args *ap)
 		}
 		if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
 		    (flags & ISLASTCN) && error == ENOENT) {
-			if (dvp->v_mount->mnt_flag & MNT_RDONLY)
+			if (mp->mnt_flag & MNT_RDONLY)
 				error = EROFS;
 			else
 				error = EJUSTRETURN;
@@ -1093,8 +1094,7 @@ nfs_lookup(struct vop_lookup_args *ap)
 			FREE((caddr_t)nfhp, M_NFSFH);
 			return (EISDIR);
 		}
-		error = nfscl_nget(dvp->v_mount, dvp, nfhp, cnp, td, &np,
-		    NULL);
+		error = nfscl_nget(mp, dvp, nfhp, cnp, td, &np, NULL);
 		if (error)
 			return (error);
 		newvp = NFSTOV(np);
@@ -1106,14 +1106,37 @@ nfs_lookup(struct vop_lookup_args *ap)
 		return (0);
 	}
 
-	if ((flags & ISDOTDOT)) {
+	if (flags & ISDOTDOT) {
+		ltype = VOP_ISLOCKED(dvp);
+		error = vfs_busy(mp, MBF_NOWAIT);
+		if (error != 0) {
+			VOP_UNLOCK(dvp, 0);
+			error = vfs_busy(mp, 0);
+			vn_lock(dvp, ltype | LK_RETRY);
+			if (error == 0 && (dvp->v_iflag & VI_DOOMED)) {
+				vfs_unbusy(mp);
+				error = ENOENT;
+			}
+			if (error != 0)
+				return (error);
+		}
 		VOP_UNLOCK(dvp, 0);
-		error = nfscl_nget(dvp->v_mount, dvp, nfhp, cnp, td, &np,
-		    NULL);
-		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
-		if (error)
+		error = nfscl_nget(mp, dvp, nfhp, cnp, td, &np, NULL);
+		if (error == 0)
+			newvp = NFSTOV(np);
+		vfs_unbusy(mp);
+		vn_lock(dvp, ltype | LK_RETRY);
+		if (dvp->v_iflag & VI_DOOMED) {
+			if (error == 0) {
+				if (newvp == dvp)
+					vrele(newvp);
+				else
+					vput(newvp);
+			}
+			error = ENOENT;
+		}
+		if (error != 0)
 			return (error);
-		newvp = NFSTOV(np);
 		if (attrflag)
 			(void) nfscl_loadattrcache(&newvp, &nfsva, NULL, NULL,
 			    0, 1);
@@ -1125,8 +1148,7 @@ nfs_lookup(struct vop_lookup_args *ap)
 			(void) nfscl_loadattrcache(&newvp, &nfsva, NULL, NULL,
 			    0, 1);
 	} else {
-		error = nfscl_nget(dvp->v_mount, dvp, nfhp, cnp, td, &np,
-		    NULL);
+		error = nfscl_nget(mp, dvp, nfhp, cnp, td, &np, NULL);
 		if (error)
 			return (error);
 		newvp = NFSTOV(np);



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