summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2006-10-29 00:04:39 +0000
committeralc <alc@FreeBSD.org>2006-10-29 00:04:39 +0000
commitce403a9391c09c72c03d76000ef81c891161fb01 (patch)
tree4e241f59d16f3c1a9ea1cee73f465d95aa6c20c1
parent417527cc24aab508dd12868c6cfc59d73475e86c (diff)
downloadFreeBSD-src-ce403a9391c09c72c03d76000ef81c891161fb01.zip
FreeBSD-src-ce403a9391c09c72c03d76000ef81c891161fb01.tar.gz
Refactor vfs_setdirty(), creating vfs_setdirty_locked_object().
Call vfs_setdirty_locked_object() from vfs_busy_pages() instead of vfs_setdirty(), thereby eliminating a second acquisition and release of the same vm object lock.
-rw-r--r--sys/kern/vfs_bio.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index d747c1d..db2aacd 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -99,6 +99,7 @@ static void vfs_page_set_valid(struct buf *bp, vm_ooffset_t off,
int pageno, vm_page_t m);
static void vfs_clean_pages(struct buf *bp);
static void vfs_setdirty(struct buf *bp);
+static void vfs_setdirty_locked_object(struct buf *bp);
static void vfs_vmio_release(struct buf *bp);
static int vfs_bio_clcheck(struct vnode *vp, int size,
daddr_t lblkno, daddr_t blkno);
@@ -2284,8 +2285,6 @@ notinmem:
static void
vfs_setdirty(struct buf *bp)
{
- int i;
- vm_object_t object;
/*
* Degenerate case - empty buffer
@@ -2302,8 +2301,19 @@ vfs_setdirty(struct buf *bp)
if ((bp->b_flags & B_VMIO) == 0)
return;
- object = bp->b_pages[0]->object;
- VM_OBJECT_LOCK(object);
+ VM_OBJECT_LOCK(bp->b_bufobj->bo_object);
+ vfs_setdirty_locked_object(bp);
+ VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object);
+}
+
+static void
+vfs_setdirty_locked_object(struct buf *bp)
+{
+ vm_object_t object;
+ int i;
+
+ object = bp->b_bufobj->bo_object;
+ VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
if (object->flags & (OBJ_MIGHTBEDIRTY|OBJ_CLEANING)) {
vm_offset_t boffset;
vm_offset_t eoffset;
@@ -2354,7 +2364,6 @@ vfs_setdirty(struct buf *bp)
bp->b_dirtyend = eoffset;
}
}
- VM_OBJECT_UNLOCK(object);
}
/*
@@ -3398,8 +3407,9 @@ vfs_busy_pages(struct buf *bp, int clear_modify)
foff = bp->b_offset;
KASSERT(bp->b_offset != NOOFFSET,
("vfs_busy_pages: no buffer offset"));
- vfs_setdirty(bp);
VM_OBJECT_LOCK(obj);
+ if (bp->b_bufsize != 0)
+ vfs_setdirty_locked_object(bp);
retry:
for (i = 0; i < bp->b_npages; i++) {
m = bp->b_pages[i];
OpenPOWER on IntegriCloud