Module Name:    src
Committed By:   hannken
Date:           Sun Oct 30 12:00:28 UTC 2011

Modified Files:
        src/sys/nfs: nfs_serv.c

Log Message:
VOP_GETATTR() needs a shared lock at least.


To generate a diff of this commit:
cvs rdiff -u -r1.160 -r1.161 src/sys/nfs/nfs_serv.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/nfs/nfs_serv.c
diff -u src/sys/nfs/nfs_serv.c:1.160 src/sys/nfs/nfs_serv.c:1.161
--- src/sys/nfs/nfs_serv.c:1.160	Mon Aug  8 16:04:07 2011
+++ src/sys/nfs/nfs_serv.c	Sun Oct 30 12:00:27 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_serv.c,v 1.160 2011/08/08 16:04:07 dholland Exp $	*/
+/*	$NetBSD: nfs_serv.c,v 1.161 2011/10/30 12:00:27 hannken Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.160 2011/08/08 16:04:07 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.161 2011/10/30 12:00:27 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -454,8 +454,11 @@ nfsrv_lookup(struct nfsrv_descript *nfsd
 	}
 
 	if (dirp) {
-		if (v3)
+		if (v3) {
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 			dirattr_ret = VOP_GETATTR(dirp, &dirattr, cred);
+			VOP_UNLOCK(dirp);
+		}
 		vrele(dirp);
 	}
 
@@ -1582,7 +1585,9 @@ nfsrv_create(struct nfsrv_descript *nfsd
 				error = EEXIST;
 		}
 		if (dirp) {
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
+			VOP_UNLOCK(dirp);
 		}
 	}
 	if (dirp) {
@@ -1741,7 +1746,9 @@ out:
 		vput(vp);
 	}
 	if (dirp) {
+		vn_lock(dirp, LK_SHARED | LK_RETRY);
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
+		VOP_UNLOCK(dirp);
 		vrele(dirp);
 		dirp = NULL;
 	}
@@ -1810,8 +1817,12 @@ nfsrv_remove(struct nfsrv_descript *nfsd
 	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
 	error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
 		&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), false);
-	if (dirp && v3) {
+	if (error == 0 && dirp && v3) {
+		if (nd.ni_dvp == nd.ni_vp)
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 		dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred);
+		if (nd.ni_dvp == nd.ni_vp)
+			VOP_UNLOCK(dirp);
 	}
 	if (!error) {
 		vp = nd.ni_vp;
@@ -1845,7 +1856,9 @@ out:
 	}
 	if (dirp) {
 		if (v3) {
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
+			VOP_UNLOCK(dirp);
 		}
 		vrele(dirp);
 	}
@@ -1902,8 +1915,12 @@ nfsrv_rename(struct nfsrv_descript *nfsd
 	fromnd.ni_cnd.cn_flags = LOCKPARENT | INRENAME;
 	error = nfs_namei(&fromnd, &fnsfh, len, slp, nam, &md,
 		&dpos, &fdirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), false);
-	if (fdirp && v3) {
+	if (error == 0 && fdirp && v3) {
+		if (fromnd.ni_dvp == fromnd.ni_vp)
+			vn_lock(fdirp, LK_SHARED | LK_RETRY);
 		fdirfor_ret = VOP_GETATTR(fdirp, &fdirfor, cred);
+		if (fromnd.ni_dvp == fromnd.ni_vp)
+			VOP_UNLOCK(fdirp);
 	}
 	if (error) {
 		nfsm_reply(2 * NFSX_WCCDATA(v3));
@@ -2070,14 +2087,18 @@ out:
 out1:
 	if (fdirp) {
 		if (v3) {
+			vn_lock(fdirp, LK_SHARED | LK_RETRY);
 			fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred);
+			VOP_UNLOCK(fdirp);
 		}
 		vrele(fdirp);
 		fdirp = NULL;
 	}
 	if (tdirp) {
 		if (v3) {
+			vn_lock(tdirp, LK_SHARED | LK_RETRY);
 			tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred);
+			VOP_UNLOCK(tdirp);
 		}
 		vrele(tdirp);
 		tdirp = NULL;
@@ -2192,11 +2213,16 @@ out:
 			vrele(nd.ni_vp);
 	}
 out1:
-	if (v3)
+	if (v3) {
+		vn_lock(vp, LK_SHARED | LK_RETRY);
 		getret = VOP_GETATTR(vp, &at, cred);
+		VOP_UNLOCK(vp);
+	}
 	if (dirp) {
 		if (v3) {
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
+			VOP_UNLOCK(dirp);
 		}
 		vrele(dirp);
 	}
@@ -2315,7 +2341,9 @@ out:
 		free(pathcp, M_TEMP);
 	if (dirp) {
 		if (v3) {
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
+			VOP_UNLOCK(dirp);
 		}
 		vrele(dirp);
 		dirp = NULL;
@@ -2436,7 +2464,9 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd,
 out:
 	if (dirp) {
 		if (v3) {
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
+			VOP_UNLOCK(dirp);
 		}
 		vrele(dirp);
 		dirp = NULL;
@@ -2559,7 +2589,9 @@ out:
 	}
 	if (dirp) {
 		if (v3) {
+			vn_lock(dirp, LK_SHARED | LK_RETRY);
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
+			VOP_UNLOCK(dirp);
 		}
 		vrele(dirp);
 	}

Reply via email to