aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/transaction.c45
-rw-r--r--fs/btrfs/transaction.h4
-rw-r--r--fs/btrfs/tree-log.c8
3 files changed, 53 insertions, 4 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 0b8f36d4400a..bca82a4ca8e6 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -344,10 +344,10 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
344/* 344/*
345 * when btree blocks are allocated, they have some corresponding bits set for 345 * when btree blocks are allocated, they have some corresponding bits set for
346 * them in one of two extent_io trees. This is used to make sure all of 346 * them in one of two extent_io trees. This is used to make sure all of
347 * those extents are on disk for transaction or log commit 347 * those extents are sent to disk but does not wait on them
348 */ 348 */
349int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, 349int btrfs_write_marked_extents(struct btrfs_root *root,
350 struct extent_io_tree *dirty_pages) 350 struct extent_io_tree *dirty_pages)
351{ 351{
352 int ret; 352 int ret;
353 int err = 0; 353 int err = 0;
@@ -394,6 +394,29 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
394 page_cache_release(page); 394 page_cache_release(page);
395 } 395 }
396 } 396 }
397 if (err)
398 werr = err;
399 return werr;
400}
401
402/*
403 * when btree blocks are allocated, they have some corresponding bits set for
404 * them in one of two extent_io trees. This is used to make sure all of
405 * those extents are on disk for transaction or log commit. We wait
406 * on all the pages and clear them from the dirty pages state tree
407 */
408int btrfs_wait_marked_extents(struct btrfs_root *root,
409 struct extent_io_tree *dirty_pages)
410{
411 int ret;
412 int err = 0;
413 int werr = 0;
414 struct page *page;
415 struct inode *btree_inode = root->fs_info->btree_inode;
416 u64 start = 0;
417 u64 end;
418 unsigned long index;
419
397 while (1) { 420 while (1) {
398 ret = find_first_extent_bit(dirty_pages, 0, &start, &end, 421 ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
399 EXTENT_DIRTY); 422 EXTENT_DIRTY);
@@ -424,6 +447,22 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
424 return werr; 447 return werr;
425} 448}
426 449
450/*
451 * when btree blocks are allocated, they have some corresponding bits set for
452 * them in one of two extent_io trees. This is used to make sure all of
453 * those extents are on disk for transaction or log commit
454 */
455int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
456 struct extent_io_tree *dirty_pages)
457{
458 int ret;
459 int ret2;
460
461 ret = btrfs_write_marked_extents(root, dirty_pages);
462 ret2 = btrfs_wait_marked_extents(root, dirty_pages);
463 return ret || ret2;
464}
465
427int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 466int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
428 struct btrfs_root *root) 467 struct btrfs_root *root)
429{ 468{
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index f68cbbe61e56..d4e3e7a6938c 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -108,5 +108,9 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
108 struct btrfs_root *root); 108 struct btrfs_root *root);
109int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, 109int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
110 struct extent_io_tree *dirty_pages); 110 struct extent_io_tree *dirty_pages);
111int btrfs_write_marked_extents(struct btrfs_root *root,
112 struct extent_io_tree *dirty_pages);
113int btrfs_wait_marked_extents(struct btrfs_root *root,
114 struct extent_io_tree *dirty_pages);
111int btrfs_transaction_in_commit(struct btrfs_fs_info *info); 115int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
112#endif 116#endif
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 0a1bde268963..4aff766d171a 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -2013,7 +2013,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2013 goto out; 2013 goto out;
2014 } 2014 }
2015 2015
2016 ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); 2016 /* we start IO on all the marked extents here, but we don't actually
2017 * wait for them until later.
2018 */
2019 ret = btrfs_write_marked_extents(log, &log->dirty_log_pages);
2017 BUG_ON(ret); 2020 BUG_ON(ret);
2018 2021
2019 btrfs_set_root_node(&log->root_item, log->node); 2022 btrfs_set_root_node(&log->root_item, log->node);
@@ -2048,6 +2051,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2048 2051
2049 index2 = log_root_tree->log_transid % 2; 2052 index2 = log_root_tree->log_transid % 2;
2050 if (atomic_read(&log_root_tree->log_commit[index2])) { 2053 if (atomic_read(&log_root_tree->log_commit[index2])) {
2054 btrfs_wait_marked_extents(log, &log->dirty_log_pages);
2051 wait_log_commit(trans, log_root_tree, 2055 wait_log_commit(trans, log_root_tree,
2052 log_root_tree->log_transid); 2056 log_root_tree->log_transid);
2053 mutex_unlock(&log_root_tree->log_mutex); 2057 mutex_unlock(&log_root_tree->log_mutex);
@@ -2067,6 +2071,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2067 * check the full commit flag again 2071 * check the full commit flag again
2068 */ 2072 */
2069 if (root->fs_info->last_trans_log_full_commit == trans->transid) { 2073 if (root->fs_info->last_trans_log_full_commit == trans->transid) {
2074 btrfs_wait_marked_extents(log, &log->dirty_log_pages);
2070 mutex_unlock(&log_root_tree->log_mutex); 2075 mutex_unlock(&log_root_tree->log_mutex);
2071 ret = -EAGAIN; 2076 ret = -EAGAIN;
2072 goto out_wake_log_root; 2077 goto out_wake_log_root;
@@ -2075,6 +2080,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2075 ret = btrfs_write_and_wait_marked_extents(log_root_tree, 2080 ret = btrfs_write_and_wait_marked_extents(log_root_tree,
2076 &log_root_tree->dirty_log_pages); 2081 &log_root_tree->dirty_log_pages);
2077 BUG_ON(ret); 2082 BUG_ON(ret);
2083 btrfs_wait_marked_extents(log, &log->dirty_log_pages);
2078 2084
2079 btrfs_set_super_log_root(&root->fs_info->super_for_commit, 2085 btrfs_set_super_log_root(&root->fs_info->super_for_commit,
2080 log_root_tree->node->start); 2086 log_root_tree->node->start);