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); |
