summaryrefslogtreecommitdiff
path: root/sys/nfs/nfs_vnops.c
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-02-23 23:47:14 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-02-23 23:47:14 +0000
commit648f8e79cec49f65d44e3f4bfc063ddeca2bb5ae (patch)
treea5f3149713bec28221eb0120fbed56c473d55791 /sys/nfs/nfs_vnops.c
parentc9c250d5ccd909b5dacacda2f547effffa788186 (diff)
Sigh. The diff is out for testing for three months without a single problem.
Two days after commit people report serious lockups all over the place. Back out nfs locking changes.
Diffstat (limited to 'sys/nfs/nfs_vnops.c')
-rw-r--r--sys/nfs/nfs_vnops.c167
1 files changed, 39 insertions, 128 deletions
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index fd83fbe2135..2dca5d994b6 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nfs_vnops.c,v 1.48 2002/02/22 20:19:14 csapuntz Exp $ */
+/* $OpenBSD: nfs_vnops.c,v 1.49 2002/02/23 23:47:13 art Exp $ */
/* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */
/*
@@ -693,7 +693,6 @@ nfs_lookup(v)
nfsfh_t *fhp;
struct nfsnode *np;
int lockparent, wantparent, error = 0, attrflag, fhsize;
- int dvp_locked = 1;
int v3 = NFS_ISV3(dvp);
*vpp = NULLVP;
@@ -702,9 +701,10 @@ nfs_lookup(v)
return (EROFS);
if (dvp->v_type != VDIR)
return (ENOTDIR);
- lockparent = ((flags & (LOCKPARENT | ISLASTCN)) == (LOCKPARENT | ISLASTCN));
+ lockparent = flags & LOCKPARENT;
wantparent = flags & (LOCKPARENT|WANTPARENT);
nmp = VFSTONFS(dvp->v_mount);
+ np = VTONFS(dvp);
if ((error = cache_lookup(dvp, vpp, cnp)) != 0 && error != ENOENT) {
struct vattr vattr;
int vpid;
@@ -718,19 +718,10 @@ nfs_lookup(v)
if (dvp == newvp) {
VREF(newvp);
error = 0;
- } else if (flags & ISDOTDOT) {
- VOP_UNLOCK(dvp, 0, p);
- dvp_locked = 0;
- error = vget(newvp, LK_EXCLUSIVE, p);
- if (error != 0)
- newvp = NULL;
- } else {
+ } else
error = vget(newvp, LK_EXCLUSIVE, p);
- if (error != 0)
- newvp = NULL;
- }
- if (error == 0) {
+ if (!error) {
if (vpid == newvp->v_id) {
if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred, cnp->cn_proc)
&& vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) {
@@ -738,30 +729,15 @@ nfs_lookup(v)
if (cnp->cn_nameiop != LOOKUP &&
(flags & ISLASTCN))
cnp->cn_flags |= SAVENAME;
- goto exit;
+ return (0);
}
cache_purge(newvp);
}
- }
- *vpp = NULLVP;
-
- if (newvp == dvp)
vrele(newvp);
- else if (newvp != NULL)
- vput(newvp);
-
- if (!dvp_locked) {
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
- dvp_locked = 1;
}
+ *vpp = NULLVP;
}
-
- np = VTONFS(dvp);
- if (np == NULL) {
- error = ERESTART;
- goto exit;
- }
- error = 0;
+ error = 0;
newvp = NULLVP;
nfsstats.lookupcache_misses++;
nfsstats.rpccnt[NFSPROC_LOOKUP]++;
@@ -784,13 +760,12 @@ nfs_lookup(v)
if (cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN)) {
if (NFS_CMPFH(np, fhp, fhsize)) {
m_freem(mrep);
- error = EISDIR;
- goto exit;
+ return (EISDIR);
}
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error) {
m_freem(mrep);
- goto exit;
+ return (error);
}
newvp = NFSTOV(np);
if (v3) {
@@ -801,8 +776,7 @@ nfs_lookup(v)
*vpp = newvp;
m_freem(mrep);
cnp->cn_flags |= SAVENAME;
- error = 0;
- goto exit;
+ return (0);
}
if (NFS_CMPFH(np, fhp, fhsize)) {
@@ -812,7 +786,7 @@ nfs_lookup(v)
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error) {
m_freem(mrep);
- goto exit;
+ return (error);
}
newvp = NFSTOV(np);
}
@@ -831,6 +805,8 @@ nfs_lookup(v)
*vpp = newvp;
nfsm_reqdone;
if (error) {
+ if (newvp != NULLVP)
+ vrele(newvp);
if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
(flags & ISLASTCN) && error == ENOENT) {
if (dvp->v_mount->mnt_flag & MNT_RDONLY)
@@ -841,25 +817,6 @@ nfs_lookup(v)
if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
cnp->cn_flags |= SAVENAME;
}
-
- exit:
- if (error != 0) {
- if (newvp == dvp) {
- vrele(newvp);
- } else if (newvp != NULL) {
- vput(newvp);
- }
- }
-
- if (!dvp_locked) {
- if (error != 0 || lockparent) {
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
- }
- } else {
- if (error == 0 && !lockparent) {
- VOP_UNLOCK(dvp, 0, p);
- }
- }
return (error);
}
@@ -1171,7 +1128,7 @@ nfs_mknodrpc(dvp, vpp, cnp, vap)
nfsm_mtofh(dvp, newvp, v3, gotvp);
if (!gotvp) {
if (newvp) {
- vput(newvp);
+ vrele(newvp);
newvp = (struct vnode *)0;
}
error = nfs_lookitup(dvp, cnp->cn_nameptr,
@@ -1184,10 +1141,8 @@ nfs_mknodrpc(dvp, vpp, cnp, vap)
nfsm_wcc_data(dvp, wccflag);
nfsm_reqdone;
if (error) {
- if (newvp) {
- vput(newvp);
- newvp = NULL;
- }
+ if (newvp)
+ vrele(newvp);
} else {
if (cnp->cn_flags & MAKEENTRY)
cache_enter(dvp, newvp, cnp);
@@ -1197,7 +1152,7 @@ nfs_mknodrpc(dvp, vpp, cnp, vap)
VTONFS(dvp)->n_flag |= NMODIFIED;
if (!wccflag)
VTONFS(dvp)->n_attrstamp = 0;
- vput(dvp);
+ vrele(dvp);
return (error);
}
@@ -1220,9 +1175,8 @@ nfs_mknod(v)
int error;
error = nfs_mknodrpc(ap->a_dvp, &newvp, ap->a_cnp, ap->a_vap);
- if (error == 0)
- vput(newvp);
-
+ if (!error)
+ vrele(newvp);
return (error);
}
@@ -1298,7 +1252,7 @@ again:
nfsm_mtofh(dvp, newvp, v3, gotvp);
if (!gotvp) {
if (newvp) {
- vput(newvp);
+ vrele(newvp);
newvp = (struct vnode *)0;
}
error = nfs_lookitup(dvp, cnp->cn_nameptr,
@@ -1316,7 +1270,7 @@ again:
goto again;
}
if (newvp)
- vput(newvp);
+ vrele(newvp);
} else if (v3 && (fmode & O_EXCL))
error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_proc);
if (!error) {
@@ -1328,7 +1282,7 @@ again:
VTONFS(dvp)->n_flag |= NMODIFIED;
if (!wccflag)
VTONFS(dvp)->n_attrstamp = 0;
- vput(dvp);
+ vrele(dvp);
return (error);
}
@@ -1400,8 +1354,8 @@ nfs_remove(v)
error = nfs_sillyrename(dvp, vp, cnp);
FREE(cnp->cn_pnbuf, M_NAMEI);
np->n_attrstamp = 0;
- vput(dvp);
- vput(vp);
+ vrele(dvp);
+ vrele(vp);
return (error);
}
@@ -1412,7 +1366,7 @@ int
nfs_removeit(sp)
struct sillyrename *sp;
{
-
+
return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred,
(struct proc *)0));
}
@@ -1492,7 +1446,7 @@ nfs_rename(v)
*/
if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename &&
tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) {
- vput(tvp);
+ vrele(tvp);
tvp = NULL;
}
@@ -1700,12 +1654,12 @@ nfs_symlink(v)
}
nfsm_reqdone;
if (newvp)
- vput(newvp);
+ vrele(newvp);
FREE(cnp->cn_pnbuf, M_NAMEI);
VTONFS(dvp)->n_flag |= NMODIFIED;
if (!wccflag)
VTONFS(dvp)->n_attrstamp = 0;
- vput(dvp);
+ vrele(dvp);
/*
* Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
*/
@@ -1775,7 +1729,7 @@ nfs_mkdir(v)
*/
if (error == EEXIST || (!error && !gotvp)) {
if (newvp) {
- vput(newvp);
+ vrele(newvp);
newvp = (struct vnode *)0;
}
error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred,
@@ -1788,11 +1742,11 @@ nfs_mkdir(v)
}
if (error) {
if (newvp)
- vput(newvp);
+ vrele(newvp);
} else
*ap->a_vpp = newvp;
FREE(cnp->cn_pnbuf, M_NAMEI);
- vput(dvp);
+ vrele(dvp);
return (error);
}
@@ -1821,7 +1775,7 @@ nfs_rmdir(v)
if (dvp == vp) {
vrele(dvp);
- vput(dvp);
+ vrele(dvp);
FREE(cnp->cn_pnbuf, M_NAMEI);
return (EINVAL);
}
@@ -1840,8 +1794,8 @@ nfs_rmdir(v)
VTONFS(dvp)->n_attrstamp = 0;
cache_purge(dvp);
cache_purge(vp);
- vput(vp);
- vput(dvp);
+ vrele(vp);
+ vrele(dvp);
/*
* Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
*/
@@ -2388,7 +2342,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
nfsm_adv(nfsm_rndup(i));
}
if (newvp != NULLVP) {
- vput(newvp);
+ vrele(newvp);
newvp = NULLVP;
}
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
@@ -2429,7 +2383,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
nfsmout:
if (newvp != NULLVP)
- vput(newvp);
+ vrele(newvp);
return (error);
}
@@ -2553,7 +2507,7 @@ nfs_lookitup(dvp, name, len, cred, procp, npp)
nfsm_postop_attr(newvp, attrflag);
if (!attrflag && *npp == NULL) {
m_freem(mrep);
- vput(newvp);
+ vrele(newvp);
return (ENOENT);
}
} else
@@ -2563,7 +2517,7 @@ nfs_lookitup(dvp, name, len, cred, procp, npp)
if (npp && *npp == NULL) {
if (error) {
if (newvp)
- vput(newvp);
+ vrele(newvp);
} else
*npp = np;
}
@@ -3227,46 +3181,3 @@ nfsfifo_close(v)
return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), ap));
}
#endif /* ! FIFO */
-
-
-int
-nfs_lock(v)
- void *v;
-{
- struct vop_lock_args /* {
- struct vnode *a_vp;
- int a_flags;
- sturct proc *a_p;
- } */ *ap = v;
- struct vnode *vp = ap->a_vp;
-
- return (lockmgr(&VTONFS(vp)->n_lock, ap->a_flags, &vp->v_interlock,
- ap->a_p));
-}
-
-int
-nfs_unlock(v)
- void *v;
-{
- struct vop_unlock_args /* {
- struct vnode *a_vp;
- int a_flags;
- struct proc *a_p;
- } */ *ap = v;
- struct vnode *vp = ap->a_vp;
-
- return (lockmgr(&VTONFS(vp)->n_lock, ap->a_flags | LK_RELEASE,
- &vp->v_interlock, ap->a_p));
-}
-
-int
-nfs_islocked(v)
- void *v;
-{
- struct vop_islocked_args /* {
- struct vnode *a_vp;
- } */ *ap = v;
-
- return (lockstatus(&VTONFS(ap->a_vp)->n_lock));
-}
-