- Lock access to the buf lists.

- Use vrefcnt() where appropriate.
 - Add some locking asserts.
This commit is contained in:
Jeff Roberson 2002-09-25 02:38:43 +00:00
parent 431886406c
commit 8926aed697
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103939
5 changed files with 36 additions and 16 deletions

View File

@ -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");

View File

@ -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 */

View File

@ -793,6 +793,8 @@ nfs_clearcommit(struct mount *mp)
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 @@ nfs_clearcommit(struct mount *mp)
== (B_DELWRI | B_NEEDCOMMIT))
bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
}
VI_UNLOCK(vp);
mtx_lock(&mntvnode_mtx);
}
mtx_unlock(&mntvnode_mtx);
splx(s);

View File

@ -980,10 +980,10 @@ nfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct thread *td)
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;
}

View File

@ -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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
* 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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
endoff = toff;
}
splx(s);
VI_UNLOCK(vp);
}
if (bvecpos > 0) {
/*
@ -2747,7 +2753,9 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
* 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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
*/
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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
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 @@ nfs_flush(struct vnode *vp, struct ucred *cred, int waitfor, struct thread *td,
}
}
}
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)