diff options
author | attilio <attilio@FreeBSD.org> | 2013-02-27 18:17:34 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2013-02-27 18:17:34 +0000 |
commit | 52c57fbbdb554a7ce0cdbb6bf27051ef70834bdf (patch) | |
tree | d0908474209a17865e044675940a2f62f9ff2493 /sys/kern/vfs_bio.c | |
parent | c74a3afc6a5d7d1ced989c36d4ba0a7d2bbc43b9 (diff) | |
download | FreeBSD-src-52c57fbbdb554a7ce0cdbb6bf27051ef70834bdf.zip FreeBSD-src-52c57fbbdb554a7ce0cdbb6bf27051ef70834bdf.tar.gz |
MFC
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 66da0d0..6d110ab 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -1269,6 +1269,15 @@ brelse(struct buf *bp) KASSERT(!(bp->b_flags & (B_CLUSTER|B_PAGING)), ("brelse: inappropriate B_PAGING or B_CLUSTER bp %p", bp)); + if (BUF_LOCKRECURSED(bp)) { + /* + * Do not process, in particular, do not handle the + * B_INVAL/B_RELBUF and do not release to free list. + */ + BUF_UNLOCK(bp); + return; + } + if (bp->b_flags & B_MANAGED) { bqrelse(bp); return; @@ -1445,12 +1454,6 @@ brelse(struct buf *bp) brelvp(bp); } - if (BUF_LOCKRECURSED(bp)) { - /* do not release to free list */ - BUF_UNLOCK(bp); - return; - } - /* enqueue */ mtx_lock(&bqlock); /* Handle delayed bremfree() processing. */ @@ -2682,6 +2685,9 @@ loop: /* We timed out or were interrupted. */ else if (error) return (NULL); + /* If recursed, assume caller knows the rules. */ + else if (BUF_LOCKRECURSED(bp)) + goto end; /* * The buffer is locked. B_CACHE is cleared if the buffer is @@ -2865,6 +2871,7 @@ loop: } CTR4(KTR_BUF, "getblk(%p, %ld, %d) = %p", vp, (long)blkno, size, bp); BUF_ASSERT_HELD(bp); +end: KASSERT(bp->b_bufobj == bo, ("bp %p wrong b_bufobj %p should be %p", bp, bp->b_bufobj, bo)); return (bp); |