aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/delayed-inode.c7
-rw-r--r--fs/btrfs/delayed-inode.h4
-rw-r--r--fs/btrfs/transaction.c27
3 files changed, 28 insertions, 10 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index fc515b787e8c..f1cbd028f7b3 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -1237,6 +1237,13 @@ again:
1237 return 0; 1237 return 0;
1238} 1238}
1239 1239
1240void btrfs_assert_delayed_root_empty(struct btrfs_root *root)
1241{
1242 struct btrfs_delayed_root *delayed_root;
1243 delayed_root = btrfs_get_delayed_root(root);
1244 WARN_ON(btrfs_first_delayed_node(delayed_root));
1245}
1246
1240void btrfs_balance_delayed_items(struct btrfs_root *root) 1247void btrfs_balance_delayed_items(struct btrfs_root *root)
1241{ 1248{
1242 struct btrfs_delayed_root *delayed_root; 1249 struct btrfs_delayed_root *delayed_root;
diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h
index cb79b6771e82..d1a6a2915c66 100644
--- a/fs/btrfs/delayed-inode.h
+++ b/fs/btrfs/delayed-inode.h
@@ -137,4 +137,8 @@ int btrfs_readdir_delayed_dir_index(struct file *filp, void *dirent,
137/* for init */ 137/* for init */
138int __init btrfs_delayed_inode_init(void); 138int __init btrfs_delayed_inode_init(void);
139void btrfs_delayed_inode_exit(void); 139void btrfs_delayed_inode_exit(void);
140
141/* for debugging */
142void btrfs_assert_delayed_root_empty(struct btrfs_root *root);
143
140#endif 144#endif
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index c073d85e14f3..51dcec86757f 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -957,6 +957,15 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
957 ret = btrfs_update_inode(trans, parent_root, parent_inode); 957 ret = btrfs_update_inode(trans, parent_root, parent_inode);
958 BUG_ON(ret); 958 BUG_ON(ret);
959 959
960 /*
961 * pull in the delayed directory update
962 * and the delayed inode item
963 * otherwise we corrupt the FS during
964 * snapshot
965 */
966 ret = btrfs_run_delayed_items(trans, root);
967 BUG_ON(ret);
968
960 record_root_in_trans(trans, root); 969 record_root_in_trans(trans, root);
961 btrfs_set_root_last_snapshot(&root->root_item, trans->transid); 970 btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
962 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); 971 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
@@ -1018,14 +1027,6 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
1018 int ret; 1027 int ret;
1019 1028
1020 list_for_each_entry(pending, head, list) { 1029 list_for_each_entry(pending, head, list) {
1021 /*
1022 * We must deal with the delayed items before creating
1023 * snapshots, or we will create a snapthot with inconsistent
1024 * information.
1025 */
1026 ret = btrfs_run_delayed_items(trans, fs_info->fs_root);
1027 BUG_ON(ret);
1028
1029 ret = create_pending_snapshot(trans, fs_info, pending); 1030 ret = create_pending_snapshot(trans, fs_info, pending);
1030 BUG_ON(ret); 1031 BUG_ON(ret);
1031 } 1032 }
@@ -1319,15 +1320,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1319 */ 1320 */
1320 mutex_lock(&root->fs_info->reloc_mutex); 1321 mutex_lock(&root->fs_info->reloc_mutex);
1321 1322
1322 ret = create_pending_snapshots(trans, root->fs_info); 1323 ret = btrfs_run_delayed_items(trans, root);
1323 BUG_ON(ret); 1324 BUG_ON(ret);
1324 1325
1325 ret = btrfs_run_delayed_items(trans, root); 1326 ret = create_pending_snapshots(trans, root->fs_info);
1326 BUG_ON(ret); 1327 BUG_ON(ret);
1327 1328
1328 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); 1329 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
1329 BUG_ON(ret); 1330 BUG_ON(ret);
1330 1331
1332 /*
1333 * make sure none of the code above managed to slip in a
1334 * delayed item
1335 */
1336 btrfs_assert_delayed_root_empty(root);
1337
1331 WARN_ON(cur_trans != trans->transaction); 1338 WARN_ON(cur_trans != trans->transaction);
1332 1339
1333 btrfs_scrub_pause(root); 1340 btrfs_scrub_pause(root);