diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/transaction.c | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index a4fe5494d01b..910ff8051ba9 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -1073,7 +1073,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1073 | goto fail; | 1073 | goto fail; |
1074 | } else if (IS_ERR(dir_item)) { | 1074 | } else if (IS_ERR(dir_item)) { |
1075 | ret = PTR_ERR(dir_item); | 1075 | ret = PTR_ERR(dir_item); |
1076 | goto abort_trans; | 1076 | btrfs_abort_transaction(trans, root, ret); |
1077 | goto fail; | ||
1077 | } | 1078 | } |
1078 | btrfs_release_path(path); | 1079 | btrfs_release_path(path); |
1079 | 1080 | ||
@@ -1084,8 +1085,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1084 | * snapshot | 1085 | * snapshot |
1085 | */ | 1086 | */ |
1086 | ret = btrfs_run_delayed_items(trans, root); | 1087 | ret = btrfs_run_delayed_items(trans, root); |
1087 | if (ret) /* Transaction aborted */ | 1088 | if (ret) { /* Transaction aborted */ |
1088 | goto abort_trans; | 1089 | btrfs_abort_transaction(trans, root, ret); |
1090 | goto fail; | ||
1091 | } | ||
1089 | 1092 | ||
1090 | record_root_in_trans(trans, root); | 1093 | record_root_in_trans(trans, root); |
1091 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); | 1094 | btrfs_set_root_last_snapshot(&root->root_item, trans->transid); |
@@ -1118,7 +1121,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1118 | if (ret) { | 1121 | if (ret) { |
1119 | btrfs_tree_unlock(old); | 1122 | btrfs_tree_unlock(old); |
1120 | free_extent_buffer(old); | 1123 | free_extent_buffer(old); |
1121 | goto abort_trans; | 1124 | btrfs_abort_transaction(trans, root, ret); |
1125 | goto fail; | ||
1122 | } | 1126 | } |
1123 | 1127 | ||
1124 | btrfs_set_lock_blocking(old); | 1128 | btrfs_set_lock_blocking(old); |
@@ -1127,8 +1131,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1127 | /* clean up in any case */ | 1131 | /* clean up in any case */ |
1128 | btrfs_tree_unlock(old); | 1132 | btrfs_tree_unlock(old); |
1129 | free_extent_buffer(old); | 1133 | free_extent_buffer(old); |
1130 | if (ret) | 1134 | if (ret) { |
1131 | goto abort_trans; | 1135 | btrfs_abort_transaction(trans, root, ret); |
1136 | goto fail; | ||
1137 | } | ||
1132 | 1138 | ||
1133 | /* see comments in should_cow_block() */ | 1139 | /* see comments in should_cow_block() */ |
1134 | root->force_cow = 1; | 1140 | root->force_cow = 1; |
@@ -1140,8 +1146,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1140 | ret = btrfs_insert_root(trans, tree_root, &key, new_root_item); | 1146 | ret = btrfs_insert_root(trans, tree_root, &key, new_root_item); |
1141 | btrfs_tree_unlock(tmp); | 1147 | btrfs_tree_unlock(tmp); |
1142 | free_extent_buffer(tmp); | 1148 | free_extent_buffer(tmp); |
1143 | if (ret) | 1149 | if (ret) { |
1144 | goto abort_trans; | 1150 | btrfs_abort_transaction(trans, root, ret); |
1151 | goto fail; | ||
1152 | } | ||
1145 | 1153 | ||
1146 | /* | 1154 | /* |
1147 | * insert root back/forward references | 1155 | * insert root back/forward references |
@@ -1150,23 +1158,30 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1150 | parent_root->root_key.objectid, | 1158 | parent_root->root_key.objectid, |
1151 | btrfs_ino(parent_inode), index, | 1159 | btrfs_ino(parent_inode), index, |
1152 | dentry->d_name.name, dentry->d_name.len); | 1160 | dentry->d_name.name, dentry->d_name.len); |
1153 | if (ret) | 1161 | if (ret) { |
1154 | goto abort_trans; | 1162 | btrfs_abort_transaction(trans, root, ret); |
1163 | goto fail; | ||
1164 | } | ||
1155 | 1165 | ||
1156 | key.offset = (u64)-1; | 1166 | key.offset = (u64)-1; |
1157 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); | 1167 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); |
1158 | if (IS_ERR(pending->snap)) { | 1168 | if (IS_ERR(pending->snap)) { |
1159 | ret = PTR_ERR(pending->snap); | 1169 | ret = PTR_ERR(pending->snap); |
1160 | goto abort_trans; | 1170 | btrfs_abort_transaction(trans, root, ret); |
1171 | goto fail; | ||
1161 | } | 1172 | } |
1162 | 1173 | ||
1163 | ret = btrfs_reloc_post_snapshot(trans, pending); | 1174 | ret = btrfs_reloc_post_snapshot(trans, pending); |
1164 | if (ret) | 1175 | if (ret) { |
1165 | goto abort_trans; | 1176 | btrfs_abort_transaction(trans, root, ret); |
1177 | goto fail; | ||
1178 | } | ||
1166 | 1179 | ||
1167 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); | 1180 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
1168 | if (ret) | 1181 | if (ret) { |
1169 | goto abort_trans; | 1182 | btrfs_abort_transaction(trans, root, ret); |
1183 | goto fail; | ||
1184 | } | ||
1170 | 1185 | ||
1171 | ret = btrfs_insert_dir_item(trans, parent_root, | 1186 | ret = btrfs_insert_dir_item(trans, parent_root, |
1172 | dentry->d_name.name, dentry->d_name.len, | 1187 | dentry->d_name.name, dentry->d_name.len, |
@@ -1174,15 +1189,17 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1174 | BTRFS_FT_DIR, index); | 1189 | BTRFS_FT_DIR, index); |
1175 | /* We have check then name at the beginning, so it is impossible. */ | 1190 | /* We have check then name at the beginning, so it is impossible. */ |
1176 | BUG_ON(ret == -EEXIST); | 1191 | BUG_ON(ret == -EEXIST); |
1177 | if (ret) | 1192 | if (ret) { |
1178 | goto abort_trans; | 1193 | btrfs_abort_transaction(trans, root, ret); |
1194 | goto fail; | ||
1195 | } | ||
1179 | 1196 | ||
1180 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 1197 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
1181 | dentry->d_name.len * 2); | 1198 | dentry->d_name.len * 2); |
1182 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; | 1199 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; |
1183 | ret = btrfs_update_inode(trans, parent_root, parent_inode); | 1200 | ret = btrfs_update_inode(trans, parent_root, parent_inode); |
1184 | if (ret) | 1201 | if (ret) |
1185 | goto abort_trans; | 1202 | btrfs_abort_transaction(trans, root, ret); |
1186 | fail: | 1203 | fail: |
1187 | dput(parent); | 1204 | dput(parent); |
1188 | trans->block_rsv = rsv; | 1205 | trans->block_rsv = rsv; |
@@ -1193,10 +1210,6 @@ root_item_alloc_fail: | |||
1193 | path_alloc_fail: | 1210 | path_alloc_fail: |
1194 | btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); | 1211 | btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); |
1195 | return ret; | 1212 | return ret; |
1196 | |||
1197 | abort_trans: | ||
1198 | btrfs_abort_transaction(trans, root, ret); | ||
1199 | goto fail; | ||
1200 | } | 1213 | } |
1201 | 1214 | ||
1202 | /* | 1215 | /* |