aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c70
1 files changed, 58 insertions, 12 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 2616491a5c5b..6217bb6d516a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -321,10 +321,36 @@ void btrfs_throttle(struct btrfs_root *root)
321 mutex_unlock(&root->fs_info->trans_mutex); 321 mutex_unlock(&root->fs_info->trans_mutex);
322} 322}
323 323
324static int should_end_transaction(struct btrfs_trans_handle *trans,
325 struct btrfs_root *root)
326{
327 int ret;
328 ret = btrfs_block_rsv_check(trans, root,
329 &root->fs_info->global_block_rsv, 0, 5);
330 return ret ? 1 : 0;
331}
332
333int btrfs_should_end_transaction(struct btrfs_trans_handle *trans,
334 struct btrfs_root *root)
335{
336 struct btrfs_transaction *cur_trans = trans->transaction;
337 int updates;
338
339 if (cur_trans->blocked || cur_trans->delayed_refs.flushing)
340 return 1;
341
342 updates = trans->delayed_ref_updates;
343 trans->delayed_ref_updates = 0;
344 if (updates)
345 btrfs_run_delayed_refs(trans, root, updates);
346
347 return should_end_transaction(trans, root);
348}
349
324static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, 350static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
325 struct btrfs_root *root, int throttle) 351 struct btrfs_root *root, int throttle)
326{ 352{
327 struct btrfs_transaction *cur_trans; 353 struct btrfs_transaction *cur_trans = trans->transaction;
328 struct btrfs_fs_info *info = root->fs_info; 354 struct btrfs_fs_info *info = root->fs_info;
329 int count = 0; 355 int count = 0;
330 356
@@ -350,9 +376,19 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
350 376
351 btrfs_trans_release_metadata(trans, root); 377 btrfs_trans_release_metadata(trans, root);
352 378
379 if (!root->fs_info->open_ioctl_trans &&
380 should_end_transaction(trans, root))
381 trans->transaction->blocked = 1;
382
383 if (cur_trans->blocked && !cur_trans->in_commit) {
384 if (throttle)
385 return btrfs_commit_transaction(trans, root);
386 else
387 wake_up_process(info->transaction_kthread);
388 }
389
353 mutex_lock(&info->trans_mutex); 390 mutex_lock(&info->trans_mutex);
354 cur_trans = info->running_transaction; 391 WARN_ON(cur_trans != info->running_transaction);
355 WARN_ON(cur_trans != trans->transaction);
356 WARN_ON(cur_trans->num_writers < 1); 392 WARN_ON(cur_trans->num_writers < 1);
357 cur_trans->num_writers--; 393 cur_trans->num_writers--;
358 394
@@ -664,30 +700,30 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
664int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) 700int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
665{ 701{
666 struct btrfs_fs_info *info = root->fs_info; 702 struct btrfs_fs_info *info = root->fs_info;
667 int ret;
668 struct btrfs_trans_handle *trans; 703 struct btrfs_trans_handle *trans;
704 int ret;
669 unsigned long nr; 705 unsigned long nr;
670 706
671 smp_mb(); 707 if (xchg(&root->defrag_running, 1))
672 if (root->defrag_running)
673 return 0; 708 return 0;
674 trans = btrfs_start_transaction(root, 1); 709
675 while (1) { 710 while (1) {
676 root->defrag_running = 1; 711 trans = btrfs_start_transaction(root, 0);
712 if (IS_ERR(trans))
713 return PTR_ERR(trans);
714
677 ret = btrfs_defrag_leaves(trans, root, cacheonly); 715 ret = btrfs_defrag_leaves(trans, root, cacheonly);
716
678 nr = trans->blocks_used; 717 nr = trans->blocks_used;
679 btrfs_end_transaction(trans, root); 718 btrfs_end_transaction(trans, root);
680 btrfs_btree_balance_dirty(info->tree_root, nr); 719 btrfs_btree_balance_dirty(info->tree_root, nr);
681 cond_resched(); 720 cond_resched();
682 721
683 trans = btrfs_start_transaction(root, 1);
684 if (root->fs_info->closing || ret != -EAGAIN) 722 if (root->fs_info->closing || ret != -EAGAIN)
685 break; 723 break;
686 } 724 }
687 root->defrag_running = 0; 725 root->defrag_running = 0;
688 smp_mb(); 726 return ret;
689 btrfs_end_transaction(trans, root);
690 return 0;
691} 727}
692 728
693#if 0 729#if 0
@@ -924,6 +960,16 @@ int btrfs_transaction_in_commit(struct btrfs_fs_info *info)
924 return ret; 960 return ret;
925} 961}
926 962
963int btrfs_transaction_blocked(struct btrfs_fs_info *info)
964{
965 int ret = 0;
966 spin_lock(&info->new_trans_lock);
967 if (info->running_transaction)
968 ret = info->running_transaction->blocked;
969 spin_unlock(&info->new_trans_lock);
970 return ret;
971}
972
927int btrfs_commit_transaction(struct btrfs_trans_handle *trans, 973int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
928 struct btrfs_root *root) 974 struct btrfs_root *root)
929{ 975{