Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/nfs Do actual vnode locking for NFS.
details: https://anonhg.NetBSD.org/src/rev/daa9f39e7d5d
branches: trunk
changeset: 503445:daa9f39e7d5d
user: fvdl <fvdl%NetBSD.org@localhost>
date: Tue Feb 06 11:40:02 2001 +0000
description:
Do actual vnode locking for NFS.
diffstat:
sys/nfs/nfs_node.c | 8 +-
sys/nfs/nfs_nqlease.c | 8 +-
sys/nfs/nfs_vfsops.c | 28 ++++---
sys/nfs/nfs_vnops.c | 188 +++++++++++++++++++++++++++++++++++++------------
sys/nfs/nfsnode.h | 8 +-
5 files changed, 171 insertions(+), 69 deletions(-)
diffs (truncated from 592 to 300 lines):
diff -r 63345a474613 -r daa9f39e7d5d sys/nfs/nfs_node.c
--- a/sys/nfs/nfs_node.c Tue Feb 06 10:58:55 2001 +0000
+++ b/sys/nfs/nfs_node.c Tue Feb 06 11:40:02 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_node.c,v 1.38 2000/11/27 08:39:48 chs Exp $ */
+/* $NetBSD: nfs_node.c,v 1.39 2001/02/06 11:40:02 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -156,7 +156,6 @@
lockmgr(&nfs_hashlock, LK_RELEASE, 0);
return (error);
}
- nvp->v_vnlock = 0; /* XXX At least untill we do locking */
vp = nvp;
np = pool_get(&nfs_node_pool, PR_WAITOK);
memset(np, 0, sizeof *np);
@@ -177,6 +176,8 @@
np->n_accstamp = -1;
np->n_vattr = pool_get(&nfs_vattr_pool, PR_WAITOK);
+ lockmgr(&vp->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
+
/*
* XXXUBC doing this while holding the nfs_hashlock is bad,
* but there's no alternative at the moment.
@@ -235,9 +236,10 @@
/*
* Remove the silly file that was rename'd earlier
*/
+ vn_lock(sp->s_dvp, LK_EXCLUSIVE | LK_RETRY);
nfs_removeit(sp);
crfree(sp->s_cred);
- vrele(sp->s_dvp);
+ vput(sp->s_dvp);
FREE(sp, M_NFSREQ);
}
np->n_flag &= (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NQNFSEVICTED |
diff -r 63345a474613 -r daa9f39e7d5d sys/nfs/nfs_nqlease.c
--- a/sys/nfs/nfs_nqlease.c Tue Feb 06 10:58:55 2001 +0000
+++ b/sys/nfs/nfs_nqlease.c Tue Feb 06 11:40:02 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_nqlease.c,v 1.35 2000/11/24 23:30:02 chs Exp $ */
+/* $NetBSD: nfs_nqlease.c,v 1.36 2001/02/06 11:40:02 fvdl Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -981,7 +981,7 @@
CIRCLEQ_INSERT_HEAD(&nmp->nm_timerhead, np, n_timer);
}
}
- vrele(vp);
+ vput(vp);
nfsm_srvdone;
}
#endif /* NFS && !NFS_V2_ONLY */
@@ -1101,7 +1101,7 @@
}
}
}
- vrele(vp);
+ vput(vp);
nmp->nm_inprog = NULLVP;
}
} else if ((np->n_expiry - NQ_RENEWAL) < time.tv_sec) {
@@ -1112,7 +1112,7 @@
if (vpid == vp->v_id &&
nqnfs_getlease(vp, ND_WRITE, cred, p)==0)
np->n_brev = np->n_lrev;
- vrele(vp);
+ vput(vp);
nmp->nm_inprog = NULLVP;
}
} else
diff -r 63345a474613 -r daa9f39e7d5d sys/nfs/nfs_vfsops.c
--- a/sys/nfs/nfs_vfsops.c Tue Feb 06 10:58:55 2001 +0000
+++ b/sys/nfs/nfs_vfsops.c Tue Feb 06 11:40:02 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_vfsops.c,v 1.99 2001/01/22 12:17:41 jdolecek Exp $ */
+/* $NetBSD: nfs_vfsops.c,v 1.100 2001/02/06 11:40:02 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
@@ -207,7 +207,7 @@
}
strncpy(&sbp->f_fstypename[0], mp->mnt_op->vfs_name, MFSNAMELEN);
nfsm_reqdone;
- vrele(vp);
+ vput(vp);
crfree(cred);
return (error);
}
@@ -718,14 +718,6 @@
* point.
*/
mp->mnt_stat.f_iosize = NFS_MAXDGRAMDATA;
- /*
- * A reference count is needed on the nfsnode representing the
- * remote root. If this object is not persistent, then backward
- * traversals of the mount point (i.e. "..") will not work if
- * the nfsnode gets flushed out of the cache. Ufs does not have
- * this problem, because one can identify root inodes by their
- * number == ROOTINO (2).
- */
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
if (error)
goto bad;
@@ -740,6 +732,17 @@
crfree(cr);
}
+ /*
+ * A reference count is needed on the nfsnode representing the
+ * remote root. If this object is not persistent, then backward
+ * traversals of the mount point (i.e. "..") will not work if
+ * the nfsnode gets flushed out of the cache. Ufs does not have
+ * this problem, because one can identify root inodes by their
+ * number == ROOTINO (2). So, just unlock, but no rele.
+ */
+
+ VOP_UNLOCK(*vpp, 0);
+
return (0);
bad:
nfs_disconnect(nmp);
@@ -809,10 +812,11 @@
nmp->nm_iflag |= NFSMNT_DISMNT;
/*
- * There are two reference counts to get rid of here.
+ * There are two reference counts to get rid of here
+ * (see comment in mountnfs()).
*/
vrele(vp);
- vrele(vp);
+ vput(vp);
vgone(vp);
nfs_disconnect(nmp);
m_freem(nmp->nm_nam);
diff -r 63345a474613 -r daa9f39e7d5d sys/nfs/nfs_vnops.c
--- a/sys/nfs/nfs_vnops.c Tue Feb 06 10:58:55 2001 +0000
+++ b/sys/nfs/nfs_vnops.c Tue Feb 06 11:40:02 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nfs_vnops.c,v 1.127 2001/01/22 12:17:42 jdolecek Exp $ */
+/* $NetBSD: nfs_vnops.c,v 1.128 2001/02/06 11:40:02 fvdl Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -771,6 +771,12 @@
* nfs lookup call, one step at a time...
* First look in cache
* If not found, unlock the directory nfsnode and do the rpc
+ *
+ * This code is full of lock/unlock statements and checks, because
+ * we continue after cache_lookup has finished (we need to check
+ * with the attr cache and do an rpc if it has timed out). This means
+ * that the locking effects of cache_lookup have to be taken into
+ * account.
*/
int
nfs_lookup(v)
@@ -798,10 +804,12 @@
struct nfsnode *np;
int lockparent, wantparent, error = 0, attrflag, fhsize;
const int v3 = NFS_ISV3(dvp);
+
cnp->cn_flags &= ~PDIRUNLOCK;
flags = cnp->cn_flags;
*vpp = NULLVP;
+ newvp = NULLVP;
if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
return (EROFS);
@@ -828,20 +836,29 @@
if (error && error != ENOENT) {
*vpp = NULLVP;
- return (error);
+ return error;
+ }
+
+ if (cnp->cn_flags & PDIRUNLOCK) {
+ error = vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
+ if (error) {
+ *vpp = NULLVP;
+ return error;
+ }
+ cnp->cn_flags &= ~PDIRUNLOCK;
}
err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, cnp->cn_proc);
if (err2) {
*vpp = NULLVP;
- return (err2);
+ return err2;
}
if (error == ENOENT) {
if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred,
cnp->cn_proc) && vattr.va_mtime.tv_sec ==
VTONFS(dvp)->n_nctime)
- return (ENOENT);
+ return ENOENT;
cache_purge(dvp);
np->n_nctime = 0;
goto dorpc;
@@ -857,15 +874,16 @@
nfsstats.lookupcache_hits++;
if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
cnp->cn_flags |= SAVENAME;
+ if ((!lockparent || !(flags & ISLASTCN)) &&
+ newvp != dvp)
+ VOP_UNLOCK(dvp, 0);
return (0);
}
- /* XXX cache_lookup() returns the vnode locked; if nfs
- * would have real vnode locking, we should call VOP_UNLOCK()
- * here; as it has no real locking, don't bother to do
- * anything */
- /* VOP_UNLOCK(newvp, 0); */
cache_purge(newvp);
- vrele(newvp);
+ if (newvp != dvp)
+ vput(newvp);
+ else
+ vrele(newvp);
*vpp = NULLVP;
}
dorpc:
@@ -897,7 +915,7 @@
error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
if (error) {
m_freem(mrep);
- return (error);
+ return error;
}
newvp = NFSTOV(np);
if (v3) {
@@ -908,27 +926,80 @@
*vpp = newvp;
m_freem(mrep);
cnp->cn_flags |= SAVENAME;
- if (!lockparent || !(flags & ISLASTCN))
+ if (!lockparent) {
+ VOP_UNLOCK(dvp, 0);
cnp->cn_flags |= PDIRUNLOCK;
+ }
return (0);
}
+ /*
+ * The postop attr handling is duplicated for each if case,
+ * because it should be done while dvp is locked (unlocking
+ * dvp is different for each case).
+ */
+
if (NFS_CMPFH(np, fhp, fhsize)) {
+ /*
+ * "." lookup
+ */
VREF(dvp);
newvp = dvp;
+ if (v3) {
+ nfsm_postop_attr(newvp, attrflag);
+ nfsm_postop_attr(dvp, attrflag);
+ } else
+ nfsm_loadattr(newvp, (struct vattr *)0);
+ } else if (flags & ISDOTDOT) {
+ /*
+ * ".." lookup
+ */
+ VOP_UNLOCK(dvp, 0);
+ cnp->cn_flags |= PDIRUNLOCK;
+
+ error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
+ if (error) {
+ if (vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY) == 0)
+ cnp->cn_flags &= ~PDIRUNLOCK;
+ m_freem(mrep);
+ return error;
+ }
+ newvp = NFSTOV(np);
+
+ if (v3) {
+ nfsm_postop_attr(newvp, attrflag);
+ nfsm_postop_attr(dvp, attrflag);
+ } else
+ nfsm_loadattr(newvp, (struct vattr *)0);
+
+ if (lockparent && (flags & ISLASTCN)) {
+ if ((error = vn_lock(dvp, LK_EXCLUSIVE))) {
+ m_freem(mrep);
+ vput(newvp);
+ return error;
+ }
+ cnp->cn_flags &= ~PDIRUNLOCK;
+ }
} else {
+ /*
Home |
Main Index |
Thread Index |
Old Index