diff options
-rw-r--r-- | fs/btrfs/transaction.c | 30 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 3 |
2 files changed, 31 insertions, 2 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index e72a013d24bf..202c1b6df4a4 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/writeback.h> | 21 | #include <linux/writeback.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/blkdev.h> | ||
23 | #include "ctree.h" | 24 | #include "ctree.h" |
24 | #include "disk-io.h" | 25 | #include "disk-io.h" |
25 | #include "transaction.h" | 26 | #include "transaction.h" |
@@ -331,6 +332,7 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | |||
331 | int werr = 0; | 332 | int werr = 0; |
332 | struct page *page; | 333 | struct page *page; |
333 | struct inode *btree_inode = root->fs_info->btree_inode; | 334 | struct inode *btree_inode = root->fs_info->btree_inode; |
335 | struct extent_io_tree *io_tree = &BTRFS_I(btree_inode)->io_tree; | ||
334 | u64 start = 0; | 336 | u64 start = 0; |
335 | u64 end; | 337 | u64 end; |
336 | unsigned long index; | 338 | unsigned long index; |
@@ -371,6 +373,11 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | |||
371 | page_cache_release(page); | 373 | page_cache_release(page); |
372 | } | 374 | } |
373 | } | 375 | } |
376 | /* | ||
377 | * we unplug once and then use the wait_on_extent_bit for | ||
378 | * everything else | ||
379 | */ | ||
380 | blk_run_address_space(btree_inode->i_mapping); | ||
374 | while(1) { | 381 | while(1) { |
375 | ret = find_first_extent_bit(dirty_pages, 0, &start, &end, | 382 | ret = find_first_extent_bit(dirty_pages, 0, &start, &end, |
376 | EXTENT_DIRTY); | 383 | EXTENT_DIRTY); |
@@ -391,7 +398,28 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | |||
391 | if (err) | 398 | if (err) |
392 | werr = err; | 399 | werr = err; |
393 | } | 400 | } |
394 | wait_on_page_writeback(page); | 401 | if (PageWriteback(page)) { |
402 | /* | ||
403 | * we don't wait on the page writeback bit | ||
404 | * because that triggers a lot of unplugs. | ||
405 | * The extent bits are much nicer to | ||
406 | * the disks, but come with a slightly | ||
407 | * higher latency because we aren't forcing | ||
408 | * unplugs. | ||
409 | */ | ||
410 | wait_on_extent_writeback(io_tree, | ||
411 | page_offset(page), | ||
412 | page_offset(page) + | ||
413 | PAGE_CACHE_SIZE - 1); | ||
414 | } | ||
415 | if (PageWriteback(page)) { | ||
416 | /* | ||
417 | * the state bits get cleared before the | ||
418 | * page bits, lets add some extra | ||
419 | * paranoia here | ||
420 | */ | ||
421 | wait_on_page_writeback(page); | ||
422 | } | ||
395 | page_cache_release(page); | 423 | page_cache_release(page); |
396 | cond_resched(); | 424 | cond_resched(); |
397 | } | 425 | } |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index cbb9bb31431d..80a27284dbf1 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -200,7 +200,8 @@ loop: | |||
200 | * is now congested. Back off and let other work structs | 200 | * is now congested. Back off and let other work structs |
201 | * run instead | 201 | * run instead |
202 | */ | 202 | */ |
203 | if (pending && bdi_write_congested(bdi)) { | 203 | if (pending && bdi_write_congested(bdi) && |
204 | fs_info->fs_devices->open_devices > 1) { | ||
204 | struct bio *old_head; | 205 | struct bio *old_head; |
205 | 206 | ||
206 | spin_lock(&device->io_lock); | 207 | spin_lock(&device->io_lock); |