diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 196 |
1 files changed, 54 insertions, 142 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c571734d5e5a..dc80f7156923 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "transaction.h" | 27 | #include "transaction.h" |
28 | #include "locking.h" | 28 | #include "locking.h" |
29 | #include "tree-log.h" | 29 | #include "tree-log.h" |
30 | #include "inode-map.h" | ||
30 | 31 | ||
31 | #define BTRFS_ROOT_TRANS_TAG 0 | 32 | #define BTRFS_ROOT_TRANS_TAG 0 |
32 | 33 | ||
@@ -80,8 +81,7 @@ static noinline int join_transaction(struct btrfs_root *root) | |||
80 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | 81 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); |
81 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | 82 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); |
82 | extent_io_tree_init(&cur_trans->dirty_pages, | 83 | extent_io_tree_init(&cur_trans->dirty_pages, |
83 | root->fs_info->btree_inode->i_mapping, | 84 | root->fs_info->btree_inode->i_mapping); |
84 | GFP_NOFS); | ||
85 | spin_lock(&root->fs_info->new_trans_lock); | 85 | spin_lock(&root->fs_info->new_trans_lock); |
86 | root->fs_info->running_transaction = cur_trans; | 86 | root->fs_info->running_transaction = cur_trans; |
87 | spin_unlock(&root->fs_info->new_trans_lock); | 87 | spin_unlock(&root->fs_info->new_trans_lock); |
@@ -347,49 +347,6 @@ out_unlock: | |||
347 | return ret; | 347 | return ret; |
348 | } | 348 | } |
349 | 349 | ||
350 | #if 0 | ||
351 | /* | ||
352 | * rate limit against the drop_snapshot code. This helps to slow down new | ||
353 | * operations if the drop_snapshot code isn't able to keep up. | ||
354 | */ | ||
355 | static void throttle_on_drops(struct btrfs_root *root) | ||
356 | { | ||
357 | struct btrfs_fs_info *info = root->fs_info; | ||
358 | int harder_count = 0; | ||
359 | |||
360 | harder: | ||
361 | if (atomic_read(&info->throttles)) { | ||
362 | DEFINE_WAIT(wait); | ||
363 | int thr; | ||
364 | thr = atomic_read(&info->throttle_gen); | ||
365 | |||
366 | do { | ||
367 | prepare_to_wait(&info->transaction_throttle, | ||
368 | &wait, TASK_UNINTERRUPTIBLE); | ||
369 | if (!atomic_read(&info->throttles)) { | ||
370 | finish_wait(&info->transaction_throttle, &wait); | ||
371 | break; | ||
372 | } | ||
373 | schedule(); | ||
374 | finish_wait(&info->transaction_throttle, &wait); | ||
375 | } while (thr == atomic_read(&info->throttle_gen)); | ||
376 | harder_count++; | ||
377 | |||
378 | if (root->fs_info->total_ref_cache_size > 1 * 1024 * 1024 && | ||
379 | harder_count < 2) | ||
380 | goto harder; | ||
381 | |||
382 | if (root->fs_info->total_ref_cache_size > 5 * 1024 * 1024 && | ||
383 | harder_count < 10) | ||
384 | goto harder; | ||
385 | |||
386 | if (root->fs_info->total_ref_cache_size > 10 * 1024 * 1024 && | ||
387 | harder_count < 20) | ||
388 | goto harder; | ||
389 | } | ||
390 | } | ||
391 | #endif | ||
392 | |||
393 | void btrfs_throttle(struct btrfs_root *root) | 350 | void btrfs_throttle(struct btrfs_root *root) |
394 | { | 351 | { |
395 | mutex_lock(&root->fs_info->trans_mutex); | 352 | mutex_lock(&root->fs_info->trans_mutex); |
@@ -487,19 +444,40 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
487 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, | 444 | int btrfs_end_transaction(struct btrfs_trans_handle *trans, |
488 | struct btrfs_root *root) | 445 | struct btrfs_root *root) |
489 | { | 446 | { |
490 | return __btrfs_end_transaction(trans, root, 0, 1); | 447 | int ret; |
448 | |||
449 | ret = __btrfs_end_transaction(trans, root, 0, 1); | ||
450 | if (ret) | ||
451 | return ret; | ||
452 | return 0; | ||
491 | } | 453 | } |
492 | 454 | ||
493 | int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, | 455 | int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, |
494 | struct btrfs_root *root) | 456 | struct btrfs_root *root) |
495 | { | 457 | { |
496 | return __btrfs_end_transaction(trans, root, 1, 1); | 458 | int ret; |
459 | |||
460 | ret = __btrfs_end_transaction(trans, root, 1, 1); | ||
461 | if (ret) | ||
462 | return ret; | ||
463 | return 0; | ||
497 | } | 464 | } |
498 | 465 | ||
499 | int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans, | 466 | int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans, |
500 | struct btrfs_root *root) | 467 | struct btrfs_root *root) |
501 | { | 468 | { |
502 | return __btrfs_end_transaction(trans, root, 0, 0); | 469 | int ret; |
470 | |||
471 | ret = __btrfs_end_transaction(trans, root, 0, 0); | ||
472 | if (ret) | ||
473 | return ret; | ||
474 | return 0; | ||
475 | } | ||
476 | |||
477 | int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans, | ||
478 | struct btrfs_root *root) | ||
479 | { | ||
480 | return __btrfs_end_transaction(trans, root, 1, 1); | ||
503 | } | 481 | } |
504 | 482 | ||
505 | /* | 483 | /* |
@@ -760,8 +738,14 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
760 | btrfs_update_reloc_root(trans, root); | 738 | btrfs_update_reloc_root(trans, root); |
761 | btrfs_orphan_commit_root(trans, root); | 739 | btrfs_orphan_commit_root(trans, root); |
762 | 740 | ||
741 | btrfs_save_ino_cache(root, trans); | ||
742 | |||
763 | if (root->commit_root != root->node) { | 743 | if (root->commit_root != root->node) { |
744 | mutex_lock(&root->fs_commit_mutex); | ||
764 | switch_commit_root(root); | 745 | switch_commit_root(root); |
746 | btrfs_unpin_free_ino(root); | ||
747 | mutex_unlock(&root->fs_commit_mutex); | ||
748 | |||
765 | btrfs_set_root_node(&root->root_item, | 749 | btrfs_set_root_node(&root->root_item, |
766 | root->node); | 750 | root->node); |
767 | } | 751 | } |
@@ -809,97 +793,6 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
809 | return ret; | 793 | return ret; |
810 | } | 794 | } |
811 | 795 | ||
812 | #if 0 | ||
813 | /* | ||
814 | * when dropping snapshots, we generate a ton of delayed refs, and it makes | ||
815 | * sense not to join the transaction while it is trying to flush the current | ||
816 | * queue of delayed refs out. | ||
817 | * | ||
818 | * This is used by the drop snapshot code only | ||
819 | */ | ||
820 | static noinline int wait_transaction_pre_flush(struct btrfs_fs_info *info) | ||
821 | { | ||
822 | DEFINE_WAIT(wait); | ||
823 | |||
824 | mutex_lock(&info->trans_mutex); | ||
825 | while (info->running_transaction && | ||
826 | info->running_transaction->delayed_refs.flushing) { | ||
827 | prepare_to_wait(&info->transaction_wait, &wait, | ||
828 | TASK_UNINTERRUPTIBLE); | ||
829 | mutex_unlock(&info->trans_mutex); | ||
830 | |||
831 | schedule(); | ||
832 | |||
833 | mutex_lock(&info->trans_mutex); | ||
834 | finish_wait(&info->transaction_wait, &wait); | ||
835 | } | ||
836 | mutex_unlock(&info->trans_mutex); | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | /* | ||
841 | * Given a list of roots that need to be deleted, call btrfs_drop_snapshot on | ||
842 | * all of them | ||
843 | */ | ||
844 | int btrfs_drop_dead_root(struct btrfs_root *root) | ||
845 | { | ||
846 | struct btrfs_trans_handle *trans; | ||
847 | struct btrfs_root *tree_root = root->fs_info->tree_root; | ||
848 | unsigned long nr; | ||
849 | int ret; | ||
850 | |||
851 | while (1) { | ||
852 | /* | ||
853 | * we don't want to jump in and create a bunch of | ||
854 | * delayed refs if the transaction is starting to close | ||
855 | */ | ||
856 | wait_transaction_pre_flush(tree_root->fs_info); | ||
857 | trans = btrfs_start_transaction(tree_root, 1); | ||
858 | |||
859 | /* | ||
860 | * we've joined a transaction, make sure it isn't | ||
861 | * closing right now | ||
862 | */ | ||
863 | if (trans->transaction->delayed_refs.flushing) { | ||
864 | btrfs_end_transaction(trans, tree_root); | ||
865 | continue; | ||
866 | } | ||
867 | |||
868 | ret = btrfs_drop_snapshot(trans, root); | ||
869 | if (ret != -EAGAIN) | ||
870 | break; | ||
871 | |||
872 | ret = btrfs_update_root(trans, tree_root, | ||
873 | &root->root_key, | ||
874 | &root->root_item); | ||
875 | if (ret) | ||
876 | break; | ||
877 | |||
878 | nr = trans->blocks_used; | ||
879 | ret = btrfs_end_transaction(trans, tree_root); | ||
880 | BUG_ON(ret); | ||
881 | |||
882 | btrfs_btree_balance_dirty(tree_root, nr); | ||
883 | cond_resched(); | ||
884 | } | ||
885 | BUG_ON(ret); | ||
886 | |||
887 | ret = btrfs_del_root(trans, tree_root, &root->root_key); | ||
888 | BUG_ON(ret); | ||
889 | |||
890 | nr = trans->blocks_used; | ||
891 | ret = btrfs_end_transaction(trans, tree_root); | ||
892 | BUG_ON(ret); | ||
893 | |||
894 | free_extent_buffer(root->node); | ||
895 | free_extent_buffer(root->commit_root); | ||
896 | kfree(root); | ||
897 | |||
898 | btrfs_btree_balance_dirty(tree_root, nr); | ||
899 | return ret; | ||
900 | } | ||
901 | #endif | ||
902 | |||
903 | /* | 796 | /* |
904 | * new snapshots need to be created at a very specific time in the | 797 | * new snapshots need to be created at a very specific time in the |
905 | * transaction commit. This does the actual creation | 798 | * transaction commit. This does the actual creation |
@@ -930,7 +823,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
930 | goto fail; | 823 | goto fail; |
931 | } | 824 | } |
932 | 825 | ||
933 | ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid); | 826 | ret = btrfs_find_free_objectid(tree_root, &objectid); |
934 | if (ret) { | 827 | if (ret) { |
935 | pending->error = ret; | 828 | pending->error = ret; |
936 | goto fail; | 829 | goto fail; |
@@ -967,7 +860,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
967 | BUG_ON(ret); | 860 | BUG_ON(ret); |
968 | ret = btrfs_insert_dir_item(trans, parent_root, | 861 | ret = btrfs_insert_dir_item(trans, parent_root, |
969 | dentry->d_name.name, dentry->d_name.len, | 862 | dentry->d_name.name, dentry->d_name.len, |
970 | parent_inode->i_ino, &key, | 863 | parent_inode, &key, |
971 | BTRFS_FT_DIR, index); | 864 | BTRFS_FT_DIR, index); |
972 | BUG_ON(ret); | 865 | BUG_ON(ret); |
973 | 866 | ||
@@ -1009,7 +902,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1009 | */ | 902 | */ |
1010 | ret = btrfs_add_root_ref(trans, tree_root, objectid, | 903 | ret = btrfs_add_root_ref(trans, tree_root, objectid, |
1011 | parent_root->root_key.objectid, | 904 | parent_root->root_key.objectid, |
1012 | parent_inode->i_ino, index, | 905 | btrfs_ino(parent_inode), index, |
1013 | dentry->d_name.name, dentry->d_name.len); | 906 | dentry->d_name.name, dentry->d_name.len); |
1014 | BUG_ON(ret); | 907 | BUG_ON(ret); |
1015 | dput(parent); | 908 | dput(parent); |
@@ -1037,6 +930,14 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, | |||
1037 | int ret; | 930 | int ret; |
1038 | 931 | ||
1039 | list_for_each_entry(pending, head, list) { | 932 | list_for_each_entry(pending, head, list) { |
933 | /* | ||
934 | * We must deal with the delayed items before creating | ||
935 | * snapshots, or we will create a snapthot with inconsistent | ||
936 | * information. | ||
937 | */ | ||
938 | ret = btrfs_run_delayed_items(trans, fs_info->fs_root); | ||
939 | BUG_ON(ret); | ||
940 | |||
1040 | ret = create_pending_snapshot(trans, fs_info, pending); | 941 | ret = create_pending_snapshot(trans, fs_info, pending); |
1041 | BUG_ON(ret); | 942 | BUG_ON(ret); |
1042 | } | 943 | } |
@@ -1290,6 +1191,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1290 | BUG_ON(ret); | 1191 | BUG_ON(ret); |
1291 | } | 1192 | } |
1292 | 1193 | ||
1194 | ret = btrfs_run_delayed_items(trans, root); | ||
1195 | BUG_ON(ret); | ||
1196 | |||
1293 | /* | 1197 | /* |
1294 | * rename don't use btrfs_join_transaction, so, once we | 1198 | * rename don't use btrfs_join_transaction, so, once we |
1295 | * set the transaction to blocked above, we aren't going | 1199 | * set the transaction to blocked above, we aren't going |
@@ -1316,11 +1220,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1316 | ret = create_pending_snapshots(trans, root->fs_info); | 1220 | ret = create_pending_snapshots(trans, root->fs_info); |
1317 | BUG_ON(ret); | 1221 | BUG_ON(ret); |
1318 | 1222 | ||
1223 | ret = btrfs_run_delayed_items(trans, root); | ||
1224 | BUG_ON(ret); | ||
1225 | |||
1319 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 1226 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
1320 | BUG_ON(ret); | 1227 | BUG_ON(ret); |
1321 | 1228 | ||
1322 | WARN_ON(cur_trans != trans->transaction); | 1229 | WARN_ON(cur_trans != trans->transaction); |
1323 | 1230 | ||
1231 | btrfs_scrub_pause(root); | ||
1324 | /* btrfs_commit_tree_roots is responsible for getting the | 1232 | /* btrfs_commit_tree_roots is responsible for getting the |
1325 | * various roots consistent with each other. Every pointer | 1233 | * various roots consistent with each other. Every pointer |
1326 | * in the tree of tree roots has to point to the most up to date | 1234 | * in the tree of tree roots has to point to the most up to date |
@@ -1405,6 +1313,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1405 | 1313 | ||
1406 | mutex_unlock(&root->fs_info->trans_mutex); | 1314 | mutex_unlock(&root->fs_info->trans_mutex); |
1407 | 1315 | ||
1316 | btrfs_scrub_continue(root); | ||
1317 | |||
1408 | if (current->journal_info == trans) | 1318 | if (current->journal_info == trans) |
1409 | current->journal_info = NULL; | 1319 | current->journal_info = NULL; |
1410 | 1320 | ||
@@ -1432,6 +1342,8 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1432 | root = list_entry(list.next, struct btrfs_root, root_list); | 1342 | root = list_entry(list.next, struct btrfs_root, root_list); |
1433 | list_del(&root->root_list); | 1343 | list_del(&root->root_list); |
1434 | 1344 | ||
1345 | btrfs_kill_all_delayed_nodes(root); | ||
1346 | |||
1435 | if (btrfs_header_backref_rev(root->node) < | 1347 | if (btrfs_header_backref_rev(root->node) < |
1436 | BTRFS_MIXED_BACKREF_REV) | 1348 | BTRFS_MIXED_BACKREF_REV) |
1437 | btrfs_drop_snapshot(root, NULL, 0); | 1349 | btrfs_drop_snapshot(root, NULL, 0); |