summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2002-09-25 02:38:43 +0000
committerjeff <jeff@FreeBSD.org>2002-09-25 02:38:43 +0000
commit5c7f8a426d77fd9157454ef8c03ad4298759b909 (patch)
tree92aceb1e68b4986cdcf026c3e92a8d9144c2ce36
parent906daccf7224474d155117b8c9b209624ea6ec01 (diff)
downloadFreeBSD-src-5c7f8a426d77fd9157454ef8c03ad4298759b909.zip
FreeBSD-src-5c7f8a426d77fd9157454ef8c03ad4298759b909.tar.gz
- Lock access to the buf lists.
- Use vrefcnt() where appropriate. - Add some locking asserts.
-rw-r--r--sys/nfsclient/nfs_bio.c2
-rw-r--r--sys/nfsclient/nfs_node.c6
-rw-r--r--sys/nfsclient/nfs_subs.c4
-rw-r--r--sys/nfsclient/nfs_vfsops.c4
-rw-r--r--sys/nfsclient/nfs_vnops.c36
5 files changed, 36 insertions, 16 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
index d8243ae..f88b04c 100644
--- a/sys/nfsclient/nfs_bio.c
+++ b/sys/nfsclient/nfs_bio.c
@@ -1344,7 +1344,7 @@ nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td)
uiop->uio_resid = 0;
}
}
- mp_fixme("Accessing VV_TEXT without a lock.");
+ ASSERT_VOP_LOCKED(vp, "nfs_doio");
if (p && (vp->v_vflag & VV_TEXT) &&
(np->n_mtime != np->n_vattr.va_mtime.tv_sec)) {
uprintf("Process killed due to text file modification\n");
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index 90ef7aa..34729a3 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -281,7 +281,7 @@ nfs_inactive(struct vop_inactive_args *ap)
struct thread *td = curthread; /* XXX */
np = VTONFS(ap->a_vp);
- if (prtactive && ap->a_vp->v_usecount != 0)
+ if (prtactive && vrefcnt(ap->a_vp) != 0)
vprint("nfs_inactive: pushing active", ap->a_vp);
if (ap->a_vp->v_type != VDIR) {
sp = np->n_sillyrename;
@@ -296,7 +296,7 @@ nfs_inactive(struct vop_inactive_args *ap)
* are being forcibly unmounted in which case we already
* have our own reference.
*/
- if (ap->a_vp->v_usecount > 0)
+ if (vrefcnt(ap->a_vp) > 0)
(void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, td, 1);
else if (vget(ap->a_vp, 0, td))
panic("nfs_inactive: lost vnode");
@@ -327,7 +327,7 @@ nfs_reclaim(struct vop_reclaim_args *ap)
struct nfsnode *np = VTONFS(vp);
struct nfsdmap *dp, *dp2;
- if (prtactive && vp->v_usecount != 0)
+ if (prtactive && vrefcnt(vp) != 0)
vprint("nfs_reclaim: pushing active", vp);
if (np->n_hash.le_prev != NULL) /* XXX beware */
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
index 1305122..c88f51e 100644
--- a/sys/nfsclient/nfs_subs.c
+++ b/sys/nfsclient/nfs_subs.c
@@ -793,6 +793,8 @@ loop:
if (vp->v_mount != mp) /* Paranoia */
goto loop;
nvp = TAILQ_NEXT(vp, v_nmntvnodes);
+ VI_LOCK(vp);
+ mtx_unlock(&mntvnode_mtx);
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
nbp = TAILQ_NEXT(bp, b_vnbufs);
if (BUF_REFCNT(bp) == 0 &&
@@ -800,6 +802,8 @@ loop:
== (B_DELWRI | B_NEEDCOMMIT))
bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
}
+ VI_UNLOCK(vp);
+ mtx_lock(&mntvnode_mtx);
}
mtx_unlock(&mntvnode_mtx);
splx(s);
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index f4a083d..04deade 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -980,10 +980,10 @@ loop:
goto loop;
vnp = TAILQ_NEXT(vp, v_nmntvnodes);
mtx_unlock(&mntvnode_mtx);
- mtx_lock(&vp->v_interlock);
+ VI_LOCK(vp);
if (VOP_ISLOCKED(vp, NULL) || TAILQ_EMPTY(&vp->v_dirtyblkhd) ||
waitfor == MNT_LAZY) {
- mtx_unlock(&vp->v_interlock);
+ VI_UNLOCK(vp);
mtx_lock(&mntvnode_mtx);
continue;
}
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index e55eb00..dff0baa 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -1419,12 +1419,12 @@ nfs_remove(struct vop_remove_args *ap)
#ifndef DIAGNOSTIC
if ((cnp->cn_flags & HASBUF) == 0)
panic("nfs_remove: no name");
- if (vp->v_usecount < 1)
+ if (vrefcnt(vp) < 1)
panic("nfs_remove: bad v_usecount");
#endif
if (vp->v_type == VDIR)
error = EPERM;
- else if (vp->v_usecount == 1 || (np->n_sillyrename &&
+ else if (vrefcnt(vp) == 1 || (np->n_sillyrename &&
VOP_GETATTR(vp, &vattr, cnp->cn_cred, cnp->cn_thread) == 0 &&
vattr.va_nlink > 1)) {
/*
@@ -1543,7 +1543,7 @@ nfs_rename(struct vop_rename_args *ap)
* rename of the new file over it.
* XXX Can't sillyrename a directory.
*/
- if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename &&
+ if (tvp && vrefcnt(tvp) > 1 && !VTONFS(tvp)->n_sillyrename &&
tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) {
vput(tvp);
tvp = NULL;
@@ -2616,6 +2616,7 @@ again:
* Count up how many buffers waiting for a commit.
*/
bveccount = 0;
+ VI_LOCK(vp);
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
nbp = TAILQ_NEXT(bp, b_vnbufs);
if (BUF_REFCNT(bp) == 0 &&
@@ -2645,13 +2646,16 @@ again:
bvecsize = NFS_COMMITBVECSIZ;
}
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
- nbp = TAILQ_NEXT(bp, b_vnbufs);
if (bvecpos >= bvecsize)
break;
+ VI_UNLOCK(vp);
if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) !=
(B_DELWRI | B_NEEDCOMMIT) ||
- BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT))
+ BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
+ VI_LOCK(vp);
+ nbp = TAILQ_NEXT(bp, b_vnbufs);
continue;
+ }
bremfree(bp);
/*
* Work out if all buffers are using the same cred
@@ -2671,6 +2675,7 @@ again:
bp->b_flags |= B_WRITEINPROG;
vfs_busy_pages(bp, 1);
+ VI_LOCK(vp);
/*
* bp is protected by being locked, but nbp is not
* and vfs_busy_pages() may sleep. We have to
@@ -2695,6 +2700,7 @@ again:
endoff = toff;
}
splx(s);
+ VI_UNLOCK(vp);
}
if (bvecpos > 0) {
/*
@@ -2747,7 +2753,9 @@ again:
* into bundirty(). XXX
*/
s = splbio();
+ VI_LOCK(vp);
vp->v_numoutput++;
+ VI_UNLOCK(vp);
bp->b_flags |= B_ASYNC;
bundirty(bp);
bp->b_flags &= ~B_DONE;
@@ -2764,11 +2772,15 @@ again:
*/
loop:
s = splbio();
+ VI_LOCK(vp);
for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) {
nbp = TAILQ_NEXT(bp, b_vnbufs);
+ VI_UNLOCK(vp);
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT)) {
- if (waitfor != MNT_WAIT || passone)
+ if (waitfor != MNT_WAIT || passone) {
+ VI_LOCK(vp);
continue;
+ }
error = BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL,
"nfsfsync", slpflag, slptimeo);
splx(s);
@@ -2790,6 +2802,7 @@ loop:
panic("nfs_fsync: not dirty");
if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) {
BUF_UNLOCK(bp);
+ VI_LOCK(vp);
continue;
}
bremfree(bp);
@@ -2804,10 +2817,10 @@ loop:
splx(s);
if (passone) {
passone = 0;
+ VI_UNLOCK(vp);
goto again;
}
if (waitfor == MNT_WAIT) {
- VI_LOCK(vp);
while (vp->v_numoutput) {
vp->v_iflag |= VI_BWAIT;
error = msleep((caddr_t)&vp->v_numoutput, VI_MTX(vp),
@@ -2824,11 +2837,12 @@ loop:
}
}
}
- VI_UNLOCK(vp);
if (!TAILQ_EMPTY(&vp->v_dirtyblkhd) && commit) {
+ VI_UNLOCK(vp);
goto loop;
}
}
+ VI_UNLOCK(vp);
if (np->n_flag & NWRITEERR) {
error = np->n_error;
np->n_flag &= ~NWRITEERR;
@@ -2907,7 +2921,9 @@ nfs_writebp(struct buf *bp, int force, struct thread *td)
bp->b_ioflags &= ~BIO_ERROR;
bp->b_iocmd = BIO_WRITE;
+ VI_LOCK(bp->b_vp);
bp->b_vp->v_numoutput++;
+ VI_UNLOCK(bp->b_vp);
curthread->td_proc->p_stats->p_ru.ru_oublock++;
splx(s);
@@ -3045,7 +3061,7 @@ nfsspec_close(struct vop_close_args *ap)
if (np->n_flag & (NACC | NUPD)) {
np->n_flag |= NCHG;
- if (vp->v_usecount == 1 &&
+ if (vrefcnt(vp) == 1 &&
(vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
VATTR_NULL(&vattr);
if (np->n_flag & NACC)
@@ -3110,7 +3126,7 @@ nfsfifo_close(struct vop_close_args *ap)
if (np->n_flag & NUPD)
np->n_mtim = ts;
np->n_flag |= NCHG;
- if (vp->v_usecount == 1 &&
+ if (vrefcnt(vp) == 1 &&
(vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
VATTR_NULL(&vattr);
if (np->n_flag & NACC)
OpenPOWER on IntegriCloud