summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsserver
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2011-01-03 00:33:32 +0000
committerrmacklem <rmacklem@FreeBSD.org>2011-01-03 00:33:32 +0000
commitbb862fc0e472220eda22c0370874315a338a4816 (patch)
tree8a175f9454d5ad63a0305357ecda04d7ca3ead7a /sys/fs/nfsserver
parentf818eb99d7d6400259258d456feba02dac8e859e (diff)
downloadFreeBSD-src-bb862fc0e472220eda22c0370874315a338a4816.zip
FreeBSD-src-bb862fc0e472220eda22c0370874315a338a4816.tar.gz
Modify the experimental NFSv4 server so that the lookup
ops return a locked vnode. This ensures that the associated mount point will always be valid for the code that follows the operation. Also add a couple of additional checks for non-error to the other functions that create file objects. MFC after: 2 weeks
Diffstat (limited to 'sys/fs/nfsserver')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c20
-rw-r--r--sys/fs/nfsserver/nfs_nfsdsocket.c6
2 files changed, 13 insertions, 13 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index c564754..f3eb52d 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -470,12 +470,10 @@ nfsrvd_lookup(struct nfsrv_descript *nd, __unused int isdgram,
nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
- if (vpp) {
- NFSVOPUNLOCK(vp, 0, p);
+ if (vpp != NULL && nd->nd_repstat == 0)
*vpp = vp;
- } else {
+ else
vput(vp);
- }
if (dirp) {
if (nd->nd_flag & ND_NFSV3)
dattr_ret = nfsvno_getattr(dirp, &dattr, nd->nd_cred,
@@ -1218,12 +1216,11 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram,
if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat)
nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred,
p, 1);
- if (vpp) {
- NFSVOPUNLOCK(vp, 0, p);
+ if (vpp != NULL && nd->nd_repstat == 0) {
+ VOP_UNLOCK(vp, 0);
*vpp = vp;
- } else {
+ } else
vput(vp);
- }
}
diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
@@ -1706,12 +1703,11 @@ nfsrvd_symlinksub(struct nfsrv_descript *nd, struct nameidata *ndp,
nd->nd_repstat = nfsvno_getattr(ndp->ni_vp,
nvap, nd->nd_cred, p, 1);
}
- if (vpp) {
- NFSVOPUNLOCK(ndp->ni_vp, 0, p);
+ if (vpp != NULL && nd->nd_repstat == 0) {
+ VOP_UNLOCK(ndp->ni_vp, 0);
*vpp = ndp->ni_vp;
- } else {
+ } else
vput(ndp->ni_vp);
- }
}
if (dirp) {
*diraft_retp = nfsvno_getattr(dirp, diraftp, nd->nd_cred, p, 0);
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index fb6a87c..68cc05a 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -861,10 +861,14 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
nfsvno_lockvfs(mp);
}
}
+ if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP)
+ /* Lookup ops return a locked vnode */
+ VOP_UNLOCK(nvp, 0);
if (!nd->nd_repstat) {
vrele(vp);
vp = nvp;
- }
+ } else
+ vrele(nvp);
}
if (nfsv4_opflag[op].modifyfs)
NFS_ENDWRITE(mp);
OpenPOWER on IntegriCloud