Commit 2c47e605 authored by Yan Zheng's avatar Yan Zheng Committed by Chris Mason

Btrfs: update backrefs while dropping snapshot

The new backref format has restriction on type of backref item.  If a tree
block isn't referenced by its owner tree, full backrefs must be used for the
pointers in it. When a tree block loses its owner tree's reference, backrefs
for the pointers in it should be updated to full backrefs. Current
btrfs_drop_snapshot misses the code that updates backrefs, so it's unsafe for
general use.

This patch adds backrefs update code to btrfs_drop_snapshot.  It isn't a
problem in the restricted form btrfs_drop_snapshot is used today, but for
general snapshot deletion this update is required.
Signed-off-by: default avatarYan Zheng <zheng.yan@oracle.com>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent a970b0a1
...@@ -2076,8 +2076,7 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, ...@@ -2076,8 +2076,7 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref);
*root);
int btrfs_drop_subtree(struct btrfs_trans_handle *trans, int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
struct extent_buffer *node, struct extent_buffer *node,
......
This diff is collapsed.
...@@ -1788,7 +1788,7 @@ static void merge_func(struct btrfs_work *work) ...@@ -1788,7 +1788,7 @@ static void merge_func(struct btrfs_work *work)
btrfs_end_transaction(trans, root); btrfs_end_transaction(trans, root);
} }
btrfs_drop_dead_root(reloc_root); btrfs_drop_snapshot(reloc_root, 0);
if (atomic_dec_and_test(async->num_pending)) if (atomic_dec_and_test(async->num_pending))
complete(async->done); complete(async->done);
...@@ -2075,9 +2075,6 @@ static int do_relocation(struct btrfs_trans_handle *trans, ...@@ -2075,9 +2075,6 @@ static int do_relocation(struct btrfs_trans_handle *trans,
ret = btrfs_drop_subtree(trans, root, eb, upper->eb); ret = btrfs_drop_subtree(trans, root, eb, upper->eb);
BUG_ON(ret); BUG_ON(ret);
btrfs_tree_unlock(eb);
free_extent_buffer(eb);
} }
if (!lowest) { if (!lowest) {
btrfs_tree_unlock(upper->eb); btrfs_tree_unlock(upper->eb);
......
...@@ -593,6 +593,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) ...@@ -593,6 +593,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
return 0; return 0;
} }
#if 0
/* /*
* when dropping snapshots, we generate a ton of delayed refs, and it makes * when dropping snapshots, we generate a ton of delayed refs, and it makes
* sense not to join the transaction while it is trying to flush the current * sense not to join the transaction while it is trying to flush the current
...@@ -681,6 +682,7 @@ int btrfs_drop_dead_root(struct btrfs_root *root) ...@@ -681,6 +682,7 @@ int btrfs_drop_dead_root(struct btrfs_root *root)
btrfs_btree_balance_dirty(tree_root, nr); btrfs_btree_balance_dirty(tree_root, nr);
return ret; return ret;
} }
#endif
/* /*
* new snapshots need to be created at a very specific time in the * new snapshots need to be created at a very specific time in the
...@@ -1081,7 +1083,7 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) ...@@ -1081,7 +1083,7 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root)
while (!list_empty(&list)) { while (!list_empty(&list)) {
root = list_entry(list.next, struct btrfs_root, root_list); root = list_entry(list.next, struct btrfs_root, root_list);
list_del_init(&root->root_list); list_del_init(&root->root_list);
btrfs_drop_dead_root(root); btrfs_drop_snapshot(root, 0);
} }
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment