From: Chris Mason Date: Mon, 15 Oct 2007 20:19:46 +0000 (-0400) Subject: Btrfs: Large block related defrag optimizations X-Git-Tag: v2.6.29-rc2~3^2~11^2~55^2~56^2~30^2~456 X-Git-Url: http://ftp.safe.ca/?a=commitdiff_plain;h=0f1ebbd159baade0417f8f62f0cd6810cc950832;p=safe%2Fjmp%2Flinux-2.6 Btrfs: Large block related defrag optimizations Signed-off-by: Chris Mason --- diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 0c6ed17..e1557e5 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -217,11 +217,9 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, root->fs_info->generation); WARN_ON(1); } - if (btrfs_buffer_defrag_done(parent)) - return 0; + parent_level = btrfs_header_level(parent); parent_nritems = btrfs_header_nritems(parent); - parent_level = btrfs_header_level(parent); blocksize = btrfs_level_size(root, parent_level - 1); start_slot = 0; diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c index 0d1a1be..d31c21a 100644 --- a/fs/btrfs/tree-defrag.c +++ b/fs/btrfs/tree-defrag.c @@ -118,7 +118,6 @@ static int defrag_walk_down(struct btrfs_trans_handle *trans, WARN_ON(*level >= BTRFS_MAX_LEVEL); btrfs_clear_buffer_defrag(path->nodes[*level]); - btrfs_clear_buffer_defrag_done(path->nodes[*level]); free_extent_buffer(path->nodes[*level]); path->nodes[*level] = NULL; @@ -148,6 +147,26 @@ static int defrag_walk_up(struct btrfs_trans_handle *trans, root->defrag_level = i; return 0; } else { + if (*level > 1 && path->nodes[*level] != root->node) { + struct extent_buffer *next; + u64 last; + int ret; + ret = btrfs_cow_block(trans, root, + path->nodes[*level], + path->nodes[*level + 1], + path->slots[*level + 1], + &next); + BUG_ON(ret); + path->nodes[*level] = next; + last = next->start; + ret = btrfs_realloc_node(trans, root, next, + cache_only, &last); + BUG_ON(ret); + + if (root == root->fs_info->extent_root) + btrfs_extent_post_op(trans, root); + } + btrfs_clear_buffer_defrag(path->nodes[*level]); btrfs_clear_buffer_defrag_done(path->nodes[*level]); free_extent_buffer(path->nodes[*level]); @@ -183,9 +202,11 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, level = btrfs_header_level(root->node); orig_level = level; + if (level == 0) { goto out; } + if (root->defrag_progress.objectid == 0) { extent_buffer_get(root->node); ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);