aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-10-16 07:33:38 -0400
committerJosef Bacik <jbacik@fusionio.com>2012-12-11 13:31:31 -0500
commit08e007d2e57744472a9424735a368ffe6d625597 (patch)
tree84227c096c05bc4c5430190f0f550b094d3bf2b7 /fs/btrfs/transaction.c
parent561c294d4cfb30c4acfa0a243448fc55af730d87 (diff)
Btrfs: improve the noflush reservation
In some places(such as: evicting inode), we just can not flush the reserved space of delalloc, flushing the delayed directory index and delayed inode is OK, but we don't try to flush those things and just go back when there is no enough space to be reserved. This patch fixes this problem. We defined 3 types of the flush operations: NO_FLUSH, FLUSH_LIMIT and FLUSH_ALL. If we can in the transaction, we should not flush anything, or the deadlock would happen, so use NO_FLUSH. If we flushing the reserved space of delalloc would cause deadlock, use FLUSH_LIMIT. In the other cases, FLUSH_ALL is used, and we will flush all things. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 04bbfb1052e..4e1def4c06b 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -295,9 +295,9 @@ static int may_wait_transaction(struct btrfs_root *root, int type)
295 return 0; 295 return 0;
296} 296}
297 297
298static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, 298static struct btrfs_trans_handle *
299 u64 num_items, int type, 299start_transaction(struct btrfs_root *root, u64 num_items, int type,
300 int noflush) 300 enum btrfs_reserve_flush_enum flush)
301{ 301{
302 struct btrfs_trans_handle *h; 302 struct btrfs_trans_handle *h;
303 struct btrfs_transaction *cur_trans; 303 struct btrfs_transaction *cur_trans;
@@ -331,14 +331,9 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
331 } 331 }
332 332
333 num_bytes = btrfs_calc_trans_metadata_size(root, num_items); 333 num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
334 if (noflush) 334 ret = btrfs_block_rsv_add(root,
335 ret = btrfs_block_rsv_add_noflush(root, 335 &root->fs_info->trans_block_rsv,
336 &root->fs_info->trans_block_rsv, 336 num_bytes, flush);
337 num_bytes);
338 else
339 ret = btrfs_block_rsv_add(root,
340 &root->fs_info->trans_block_rsv,
341 num_bytes);
342 if (ret) 337 if (ret)
343 return ERR_PTR(ret); 338 return ERR_PTR(ret);
344 } 339 }
@@ -422,13 +417,15 @@ got_it:
422struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, 417struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
423 int num_items) 418 int num_items)
424{ 419{
425 return start_transaction(root, num_items, TRANS_START, 0); 420 return start_transaction(root, num_items, TRANS_START,
421 BTRFS_RESERVE_FLUSH_ALL);
426} 422}
427 423
428struct btrfs_trans_handle *btrfs_start_transaction_noflush( 424struct btrfs_trans_handle *btrfs_start_transaction_lflush(
429 struct btrfs_root *root, int num_items) 425 struct btrfs_root *root, int num_items)
430{ 426{
431 return start_transaction(root, num_items, TRANS_START, 1); 427 return start_transaction(root, num_items, TRANS_START,
428 BTRFS_RESERVE_FLUSH_LIMIT);
432} 429}
433 430
434struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root) 431struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root)
@@ -1032,8 +1029,9 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1032 btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); 1029 btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
1033 1030
1034 if (to_reserve > 0) { 1031 if (to_reserve > 0) {
1035 ret = btrfs_block_rsv_add_noflush(root, &pending->block_rsv, 1032 ret = btrfs_block_rsv_add(root, &pending->block_rsv,
1036 to_reserve); 1033 to_reserve,
1034 BTRFS_RESERVE_NO_FLUSH);
1037 if (ret) { 1035 if (ret) {
1038 pending->error = ret; 1036 pending->error = ret;
1039 goto no_free_objectid; 1037 goto no_free_objectid;