diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-02-23 23:47:14 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-02-23 23:47:14 +0000 |
commit | 648f8e79cec49f65d44e3f4bfc063ddeca2bb5ae (patch) | |
tree | a5f3149713bec28221eb0120fbed56c473d55791 /sys/nfs/nfs_vnops.c | |
parent | c9c250d5ccd909b5dacacda2f547effffa788186 (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.c | 167 |
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)); -} - |