summaryrefslogtreecommitdiff
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-08-15 19:34:15 (GMT)
committerChris Mason <chris.mason@oracle.com>2008-09-25 15:04:06 (GMT)
commit777e6bd706ee40897545463871de5b456fbc46dc (patch)
treecb927528e02234eb7fa6b5d1f14b9367efd755b6 /fs/btrfs/transaction.c
parent0986fe9eac24fd186927c3b87af51d62f8ab92cd (diff)
downloadlinux-fsl-qoriq-777e6bd706ee40897545463871de5b456fbc46dc.tar.xz
Btrfs: Transaction commit: don't use filemap_fdatawait
After writing out all the remaining btree blocks in the transaction, the commit code would use filemap_fdatawait to make sure it was all on disk. This means it would wait for blocks written by other procs as well. The new code walks the list of blocks for this transaction again and waits only for those required by this transaction. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 9d3d08e..6bcb087 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -303,12 +303,12 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
int ret;
- int err;
+ int err = 0;
int werr = 0;
struct extent_io_tree *dirty_pages;
struct page *page;
struct inode *btree_inode = root->fs_info->btree_inode;
- u64 start;
+ u64 start = 0;
u64 end;
unsigned long index;
@@ -317,12 +317,15 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
}
dirty_pages = &trans->transaction->dirty_pages;
while(1) {
- ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
+ ret = find_first_extent_bit(dirty_pages, start, &start, &end,
EXTENT_DIRTY);
if (ret)
break;
- clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
while(start <= end) {
+ if (btrfs_congested_async(root->fs_info, 0))
+ congestion_wait(WRITE, HZ/10);
+ cond_resched();
+
index = start >> PAGE_CACHE_SHIFT;
start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
page = find_lock_page(btree_inode->i_mapping, index);
@@ -343,7 +346,30 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
page_cache_release(page);
}
}
- err = filemap_fdatawait(btree_inode->i_mapping);
+ while(1) {
+ ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
+ EXTENT_DIRTY);
+ if (ret)
+ break;
+
+ clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
+ while(start <= end) {
+ index = start >> PAGE_CACHE_SHIFT;
+ start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
+ page = find_get_page(btree_inode->i_mapping, index);
+ if (!page)
+ continue;
+ if (PageDirty(page)) {
+ lock_page(page);
+ err = write_one_page(page, 0);
+ if (err)
+ werr = err;
+ }
+ wait_on_page_writeback(page);
+ page_cache_release(page);
+ cond_resched();
+ }
+ }
if (err)
werr = err;
return werr;