aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2011-06-17 16:14:09 -0400
committerChris Mason <chris.mason@oracle.com>2011-06-17 16:38:47 -0400
commite999376f094162aa425ae749aa1df95ab928d010 (patch)
tree080d4a2a20d8d7e7ea8b36f63150827b970da715 /fs
parent35a30d7ce54e087d8025a725d4e5a2fdee723a9f (diff)
Btrfs: avoid delayed metadata items during commits
Snapshot creation has two phases. One is the initial snapshot setup, and the second is done during commit, while nobody is allowed to modify the root we are snapshotting. The delayed metadata insertion code can break that rule, it does a delayed inode update on the inode of the parent of the snapshot, and delayed directory item insertion. This makes sure to run the pending delayed operations before we record the snapshot root, which avoids corruptions. Signed-off-by: Chris Mason <chris.mason@oracle.com>
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);