aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-08-15 15:34:15 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:06 -0400
commit777e6bd706ee40897545463871de5b456fbc46dc (patch)
treecb927528e02234eb7fa6b5d1f14b9367efd755b6 /fs/btrfs/transaction.c
parent0986fe9eac24fd186927c3b87af51d62f8ab92cd (diff)
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 9d3d08e9f8d1..6bcb0876f9bb 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,
303 struct btrfs_root *root) 303 struct btrfs_root *root)
304{ 304{
305 int ret; 305 int ret;
306 int err; 306 int err = 0;
307 int werr = 0; 307 int werr = 0;
308 struct extent_io_tree *dirty_pages; 308 struct extent_io_tree *dirty_pages;
309 struct page *page; 309 struct page *page;
310 struct inode *btree_inode = root->fs_info->btree_inode; 310 struct inode *btree_inode = root->fs_info->btree_inode;
311 u64 start; 311 u64 start = 0;
312 u64 end; 312 u64 end;
313 unsigned long index; 313 unsigned long index;
314 314
@@ -317,12 +317,15 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
317 } 317 }
318 dirty_pages = &trans->transaction->dirty_pages; 318 dirty_pages = &trans->transaction->dirty_pages;
319 while(1) { 319 while(1) {
320 ret = find_first_extent_bit(dirty_pages, 0, &start, &end, 320 ret = find_first_extent_bit(dirty_pages, start, &start, &end,
321 EXTENT_DIRTY); 321 EXTENT_DIRTY);
322 if (ret) 322 if (ret)
323 break; 323 break;
324 clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
325 while(start <= end) { 324 while(start <= end) {
325 if (btrfs_congested_async(root->fs_info, 0))
326 congestion_wait(WRITE, HZ/10);
327 cond_resched();
328
326 index = start >> PAGE_CACHE_SHIFT; 329 index = start >> PAGE_CACHE_SHIFT;
327 start = (u64)(index + 1) << PAGE_CACHE_SHIFT; 330 start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
328 page = find_lock_page(btree_inode->i_mapping, index); 331 page = find_lock_page(btree_inode->i_mapping, index);
@@ -343,7 +346,30 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
343 page_cache_release(page); 346 page_cache_release(page);
344 } 347 }
345 } 348 }
346 err = filemap_fdatawait(btree_inode->i_mapping); 349 while(1) {
350 ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
351 EXTENT_DIRTY);
352 if (ret)
353 break;
354
355 clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
356 while(start <= end) {
357 index = start >> PAGE_CACHE_SHIFT;
358 start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
359 page = find_get_page(btree_inode->i_mapping, index);
360 if (!page)
361 continue;
362 if (PageDirty(page)) {
363 lock_page(page);
364 err = write_one_page(page, 0);
365 if (err)
366 werr = err;
367 }
368 wait_on_page_writeback(page);
369 page_cache_release(page);
370 cond_resched();
371 }
372 }
347 if (err) 373 if (err)
348 werr = err; 374 werr = err;
349 return werr; 375 return werr;