diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 213 |
1 files changed, 172 insertions, 41 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 04b77e3ceb7a..8da29e8e4de1 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -31,7 +31,7 @@ | |||
31 | 31 | ||
32 | #define BTRFS_ROOT_TRANS_TAG 0 | 32 | #define BTRFS_ROOT_TRANS_TAG 0 |
33 | 33 | ||
34 | static noinline void put_transaction(struct btrfs_transaction *transaction) | 34 | void put_transaction(struct btrfs_transaction *transaction) |
35 | { | 35 | { |
36 | WARN_ON(atomic_read(&transaction->use_count) == 0); | 36 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
37 | if (atomic_dec_and_test(&transaction->use_count)) { | 37 | if (atomic_dec_and_test(&transaction->use_count)) { |
@@ -58,6 +58,12 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail) | |||
58 | 58 | ||
59 | spin_lock(&root->fs_info->trans_lock); | 59 | spin_lock(&root->fs_info->trans_lock); |
60 | loop: | 60 | loop: |
61 | /* The file system has been taken offline. No new transactions. */ | ||
62 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | ||
63 | spin_unlock(&root->fs_info->trans_lock); | ||
64 | return -EROFS; | ||
65 | } | ||
66 | |||
61 | if (root->fs_info->trans_no_join) { | 67 | if (root->fs_info->trans_no_join) { |
62 | if (!nofail) { | 68 | if (!nofail) { |
63 | spin_unlock(&root->fs_info->trans_lock); | 69 | spin_unlock(&root->fs_info->trans_lock); |
@@ -67,6 +73,8 @@ loop: | |||
67 | 73 | ||
68 | cur_trans = root->fs_info->running_transaction; | 74 | cur_trans = root->fs_info->running_transaction; |
69 | if (cur_trans) { | 75 | if (cur_trans) { |
76 | if (cur_trans->aborted) | ||
77 | return cur_trans->aborted; | ||
70 | atomic_inc(&cur_trans->use_count); | 78 | atomic_inc(&cur_trans->use_count); |
71 | atomic_inc(&cur_trans->num_writers); | 79 | atomic_inc(&cur_trans->num_writers); |
72 | cur_trans->num_joined++; | 80 | cur_trans->num_joined++; |
@@ -123,6 +131,7 @@ loop: | |||
123 | root->fs_info->generation++; | 131 | root->fs_info->generation++; |
124 | cur_trans->transid = root->fs_info->generation; | 132 | cur_trans->transid = root->fs_info->generation; |
125 | root->fs_info->running_transaction = cur_trans; | 133 | root->fs_info->running_transaction = cur_trans; |
134 | cur_trans->aborted = 0; | ||
126 | spin_unlock(&root->fs_info->trans_lock); | 135 | spin_unlock(&root->fs_info->trans_lock); |
127 | 136 | ||
128 | return 0; | 137 | return 0; |
@@ -318,6 +327,7 @@ again: | |||
318 | h->use_count = 1; | 327 | h->use_count = 1; |
319 | h->block_rsv = NULL; | 328 | h->block_rsv = NULL; |
320 | h->orig_rsv = NULL; | 329 | h->orig_rsv = NULL; |
330 | h->aborted = 0; | ||
321 | 331 | ||
322 | smp_mb(); | 332 | smp_mb(); |
323 | if (cur_trans->blocked && may_wait_transaction(root, type)) { | 333 | if (cur_trans->blocked && may_wait_transaction(root, type)) { |
@@ -327,8 +337,7 @@ again: | |||
327 | 337 | ||
328 | if (num_bytes) { | 338 | if (num_bytes) { |
329 | trace_btrfs_space_reservation(root->fs_info, "transaction", | 339 | trace_btrfs_space_reservation(root->fs_info, "transaction", |
330 | (u64)(unsigned long)h, | 340 | h->transid, num_bytes, 1); |
331 | num_bytes, 1); | ||
332 | h->block_rsv = &root->fs_info->trans_block_rsv; | 341 | h->block_rsv = &root->fs_info->trans_block_rsv; |
333 | h->bytes_reserved = num_bytes; | 342 | h->bytes_reserved = num_bytes; |
334 | } | 343 | } |
@@ -440,6 +449,7 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, | |||
440 | struct btrfs_transaction *cur_trans = trans->transaction; | 449 | struct btrfs_transaction *cur_trans = trans->transaction; |
441 | struct btrfs_block_rsv *rsv = trans->block_rsv; | 450 | struct btrfs_block_rsv *rsv = trans->block_rsv; |
442 | int updates; | 451 | int updates; |
452 | int err; | ||
443 | 453 | ||
444 | smp_mb(); | 454 | smp_mb(); |
445 | if (cur_trans->blocked || cur_trans->delayed_refs.flushing) | 455 | if (cur_trans->blocked || cur_trans->delayed_refs.flushing) |
@@ -453,8 +463,11 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, | |||
453 | 463 | ||
454 | updates = trans->delayed_ref_updates; | 464 | updates = trans->delayed_ref_updates; |
455 | trans->delayed_ref_updates = 0; | 465 | trans->delayed_ref_updates = 0; |
456 | if (updates) | 466 | if (updates) { |
457 | btrfs_run_delayed_refs(trans, root, updates); | 467 | err = btrfs_run_delayed_refs(trans, root, updates); |
468 | if (err) /* Error code will also eval true */ | ||
469 | return err; | ||
470 | } | ||
458 | 471 | ||
459 | trans->block_rsv = rsv; | 472 | trans->block_rsv = rsv; |
460 | 473 | ||
@@ -525,6 +538,11 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
525 | if (throttle) | 538 | if (throttle) |
526 | btrfs_run_delayed_iputs(root); | 539 | btrfs_run_delayed_iputs(root); |
527 | 540 | ||
541 | if (trans->aborted || | ||
542 | root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | ||
543 | return -EIO; | ||
544 | } | ||
545 | |||
528 | return 0; | 546 | return 0; |
529 | } | 547 | } |
530 | 548 | ||
@@ -690,11 +708,13 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
690 | ret = btrfs_update_root(trans, tree_root, | 708 | ret = btrfs_update_root(trans, tree_root, |
691 | &root->root_key, | 709 | &root->root_key, |
692 | &root->root_item); | 710 | &root->root_item); |
693 | BUG_ON(ret); | 711 | if (ret) |
712 | return ret; | ||
694 | 713 | ||
695 | old_root_used = btrfs_root_used(&root->root_item); | 714 | old_root_used = btrfs_root_used(&root->root_item); |
696 | ret = btrfs_write_dirty_block_groups(trans, root); | 715 | ret = btrfs_write_dirty_block_groups(trans, root); |
697 | BUG_ON(ret); | 716 | if (ret) |
717 | return ret; | ||
698 | } | 718 | } |
699 | 719 | ||
700 | if (root != root->fs_info->extent_root) | 720 | if (root != root->fs_info->extent_root) |
@@ -705,6 +725,10 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
705 | 725 | ||
706 | /* | 726 | /* |
707 | * update all the cowonly tree roots on disk | 727 | * update all the cowonly tree roots on disk |
728 | * | ||
729 | * The error handling in this function may not be obvious. Any of the | ||
730 | * failures will cause the file system to go offline. We still need | ||
731 | * to clean up the delayed refs. | ||
708 | */ | 732 | */ |
709 | static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | 733 | static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, |
710 | struct btrfs_root *root) | 734 | struct btrfs_root *root) |
@@ -715,22 +739,30 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
715 | int ret; | 739 | int ret; |
716 | 740 | ||
717 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 741 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
718 | BUG_ON(ret); | 742 | if (ret) |
743 | return ret; | ||
719 | 744 | ||
720 | eb = btrfs_lock_root_node(fs_info->tree_root); | 745 | eb = btrfs_lock_root_node(fs_info->tree_root); |
721 | btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb); | 746 | ret = btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, |
747 | 0, &eb); | ||
722 | btrfs_tree_unlock(eb); | 748 | btrfs_tree_unlock(eb); |
723 | free_extent_buffer(eb); | 749 | free_extent_buffer(eb); |
724 | 750 | ||
751 | if (ret) | ||
752 | return ret; | ||
753 | |||
725 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 754 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
726 | BUG_ON(ret); | 755 | if (ret) |
756 | return ret; | ||
727 | 757 | ||
728 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { | 758 | while (!list_empty(&fs_info->dirty_cowonly_roots)) { |
729 | next = fs_info->dirty_cowonly_roots.next; | 759 | next = fs_info->dirty_cowonly_roots.next; |
730 | list_del_init(next); | 760 | list_del_init(next); |
731 | root = list_entry(next, struct btrfs_root, dirty_list); | 761 | root = list_entry(next, struct btrfs_root, dirty_list); |
732 | 762 | ||
733 | update_cowonly_root(trans, root); | 763 | ret = update_cowonly_root(trans, root); |
764 | if (ret) | ||
765 | return ret; | ||
734 | } | 766 | } |
735 | 767 | ||
736 | down_write(&fs_info->extent_commit_sem); | 768 | down_write(&fs_info->extent_commit_sem); |
@@ -874,7 +906,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
874 | 906 | ||
875 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); | 907 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); |
876 | if (!new_root_item) { | 908 | if (!new_root_item) { |
877 | pending->error = -ENOMEM; | 909 | ret = pending->error = -ENOMEM; |
878 | goto fail; | 910 | goto fail; |
879 | } | 911 | } |
880 | 912 | ||
@@ -911,21 +943,24 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
911 | * insert the directory item | 943 | * insert the directory item |
912 | */ | 944 | */ |
913 | ret = btrfs_set_inode_index(parent_inode, &index); | 945 | ret = btrfs_set_inode_index(parent_inode, &index); |
914 | BUG_ON(ret); | 946 | BUG_ON(ret); /* -ENOMEM */ |
915 | ret = btrfs_insert_dir_item(trans, parent_root, | 947 | ret = btrfs_insert_dir_item(trans, parent_root, |
916 | dentry->d_name.name, dentry->d_name.len, | 948 | dentry->d_name.name, dentry->d_name.len, |
917 | parent_inode, &key, | 949 | parent_inode, &key, |
918 | BTRFS_FT_DIR, index); | 950 | BTRFS_FT_DIR, index); |
919 | if (ret) { | 951 | if (ret == -EEXIST) { |
920 | pending->error = -EEXIST; | 952 | pending->error = -EEXIST; |
921 | dput(parent); | 953 | dput(parent); |
922 | goto fail; | 954 | goto fail; |
955 | } else if (ret) { | ||
956 | goto abort_trans_dput; | ||
923 | } | 957 | } |
924 | 958 | ||
925 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 959 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
926 | dentry->d_name.len * 2); | 960 | dentry->d_name.len * 2); |
927 | ret = btrfs_update_inode(trans, parent_root, parent_inode); | 961 | ret = btrfs_update_inode(trans, parent_root, parent_inode); |
928 | BUG_ON(ret); | 962 | if (ret) |
963 | goto abort_trans_dput; | ||
929 | 964 | ||
930 | /* | 965 | /* |
931 | * pull in the delayed directory update | 966 | * pull in the delayed directory update |
@@ -934,7 +969,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
934 | * snapshot | 969 | * snapshot |
935 | */ | 970 | */ |
936 | ret = btrfs_run_delayed_items(trans, root); | 971 | ret = btrfs_run_delayed_items(trans, root); |
937 | BUG_ON(ret); | 972 | if (ret) { /* Transaction aborted */ |
973 | dput(parent); | ||
974 | goto fail; | ||
975 | } | ||
938 | 976 | ||
939 | record_root_in_trans(trans, root); | 977 | record_root_in_trans(trans, root); |
940 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); | 978 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); |
@@ -949,12 +987,21 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
949 | btrfs_set_root_flags(new_root_item, root_flags); | 987 | btrfs_set_root_flags(new_root_item, root_flags); |
950 | 988 | ||
951 | old = btrfs_lock_root_node(root); | 989 | old = btrfs_lock_root_node(root); |
952 | btrfs_cow_block(trans, root, old, NULL, 0, &old); | 990 | ret = btrfs_cow_block(trans, root, old, NULL, 0, &old); |
991 | if (ret) { | ||
992 | btrfs_tree_unlock(old); | ||
993 | free_extent_buffer(old); | ||
994 | goto abort_trans_dput; | ||
995 | } | ||
996 | |||
953 | btrfs_set_lock_blocking(old); | 997 | btrfs_set_lock_blocking(old); |
954 | 998 | ||
955 | btrfs_copy_root(trans, root, old, &tmp, objectid); | 999 | ret = btrfs_copy_root(trans, root, old, &tmp, objectid); |
1000 | /* clean up in any case */ | ||
956 | btrfs_tree_unlock(old); | 1001 | btrfs_tree_unlock(old); |
957 | free_extent_buffer(old); | 1002 | free_extent_buffer(old); |
1003 | if (ret) | ||
1004 | goto abort_trans_dput; | ||
958 | 1005 | ||
959 | /* see comments in should_cow_block() */ | 1006 | /* see comments in should_cow_block() */ |
960 | root->force_cow = 1; | 1007 | root->force_cow = 1; |
@@ -966,7 +1013,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
966 | ret = btrfs_insert_root(trans, tree_root, &key, new_root_item); | 1013 | ret = btrfs_insert_root(trans, tree_root, &key, new_root_item); |
967 | btrfs_tree_unlock(tmp); | 1014 | btrfs_tree_unlock(tmp); |
968 | free_extent_buffer(tmp); | 1015 | free_extent_buffer(tmp); |
969 | BUG_ON(ret); | 1016 | if (ret) |
1017 | goto abort_trans_dput; | ||
970 | 1018 | ||
971 | /* | 1019 | /* |
972 | * insert root back/forward references | 1020 | * insert root back/forward references |
@@ -975,19 +1023,32 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
975 | parent_root->root_key.objectid, | 1023 | parent_root->root_key.objectid, |
976 | btrfs_ino(parent_inode), index, | 1024 | btrfs_ino(parent_inode), index, |
977 | dentry->d_name.name, dentry->d_name.len); | 1025 | dentry->d_name.name, dentry->d_name.len); |
978 | BUG_ON(ret); | ||
979 | dput(parent); | 1026 | dput(parent); |
1027 | if (ret) | ||
1028 | goto fail; | ||
980 | 1029 | ||
981 | key.offset = (u64)-1; | 1030 | key.offset = (u64)-1; |
982 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); | 1031 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); |
983 | BUG_ON(IS_ERR(pending->snap)); | 1032 | if (IS_ERR(pending->snap)) { |
1033 | ret = PTR_ERR(pending->snap); | ||
1034 | goto abort_trans; | ||
1035 | } | ||
984 | 1036 | ||
985 | btrfs_reloc_post_snapshot(trans, pending); | 1037 | ret = btrfs_reloc_post_snapshot(trans, pending); |
1038 | if (ret) | ||
1039 | goto abort_trans; | ||
1040 | ret = 0; | ||
986 | fail: | 1041 | fail: |
987 | kfree(new_root_item); | 1042 | kfree(new_root_item); |
988 | trans->block_rsv = rsv; | 1043 | trans->block_rsv = rsv; |
989 | btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); | 1044 | btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); |
990 | return 0; | 1045 | return ret; |
1046 | |||
1047 | abort_trans_dput: | ||
1048 | dput(parent); | ||
1049 | abort_trans: | ||
1050 | btrfs_abort_transaction(trans, root, ret); | ||
1051 | goto fail; | ||
991 | } | 1052 | } |
992 | 1053 | ||
993 | /* | 1054 | /* |
@@ -1124,6 +1185,33 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
1124 | return 0; | 1185 | return 0; |
1125 | } | 1186 | } |
1126 | 1187 | ||
1188 | |||
1189 | static void cleanup_transaction(struct btrfs_trans_handle *trans, | ||
1190 | struct btrfs_root *root) | ||
1191 | { | ||
1192 | struct btrfs_transaction *cur_trans = trans->transaction; | ||
1193 | |||
1194 | WARN_ON(trans->use_count > 1); | ||
1195 | |||
1196 | spin_lock(&root->fs_info->trans_lock); | ||
1197 | list_del_init(&cur_trans->list); | ||
1198 | spin_unlock(&root->fs_info->trans_lock); | ||
1199 | |||
1200 | btrfs_cleanup_one_transaction(trans->transaction, root); | ||
1201 | |||
1202 | put_transaction(cur_trans); | ||
1203 | put_transaction(cur_trans); | ||
1204 | |||
1205 | trace_btrfs_transaction_commit(root); | ||
1206 | |||
1207 | btrfs_scrub_continue(root); | ||
1208 | |||
1209 | if (current->journal_info == trans) | ||
1210 | current->journal_info = NULL; | ||
1211 | |||
1212 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | ||
1213 | } | ||
1214 | |||
1127 | /* | 1215 | /* |
1128 | * btrfs_transaction state sequence: | 1216 | * btrfs_transaction state sequence: |
1129 | * in_commit = 0, blocked = 0 (initial) | 1217 | * in_commit = 0, blocked = 0 (initial) |
@@ -1135,10 +1223,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1135 | struct btrfs_root *root) | 1223 | struct btrfs_root *root) |
1136 | { | 1224 | { |
1137 | unsigned long joined = 0; | 1225 | unsigned long joined = 0; |
1138 | struct btrfs_transaction *cur_trans; | 1226 | struct btrfs_transaction *cur_trans = trans->transaction; |
1139 | struct btrfs_transaction *prev_trans = NULL; | 1227 | struct btrfs_transaction *prev_trans = NULL; |
1140 | DEFINE_WAIT(wait); | 1228 | DEFINE_WAIT(wait); |
1141 | int ret; | 1229 | int ret = -EIO; |
1142 | int should_grow = 0; | 1230 | int should_grow = 0; |
1143 | unsigned long now = get_seconds(); | 1231 | unsigned long now = get_seconds(); |
1144 | int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); | 1232 | int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); |
@@ -1148,13 +1236,18 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1148 | btrfs_trans_release_metadata(trans, root); | 1236 | btrfs_trans_release_metadata(trans, root); |
1149 | trans->block_rsv = NULL; | 1237 | trans->block_rsv = NULL; |
1150 | 1238 | ||
1239 | if (cur_trans->aborted) | ||
1240 | goto cleanup_transaction; | ||
1241 | |||
1151 | /* make a pass through all the delayed refs we have so far | 1242 | /* make a pass through all the delayed refs we have so far |
1152 | * any runnings procs may add more while we are here | 1243 | * any runnings procs may add more while we are here |
1153 | */ | 1244 | */ |
1154 | ret = btrfs_run_delayed_refs(trans, root, 0); | 1245 | ret = btrfs_run_delayed_refs(trans, root, 0); |
1155 | BUG_ON(ret); | 1246 | if (ret) |
1247 | goto cleanup_transaction; | ||
1156 | 1248 | ||
1157 | cur_trans = trans->transaction; | 1249 | cur_trans = trans->transaction; |
1250 | |||
1158 | /* | 1251 | /* |
1159 | * set the flushing flag so procs in this transaction have to | 1252 | * set the flushing flag so procs in this transaction have to |
1160 | * start sending their work down. | 1253 | * start sending their work down. |
@@ -1162,19 +1255,20 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1162 | cur_trans->delayed_refs.flushing = 1; | 1255 | cur_trans->delayed_refs.flushing = 1; |
1163 | 1256 | ||
1164 | ret = btrfs_run_delayed_refs(trans, root, 0); | 1257 | ret = btrfs_run_delayed_refs(trans, root, 0); |
1165 | BUG_ON(ret); | 1258 | if (ret) |
1259 | goto cleanup_transaction; | ||
1166 | 1260 | ||
1167 | spin_lock(&cur_trans->commit_lock); | 1261 | spin_lock(&cur_trans->commit_lock); |
1168 | if (cur_trans->in_commit) { | 1262 | if (cur_trans->in_commit) { |
1169 | spin_unlock(&cur_trans->commit_lock); | 1263 | spin_unlock(&cur_trans->commit_lock); |
1170 | atomic_inc(&cur_trans->use_count); | 1264 | atomic_inc(&cur_trans->use_count); |
1171 | btrfs_end_transaction(trans, root); | 1265 | ret = btrfs_end_transaction(trans, root); |
1172 | 1266 | ||
1173 | wait_for_commit(root, cur_trans); | 1267 | wait_for_commit(root, cur_trans); |
1174 | 1268 | ||
1175 | put_transaction(cur_trans); | 1269 | put_transaction(cur_trans); |
1176 | 1270 | ||
1177 | return 0; | 1271 | return ret; |
1178 | } | 1272 | } |
1179 | 1273 | ||
1180 | trans->transaction->in_commit = 1; | 1274 | trans->transaction->in_commit = 1; |
@@ -1214,12 +1308,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1214 | 1308 | ||
1215 | if (flush_on_commit || snap_pending) { | 1309 | if (flush_on_commit || snap_pending) { |
1216 | btrfs_start_delalloc_inodes(root, 1); | 1310 | btrfs_start_delalloc_inodes(root, 1); |
1217 | ret = btrfs_wait_ordered_extents(root, 0, 1); | 1311 | btrfs_wait_ordered_extents(root, 0, 1); |
1218 | BUG_ON(ret); | ||
1219 | } | 1312 | } |
1220 | 1313 | ||
1221 | ret = btrfs_run_delayed_items(trans, root); | 1314 | ret = btrfs_run_delayed_items(trans, root); |
1222 | BUG_ON(ret); | 1315 | if (ret) |
1316 | goto cleanup_transaction; | ||
1223 | 1317 | ||
1224 | /* | 1318 | /* |
1225 | * rename don't use btrfs_join_transaction, so, once we | 1319 | * rename don't use btrfs_join_transaction, so, once we |
@@ -1261,13 +1355,22 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1261 | mutex_lock(&root->fs_info->reloc_mutex); | 1355 | mutex_lock(&root->fs_info->reloc_mutex); |
1262 | 1356 | ||
1263 | ret = btrfs_run_delayed_items(trans, root); | 1357 | ret = btrfs_run_delayed_items(trans, root); |
1264 | BUG_ON(ret); | 1358 | if (ret) { |
1359 | mutex_unlock(&root->fs_info->reloc_mutex); | ||
1360 | goto cleanup_transaction; | ||
1361 | } | ||
1265 | 1362 | ||
1266 | ret = create_pending_snapshots(trans, root->fs_info); | 1363 | ret = create_pending_snapshots(trans, root->fs_info); |
1267 | BUG_ON(ret); | 1364 | if (ret) { |
1365 | mutex_unlock(&root->fs_info->reloc_mutex); | ||
1366 | goto cleanup_transaction; | ||
1367 | } | ||
1268 | 1368 | ||
1269 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 1369 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
1270 | BUG_ON(ret); | 1370 | if (ret) { |
1371 | mutex_unlock(&root->fs_info->reloc_mutex); | ||
1372 | goto cleanup_transaction; | ||
1373 | } | ||
1271 | 1374 | ||
1272 | /* | 1375 | /* |
1273 | * make sure none of the code above managed to slip in a | 1376 | * make sure none of the code above managed to slip in a |
@@ -1294,7 +1397,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1294 | mutex_lock(&root->fs_info->tree_log_mutex); | 1397 | mutex_lock(&root->fs_info->tree_log_mutex); |
1295 | 1398 | ||
1296 | ret = commit_fs_roots(trans, root); | 1399 | ret = commit_fs_roots(trans, root); |
1297 | BUG_ON(ret); | 1400 | if (ret) { |
1401 | mutex_unlock(&root->fs_info->tree_log_mutex); | ||
1402 | goto cleanup_transaction; | ||
1403 | } | ||
1298 | 1404 | ||
1299 | /* commit_fs_roots gets rid of all the tree log roots, it is now | 1405 | /* commit_fs_roots gets rid of all the tree log roots, it is now |
1300 | * safe to free the root of tree log roots | 1406 | * safe to free the root of tree log roots |
@@ -1302,7 +1408,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1302 | btrfs_free_log_root_tree(trans, root->fs_info); | 1408 | btrfs_free_log_root_tree(trans, root->fs_info); |
1303 | 1409 | ||
1304 | ret = commit_cowonly_roots(trans, root); | 1410 | ret = commit_cowonly_roots(trans, root); |
1305 | BUG_ON(ret); | 1411 | if (ret) { |
1412 | mutex_unlock(&root->fs_info->tree_log_mutex); | ||
1413 | goto cleanup_transaction; | ||
1414 | } | ||
1306 | 1415 | ||
1307 | btrfs_prepare_extent_commit(trans, root); | 1416 | btrfs_prepare_extent_commit(trans, root); |
1308 | 1417 | ||
@@ -1336,8 +1445,18 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1336 | wake_up(&root->fs_info->transaction_wait); | 1445 | wake_up(&root->fs_info->transaction_wait); |
1337 | 1446 | ||
1338 | ret = btrfs_write_and_wait_transaction(trans, root); | 1447 | ret = btrfs_write_and_wait_transaction(trans, root); |
1339 | BUG_ON(ret); | 1448 | if (ret) { |
1340 | write_ctree_super(trans, root, 0); | 1449 | btrfs_error(root->fs_info, ret, |
1450 | "Error while writing out transaction."); | ||
1451 | mutex_unlock(&root->fs_info->tree_log_mutex); | ||
1452 | goto cleanup_transaction; | ||
1453 | } | ||
1454 | |||
1455 | ret = write_ctree_super(trans, root, 0); | ||
1456 | if (ret) { | ||
1457 | mutex_unlock(&root->fs_info->tree_log_mutex); | ||
1458 | goto cleanup_transaction; | ||
1459 | } | ||
1341 | 1460 | ||
1342 | /* | 1461 | /* |
1343 | * the super is written, we can safely allow the tree-loggers | 1462 | * the super is written, we can safely allow the tree-loggers |
@@ -1373,6 +1492,15 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
1373 | btrfs_run_delayed_iputs(root); | 1492 | btrfs_run_delayed_iputs(root); |
1374 | 1493 | ||
1375 | return ret; | 1494 | return ret; |
1495 | |||
1496 | cleanup_transaction: | ||
1497 | btrfs_printk(root->fs_info, "Skipping commit of aborted transaction.\n"); | ||
1498 | // WARN_ON(1); | ||
1499 | if (current->journal_info == trans) | ||
1500 | current->journal_info = NULL; | ||
1501 | cleanup_transaction(trans, root); | ||
1502 | |||
1503 | return ret; | ||
1376 | } | 1504 | } |
1377 | 1505 | ||
1378 | /* | 1506 | /* |
@@ -1388,6 +1516,8 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1388 | spin_unlock(&fs_info->trans_lock); | 1516 | spin_unlock(&fs_info->trans_lock); |
1389 | 1517 | ||
1390 | while (!list_empty(&list)) { | 1518 | while (!list_empty(&list)) { |
1519 | int ret; | ||
1520 | |||
1391 | root = list_entry(list.next, struct btrfs_root, root_list); | 1521 | root = list_entry(list.next, struct btrfs_root, root_list); |
1392 | list_del(&root->root_list); | 1522 | list_del(&root->root_list); |
1393 | 1523 | ||
@@ -1395,9 +1525,10 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1395 | 1525 | ||
1396 | if (btrfs_header_backref_rev(root->node) < | 1526 | if (btrfs_header_backref_rev(root->node) < |
1397 | BTRFS_MIXED_BACKREF_REV) | 1527 | BTRFS_MIXED_BACKREF_REV) |
1398 | btrfs_drop_snapshot(root, NULL, 0, 0); | 1528 | ret = btrfs_drop_snapshot(root, NULL, 0, 0); |
1399 | else | 1529 | else |
1400 | btrfs_drop_snapshot(root, NULL, 1, 0); | 1530 | ret =btrfs_drop_snapshot(root, NULL, 1, 0); |
1531 | BUG_ON(ret < 0); | ||
1401 | } | 1532 | } |
1402 | return 0; | 1533 | return 0; |
1403 | } | 1534 | } |