From 2c82bcf0eb655679065e5fb2add651e3e6dc3252 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Fri, 7 Nov 2008 18:22:45 -0500 Subject: [PATCH] --- yaml --- r: 129002 b: refs/heads/master c: 5f2cc086ccab27ac5252b3883ac004347860b4c7 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/btrfs/transaction.c | 30 +++++++++++++++++++++++++++++- trunk/fs/btrfs/volumes.c | 3 ++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 8f7261a8ebda..8a7781adf1b1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 42e70e7a2f9d96fd843723fa46d5121cb3e551d0 +refs/heads/master: 5f2cc086ccab27ac5252b3883ac004347860b4c7 diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index e72a013d24bf..202c1b6df4a4 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "ctree.h" #include "disk-io.h" #include "transaction.h" @@ -331,6 +332,7 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, int werr = 0; struct page *page; struct inode *btree_inode = root->fs_info->btree_inode; + struct extent_io_tree *io_tree = &BTRFS_I(btree_inode)->io_tree; u64 start = 0; u64 end; unsigned long index; @@ -371,6 +373,11 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, page_cache_release(page); } } + /* + * we unplug once and then use the wait_on_extent_bit for + * everything else + */ + blk_run_address_space(btree_inode->i_mapping); while(1) { ret = find_first_extent_bit(dirty_pages, 0, &start, &end, EXTENT_DIRTY); @@ -391,7 +398,28 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, if (err) werr = err; } - wait_on_page_writeback(page); + if (PageWriteback(page)) { + /* + * we don't wait on the page writeback bit + * because that triggers a lot of unplugs. + * The extent bits are much nicer to + * the disks, but come with a slightly + * higher latency because we aren't forcing + * unplugs. + */ + wait_on_extent_writeback(io_tree, + page_offset(page), + page_offset(page) + + PAGE_CACHE_SIZE - 1); + } + if (PageWriteback(page)) { + /* + * the state bits get cleared before the + * page bits, lets add some extra + * paranoia here + */ + wait_on_page_writeback(page); + } page_cache_release(page); cond_resched(); } diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index cbb9bb31431d..80a27284dbf1 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -200,7 +200,8 @@ static int noinline run_scheduled_bios(struct btrfs_device *device) * is now congested. Back off and let other work structs * run instead */ - if (pending && bdi_write_congested(bdi)) { + if (pending && bdi_write_congested(bdi) && + fs_info->fs_devices->open_devices > 1) { struct bio *old_head; spin_lock(&device->io_lock);