From: matthew Date: Tue, 3 Aug 2010 04:10:16 +0000 (+0000) Subject: If an asynchronous request invalidates a buf, then we might remove it X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=68b1adfeabd7627ee019b45160095fa1f6a8bc77;p=openbsd If an asynchronous request invalidates a buf, then we might remove it from its vnode's buffer cache in an interrupt context. Therefore we need interrupt protection when searching the buffer red-black tree. ok deraadt@, thib@, art@ --- diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 774dfc794ff..0b7b2ccde22 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_bio.c,v 1.124 2010/07/01 16:23:09 thib Exp $ */ +/* $OpenBSD: vfs_bio.c,v 1.125 2010/08/03 04:10:16 matthew Exp $ */ /* $NetBSD: vfs_bio.c,v 1.44 1996/06/11 11:15:36 pk Exp $ */ /* @@ -873,12 +873,17 @@ incore(struct vnode *vp, daddr64_t blkno) { struct buf *bp; struct buf b; + int s; + + s = splbio(); /* Search buf lookup tree */ b.b_lblkno = blkno; bp = RB_FIND(buf_rb_bufs, &vp->v_bufs_tree, &b); - if (bp && !ISSET(bp->b_flags, B_INVAL)) - return(bp); + if (bp != NULL && ISSET(bp->b_flags, B_INVAL)) + bp = NULL; + + splx(s); return(NULL); } @@ -908,11 +913,10 @@ getblk(struct vnode *vp, daddr64_t blkno, int size, int slpflag, int slptimeo) * the block until the write is finished. */ start: + s = splbio(); b.b_lblkno = blkno; bp = RB_FIND(buf_rb_bufs, &vp->v_bufs_tree, &b); if (bp != NULL) { - - s = splbio(); if (ISSET(bp->b_flags, B_BUSY)) { SET(bp->b_flags, B_WANTED); error = tsleep(bp, slpflag | (PRIBIO + 1), "getblk", @@ -931,8 +935,8 @@ start: splx(s); return (bp); } - splx(s); } + splx(s); if ((bp = buf_get(vp, blkno, size)) == NULL) goto start;