aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2010-05-16 10:49:59 -0400
committerChris Mason <chris.mason@oracle.com>2010-05-25 10:34:54 -0400
commit3fd0a5585eb98e074fb9934549c8d85c49756c0d (patch)
tree3e7ff9bd9678a5eea62818a2f4a50e19dda91a81 /fs/btrfs/extent-tree.c
parentefa56464562991b8c24f965199888806bd8c4b38 (diff)
Btrfs: Metadata ENOSPC handling for balance
This patch adds metadata ENOSPC handling for the balance code. It is consisted by following major changes: 1. Avoid COW tree leave in the phrase of merging tree. 2. Handle interaction with snapshot creation. 3. make the backref cache can live across transactions. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a713f69f0c7a..d61a799fe323 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5875,7 +5875,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
5875 * also make sure backrefs for the shared block and all lower level 5875 * also make sure backrefs for the shared block and all lower level
5876 * blocks are properly updated. 5876 * blocks are properly updated.
5877 */ 5877 */
5878int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref) 5878int btrfs_drop_snapshot(struct btrfs_root *root,
5879 struct btrfs_block_rsv *block_rsv, int update_ref)
5879{ 5880{
5880 struct btrfs_path *path; 5881 struct btrfs_path *path;
5881 struct btrfs_trans_handle *trans; 5882 struct btrfs_trans_handle *trans;
@@ -5894,6 +5895,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref)
5894 BUG_ON(!wc); 5895 BUG_ON(!wc);
5895 5896
5896 trans = btrfs_start_transaction(tree_root, 0); 5897 trans = btrfs_start_transaction(tree_root, 0);
5898 if (block_rsv)
5899 trans->block_rsv = block_rsv;
5897 5900
5898 if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) { 5901 if (btrfs_disk_key_objectid(&root_item->drop_progress) == 0) {
5899 level = btrfs_header_level(root->node); 5902 level = btrfs_header_level(root->node);
@@ -5981,24 +5984,16 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref)
5981 } 5984 }
5982 5985
5983 BUG_ON(wc->level == 0); 5986 BUG_ON(wc->level == 0);
5984 if (trans->transaction->in_commit || 5987 if (btrfs_should_end_transaction(trans, tree_root)) {
5985 trans->transaction->delayed_refs.flushing) {
5986 ret = btrfs_update_root(trans, tree_root, 5988 ret = btrfs_update_root(trans, tree_root,
5987 &root->root_key, 5989 &root->root_key,
5988 root_item); 5990 root_item);
5989 BUG_ON(ret); 5991 BUG_ON(ret);
5990 5992
5991 btrfs_end_transaction(trans, tree_root); 5993 btrfs_end_transaction_throttle(trans, tree_root);
5992 trans = btrfs_start_transaction(tree_root, 0); 5994 trans = btrfs_start_transaction(tree_root, 0);
5993 if (IS_ERR(trans)) 5995 if (block_rsv)
5994 return PTR_ERR(trans); 5996 trans->block_rsv = block_rsv;
5995 } else {
5996 unsigned long update;
5997 update = trans->delayed_ref_updates;
5998 trans->delayed_ref_updates = 0;
5999 if (update)
6000 btrfs_run_delayed_refs(trans, tree_root,
6001 update);
6002 } 5997 }
6003 } 5998 }
6004 btrfs_release_path(root, path); 5999 btrfs_release_path(root, path);
@@ -6026,7 +6021,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref)
6026 kfree(root); 6021 kfree(root);
6027 } 6022 }
6028out: 6023out:
6029 btrfs_end_transaction(trans, tree_root); 6024 btrfs_end_transaction_throttle(trans, tree_root);
6030 kfree(wc); 6025 kfree(wc);
6031 btrfs_free_path(path); 6026 btrfs_free_path(path);
6032 return err; 6027 return err;