diff options
-rw-r--r-- | fs/btrfs/delayed-inode.c | 7 | ||||
-rw-r--r-- | fs/btrfs/delayed-inode.h | 4 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 27 |
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 | ||
1240 | void 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 | |||
1240 | void btrfs_balance_delayed_items(struct btrfs_root *root) | 1247 | void 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 */ |
138 | int __init btrfs_delayed_inode_init(void); | 138 | int __init btrfs_delayed_inode_init(void); |
139 | void btrfs_delayed_inode_exit(void); | 139 | void btrfs_delayed_inode_exit(void); |
140 | |||
141 | /* for debugging */ | ||
142 | void 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); |