summaryrefslogtreecommitdiffstats
path: root/sys/nfs4client
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-03-28 09:29:58 +0000
committerjeff <jeff@FreeBSD.org>2005-03-28 09:29:58 +0000
commit5f8bc80203c1f09224b3147185dc75b9836efa82 (patch)
tree55f8f7863119a8b25b0a65b6af969ad7dfbfb683 /sys/nfs4client
parenteb142209f00eb33da0b100cb34139de01a18a9a8 (diff)
downloadFreeBSD-src-5f8bc80203c1f09224b3147185dc75b9836efa82.zip
FreeBSD-src-5f8bc80203c1f09224b3147185dc75b9836efa82.tar.gz
- We no longer have to bother with PDIRUNLOCK, lookup() handles it for us.
- Network filesystems are written with a special idiom that checks the cache first, and may even unlock dvp before discovering that a network round-trip is required to resolve the name. I believe dvp is prevented from being recycled even in the forced unmount case by the shared lock on the mount point. If not, this code should grow checks for VI_DOOMED after it relocks dvp or it will access NULL v_data fields. Sponsored by: Isilon Systems, Inc.
Diffstat (limited to 'sys/nfs4client')
-rw-r--r--sys/nfs4client/nfs4_vnops.c57
1 files changed, 10 insertions, 47 deletions
diff --git a/sys/nfs4client/nfs4_vnops.c b/sys/nfs4client/nfs4_vnops.c
index ca1f303..be6bd85 100644
--- a/sys/nfs4client/nfs4_vnops.c
+++ b/sys/nfs4client/nfs4_vnops.c
@@ -937,7 +937,7 @@ nfs4_lookup(struct vop_lookup_args *ap)
long len;
nfsfh_t *fhp;
struct nfsnode *np;
- int lockparent, wantparent, error = 0, fhsize;
+ int wantparent, error = 0, fhsize;
struct thread *td = cnp->cn_thread;
struct nfs4_compound cp;
struct nfs4_oparg_getattr ga, dga;
@@ -945,13 +945,11 @@ nfs4_lookup(struct vop_lookup_args *ap)
struct nfs4_oparg_getfh gfh;
*vpp = NULLVP;
- cnp->cn_flags &= ~PDIRUNLOCK;
if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
return (EROFS);
if (dvp->v_type != VDIR)
return (ENOTDIR);
- lockparent = flags & LOCKPARENT;
wantparent = flags & (LOCKPARENT|WANTPARENT);
nmp = VFSTONFS(dvp->v_mount);
np = VTONFS(dvp);
@@ -977,20 +975,11 @@ nfs4_lookup(struct vop_lookup_args *ap)
error = 0;
} else if (flags & ISDOTDOT) {
VOP_UNLOCK(dvp, 0, td);
- cnp->cn_flags |= PDIRUNLOCK;
error = vget(newvp, LK_EXCLUSIVE, td);
- if (!error && lockparent && (flags & ISLASTCN)) {
- error = vn_lock(dvp, LK_EXCLUSIVE, td);
- if (error == 0)
- cnp->cn_flags &= ~PDIRUNLOCK;
- }
- } else {
+ if (error)
+ vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY, td);
+ } else
error = vget(newvp, LK_EXCLUSIVE, td);
- if (!lockparent || error || !(flags & ISLASTCN)) {
- VOP_UNLOCK(dvp, 0, td);
- cnp->cn_flags |= PDIRUNLOCK;
- }
- }
if (!error) {
if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred, td)
&& vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) {
@@ -1002,18 +991,15 @@ nfs4_lookup(struct vop_lookup_args *ap)
return (0);
}
cache_purge(newvp);
- vput(newvp);
- if (lockparent && dvp != newvp && (flags & ISLASTCN))
- VOP_UNLOCK(dvp, 0, td);
+ if (newvp != dvp)
+ vput(newvp);
+ else
+ vrele(newvp);
+ if (flags & ISDOTDOT)
+ vn_lock(dvp, LK_EXCLUSIVE|LK_RETRY, td);
}
vdrop(newvp);
- error = vn_lock(dvp, LK_EXCLUSIVE, td);
*vpp = NULLVP;
- if (error) {
- cnp->cn_flags |= PDIRUNLOCK;
- return (error);
- }
- cnp->cn_flags &= ~PDIRUNLOCK;
}
error = 0;
@@ -1079,10 +1065,6 @@ nfs4_lookup(struct vop_lookup_args *ap)
*vpp = newvp;
cnp->cn_flags |= SAVENAME;
- if (!lockparent) {
- VOP_UNLOCK(dvp, 0, td);
- cnp->cn_flags |= PDIRUNLOCK;
- }
return (0);
}
@@ -1097,16 +1079,6 @@ nfs4_lookup(struct vop_lookup_args *ap)
newvp = NFSTOV(np);
nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL);
-
- if (lockparent && (flags & ISLASTCN)) {
- error = vn_lock(dvp, LK_EXCLUSIVE, td);
- if (error) {
- cnp->cn_flags |= PDIRUNLOCK;
- vput(newvp);
- return (error);
- }
- } else
- cnp->cn_flags |= PDIRUNLOCK;
} else if (NFS_CMPFH(np, fhp, fhsize)) {
VREF(dvp);
newvp = dvp;
@@ -1114,11 +1086,6 @@ nfs4_lookup(struct vop_lookup_args *ap)
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error)
return (error);
-
- if (!lockparent || !(flags & ISLASTCN)) {
- cnp->cn_flags |= PDIRUNLOCK;
- VOP_UNLOCK(dvp, 0, td);
- }
newvp = NFSTOV(np);
/* Fill in np used by open. */
@@ -1152,10 +1119,6 @@ nfsmout:
}
if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
(flags & ISLASTCN) && error == ENOENT) {
- if (!lockparent) {
- VOP_UNLOCK(dvp, 0, td);
- cnp->cn_flags |= PDIRUNLOCK;
- }
if (dvp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else
OpenPOWER on IntegriCloud