aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-defrag.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-05-24 14:04:53 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:03 -0400
commit0ef3e66b6700eb8f052daa8b89443ff872fbbdfc (patch)
tree26bce57770b4f093199b6f87ab8ed3a54e951337 /fs/btrfs/tree-defrag.c
parent515dc3228c568f9df8b634f82b3471e20205ac16 (diff)
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 <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/tree-defrag.c')
-rw-r--r--fs/btrfs/tree-defrag.c17
1 files changed, 17 insertions, 0 deletions
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,
198 goto out; 198 goto out;
199 } 199 }
200 if (root->defrag_progress.objectid == 0) { 200 if (root->defrag_progress.objectid == 0) {
201 u32 nritems;
202
203 nritems = btrfs_header_nritems(root->node);
204 root->defrag_max.objectid = 0;
205 /* from above we know this is not a leaf */
206 btrfs_node_key_to_cpu(root->node, &root->defrag_max,
207 nritems - 1);
201 extent_buffer_get(root->node); 208 extent_buffer_get(root->node);
202 ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); 209 ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);
203 BUG_ON(ret); 210 BUG_ON(ret);
@@ -254,6 +261,16 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
254out: 261out:
255 if (path) 262 if (path)
256 btrfs_free_path(path); 263 btrfs_free_path(path);
264 if (ret == -EAGAIN) {
265 if (root->defrag_max.objectid > root->defrag_progress.objectid)
266 goto done;
267 if (root->defrag_max.type > root->defrag_progress.type)
268 goto done;
269 if (root->defrag_max.offset > root->defrag_progress.offset)
270 goto done;
271 ret = 0;
272 }
273done:
257 if (ret != -EAGAIN) { 274 if (ret != -EAGAIN) {
258 memset(&root->defrag_progress, 0, 275 memset(&root->defrag_progress, 0,
259 sizeof(root->defrag_progress)); 276 sizeof(root->defrag_progress));