From 0ef3e66b6700eb8f052daa8b89443ff872fbbdfc Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Sat, 24 May 2008 14:04:53 -0400 Subject: Btrfs: Allocator fix variety pack * Force chunk allocation when find_free_extent has to do a full scan * Record the max key at the start of defrag so it doesn't run forever * Block groups might not be contiguous, make a forward search for the next block group in extent-tree.c * Get rid of extra checks for total fs size * Fix relocate_one_reference to avoid relocating the same file data block twice when referenced by an older transaction * Use the open device count when allocating chunks so that we don't try to allocate from devices that don't exist Signed-off-by: Chris Mason --- fs/btrfs/tree-defrag.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'fs/btrfs/tree-defrag.c') diff --git a/fs/btrfs/tree-defrag.c b/fs/btrfs/tree-defrag.c index c02e2bf2f028..155961c7b4d5 100644 --- a/fs/btrfs/tree-defrag.c +++ b/fs/btrfs/tree-defrag.c @@ -198,6 +198,13 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, goto out; } if (root->defrag_progress.objectid == 0) { + u32 nritems; + + nritems = btrfs_header_nritems(root->node); + root->defrag_max.objectid = 0; + /* from above we know this is not a leaf */ + btrfs_node_key_to_cpu(root->node, &root->defrag_max, + nritems - 1); extent_buffer_get(root->node); ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); BUG_ON(ret); @@ -254,6 +261,16 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, out: if (path) btrfs_free_path(path); + if (ret == -EAGAIN) { + if (root->defrag_max.objectid > root->defrag_progress.objectid) + goto done; + if (root->defrag_max.type > root->defrag_progress.type) + goto done; + if (root->defrag_max.offset > root->defrag_progress.offset) + goto done; + ret = 0; + } +done: if (ret != -EAGAIN) { memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); -- cgit v1.2.2