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);
}