aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/disk-io.c16
-rw-r--r--fs/btrfs/ioctl.c6
-rw-r--r--fs/btrfs/transaction.c58
3 files changed, 41 insertions, 39 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 02369a3c162e..7d84651e850b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -62,7 +62,7 @@ static void btrfs_destroy_ordered_operations(struct btrfs_transaction *t,
62static void btrfs_destroy_ordered_extents(struct btrfs_root *root); 62static void btrfs_destroy_ordered_extents(struct btrfs_root *root);
63static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, 63static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
64 struct btrfs_root *root); 64 struct btrfs_root *root);
65static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t); 65static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t);
66static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root); 66static void btrfs_destroy_delalloc_inodes(struct btrfs_root *root);
67static int btrfs_destroy_marked_extents(struct btrfs_root *root, 67static int btrfs_destroy_marked_extents(struct btrfs_root *root,
68 struct extent_io_tree *dirty_pages, 68 struct extent_io_tree *dirty_pages,
@@ -3687,7 +3687,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
3687 return ret; 3687 return ret;
3688} 3688}
3689 3689
3690static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t) 3690static void btrfs_evict_pending_snapshots(struct btrfs_transaction *t)
3691{ 3691{
3692 struct btrfs_pending_snapshot *snapshot; 3692 struct btrfs_pending_snapshot *snapshot;
3693 struct list_head splice; 3693 struct list_head splice;
@@ -3700,10 +3700,8 @@ static void btrfs_destroy_pending_snapshots(struct btrfs_transaction *t)
3700 snapshot = list_entry(splice.next, 3700 snapshot = list_entry(splice.next,
3701 struct btrfs_pending_snapshot, 3701 struct btrfs_pending_snapshot,
3702 list); 3702 list);
3703 3703 snapshot->error = -ECANCELED;
3704 list_del_init(&snapshot->list); 3704 list_del_init(&snapshot->list);
3705
3706 kfree(snapshot);
3707 } 3705 }
3708} 3706}
3709 3707
@@ -3840,6 +3838,8 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
3840 cur_trans->blocked = 1; 3838 cur_trans->blocked = 1;
3841 wake_up(&root->fs_info->transaction_blocked_wait); 3839 wake_up(&root->fs_info->transaction_blocked_wait);
3842 3840
3841 btrfs_evict_pending_snapshots(cur_trans);
3842
3843 cur_trans->blocked = 0; 3843 cur_trans->blocked = 0;
3844 wake_up(&root->fs_info->transaction_wait); 3844 wake_up(&root->fs_info->transaction_wait);
3845 3845
@@ -3849,8 +3849,6 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans,
3849 btrfs_destroy_delayed_inodes(root); 3849 btrfs_destroy_delayed_inodes(root);
3850 btrfs_assert_delayed_root_empty(root); 3850 btrfs_assert_delayed_root_empty(root);
3851 3851
3852 btrfs_destroy_pending_snapshots(cur_trans);
3853
3854 btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages, 3852 btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages,
3855 EXTENT_DIRTY); 3853 EXTENT_DIRTY);
3856 btrfs_destroy_pinned_extent(root, 3854 btrfs_destroy_pinned_extent(root,
@@ -3894,6 +3892,8 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
3894 if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) 3892 if (waitqueue_active(&root->fs_info->transaction_blocked_wait))
3895 wake_up(&root->fs_info->transaction_blocked_wait); 3893 wake_up(&root->fs_info->transaction_blocked_wait);
3896 3894
3895 btrfs_evict_pending_snapshots(t);
3896
3897 t->blocked = 0; 3897 t->blocked = 0;
3898 smp_mb(); 3898 smp_mb();
3899 if (waitqueue_active(&root->fs_info->transaction_wait)) 3899 if (waitqueue_active(&root->fs_info->transaction_wait))
@@ -3907,8 +3907,6 @@ int btrfs_cleanup_transaction(struct btrfs_root *root)
3907 btrfs_destroy_delayed_inodes(root); 3907 btrfs_destroy_delayed_inodes(root);
3908 btrfs_assert_delayed_root_empty(root); 3908 btrfs_assert_delayed_root_empty(root);
3909 3909
3910 btrfs_destroy_pending_snapshots(t);
3911
3912 btrfs_destroy_delalloc_inodes(root); 3910 btrfs_destroy_delalloc_inodes(root);
3913 3911
3914 spin_lock(&root->fs_info->trans_lock); 3912 spin_lock(&root->fs_info->trans_lock);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index b908960c9746..94c0e42dfa1e 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -596,12 +596,8 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
596 ret = btrfs_commit_transaction(trans, 596 ret = btrfs_commit_transaction(trans,
597 root->fs_info->extent_root); 597 root->fs_info->extent_root);
598 } 598 }
599 if (ret) { 599 if (ret)
600 /* cleanup_transaction has freed this for us */
601 if (trans->aborted)
602 pending_snapshot = NULL;
603 goto fail; 600 goto fail;
604 }
605 601
606 ret = pending_snapshot->error; 602 ret = pending_snapshot->error;
607 if (ret) 603 if (ret)
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index f11c2e0a3746..d8fce6fe9cf8 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1053,7 +1053,12 @@ int btrfs_defrag_root(struct btrfs_root *root)
1053 1053
1054/* 1054/*
1055 * new snapshots need to be created at a very specific time in the 1055 * new snapshots need to be created at a very specific time in the
1056 * transaction commit. This does the actual creation 1056 * transaction commit. This does the actual creation.
1057 *
1058 * Note:
1059 * If the error which may affect the commitment of the current transaction
1060 * happens, we should return the error number. If the error which just affect
1061 * the creation of the pending snapshots, just return 0.
1057 */ 1062 */
1058static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, 1063static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1059 struct btrfs_fs_info *fs_info, 1064 struct btrfs_fs_info *fs_info,
@@ -1072,7 +1077,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1072 struct extent_buffer *tmp; 1077 struct extent_buffer *tmp;
1073 struct extent_buffer *old; 1078 struct extent_buffer *old;
1074 struct timespec cur_time = CURRENT_TIME; 1079 struct timespec cur_time = CURRENT_TIME;
1075 int ret; 1080 int ret = 0;
1076 u64 to_reserve = 0; 1081 u64 to_reserve = 0;
1077 u64 index = 0; 1082 u64 index = 0;
1078 u64 objectid; 1083 u64 objectid;
@@ -1081,40 +1086,36 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1081 1086
1082 path = btrfs_alloc_path(); 1087 path = btrfs_alloc_path();
1083 if (!path) { 1088 if (!path) {
1084 ret = pending->error = -ENOMEM; 1089 pending->error = -ENOMEM;
1085 return ret; 1090 return 0;
1086 } 1091 }
1087 1092
1088 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 1093 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
1089 if (!new_root_item) { 1094 if (!new_root_item) {
1090 ret = pending->error = -ENOMEM; 1095 pending->error = -ENOMEM;
1091 goto root_item_alloc_fail; 1096 goto root_item_alloc_fail;
1092 } 1097 }
1093 1098
1094 ret = btrfs_find_free_objectid(tree_root, &objectid); 1099 pending->error = btrfs_find_free_objectid(tree_root, &objectid);
1095 if (ret) { 1100 if (pending->error)
1096 pending->error = ret;
1097 goto no_free_objectid; 1101 goto no_free_objectid;
1098 }
1099 1102
1100 btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); 1103 btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
1101 1104
1102 if (to_reserve > 0) { 1105 if (to_reserve > 0) {
1103 ret = btrfs_block_rsv_add(root, &pending->block_rsv, 1106 pending->error = btrfs_block_rsv_add(root,
1104 to_reserve, 1107 &pending->block_rsv,
1105 BTRFS_RESERVE_NO_FLUSH); 1108 to_reserve,
1106 if (ret) { 1109 BTRFS_RESERVE_NO_FLUSH);
1107 pending->error = ret; 1110 if (pending->error)
1108 goto no_free_objectid; 1111 goto no_free_objectid;
1109 }
1110 } 1112 }
1111 1113
1112 ret = btrfs_qgroup_inherit(trans, fs_info, root->root_key.objectid, 1114 pending->error = btrfs_qgroup_inherit(trans, fs_info,
1113 objectid, pending->inherit); 1115 root->root_key.objectid,
1114 if (ret) { 1116 objectid, pending->inherit);
1115 pending->error = ret; 1117 if (pending->error)
1116 goto no_free_objectid; 1118 goto no_free_objectid;
1117 }
1118 1119
1119 key.objectid = objectid; 1120 key.objectid = objectid;
1120 key.offset = (u64)-1; 1121 key.offset = (u64)-1;
@@ -1142,7 +1143,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1142 dentry->d_name.len, 0); 1143 dentry->d_name.len, 0);
1143 if (dir_item != NULL && !IS_ERR(dir_item)) { 1144 if (dir_item != NULL && !IS_ERR(dir_item)) {
1144 pending->error = -EEXIST; 1145 pending->error = -EEXIST;
1145 goto fail; 1146 goto dir_item_existed;
1146 } else if (IS_ERR(dir_item)) { 1147 } else if (IS_ERR(dir_item)) {
1147 ret = PTR_ERR(dir_item); 1148 ret = PTR_ERR(dir_item);
1148 btrfs_abort_transaction(trans, root, ret); 1149 btrfs_abort_transaction(trans, root, ret);
@@ -1273,6 +1274,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1273 if (ret) 1274 if (ret)
1274 btrfs_abort_transaction(trans, root, ret); 1275 btrfs_abort_transaction(trans, root, ret);
1275fail: 1276fail:
1277 pending->error = ret;
1278dir_item_existed:
1276 trans->block_rsv = rsv; 1279 trans->block_rsv = rsv;
1277 trans->bytes_reserved = 0; 1280 trans->bytes_reserved = 0;
1278no_free_objectid: 1281no_free_objectid:
@@ -1288,12 +1291,17 @@ root_item_alloc_fail:
1288static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, 1291static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
1289 struct btrfs_fs_info *fs_info) 1292 struct btrfs_fs_info *fs_info)
1290{ 1293{
1291 struct btrfs_pending_snapshot *pending; 1294 struct btrfs_pending_snapshot *pending, *next;
1292 struct list_head *head = &trans->transaction->pending_snapshots; 1295 struct list_head *head = &trans->transaction->pending_snapshots;
1296 int ret = 0;
1293 1297
1294 list_for_each_entry(pending, head, list) 1298 list_for_each_entry_safe(pending, next, head, list) {
1295 create_pending_snapshot(trans, fs_info, pending); 1299 list_del(&pending->list);
1296 return 0; 1300 ret = create_pending_snapshot(trans, fs_info, pending);
1301 if (ret)
1302 break;
1303 }
1304 return ret;
1297} 1305}
1298 1306
1299static void update_super_roots(struct btrfs_root *root) 1307static void update_super_roots(struct btrfs_root *root)