diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-06-25 16:01:31 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:04 -0400 |
commit | 3f157a2fd2ad731e1ed9964fecdc5f459f04a4a4 (patch) | |
tree | df9421e7b1d0c06d5efb8659f4317438d3d511d7 /fs/btrfs/transaction.c | |
parent | 1b1e2135dc1e4efbcf25ac9ac9979316d4e1193e (diff) |
Btrfs: Online btree defragmentation fixes
The btree defragger wasn't making forward progress because the new key wasn't
being saved by the btrfs_search_forward function.
This also disables the automatic btree defrag, it wasn't scaling well to
huge filesystems. The auto-defrag needs to be done differently.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r-- | fs/btrfs/transaction.c | 35 |
1 files changed, 1 insertions, 34 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 8e909cb97c6d..98f422d9ab07 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -30,7 +30,6 @@ extern struct kmem_cache *btrfs_trans_handle_cachep; | |||
30 | extern struct kmem_cache *btrfs_transaction_cachep; | 30 | extern struct kmem_cache *btrfs_transaction_cachep; |
31 | 31 | ||
32 | #define BTRFS_ROOT_TRANS_TAG 0 | 32 | #define BTRFS_ROOT_TRANS_TAG 0 |
33 | #define BTRFS_ROOT_DEFRAG_TAG 1 | ||
34 | 33 | ||
35 | static noinline void put_transaction(struct btrfs_transaction *transaction) | 34 | static noinline void put_transaction(struct btrfs_transaction *transaction) |
36 | { | 35 | { |
@@ -92,9 +91,6 @@ static noinline int record_root_in_trans(struct btrfs_root *root) | |||
92 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, | 91 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, |
93 | (unsigned long)root->root_key.objectid, | 92 | (unsigned long)root->root_key.objectid, |
94 | BTRFS_ROOT_TRANS_TAG); | 93 | BTRFS_ROOT_TRANS_TAG); |
95 | radix_tree_tag_set(&root->fs_info->fs_roots_radix, | ||
96 | (unsigned long)root->root_key.objectid, | ||
97 | BTRFS_ROOT_DEFRAG_TAG); | ||
98 | root->commit_root = btrfs_root_node(root); | 94 | root->commit_root = btrfs_root_node(root); |
99 | } else { | 95 | } else { |
100 | WARN_ON(1); | 96 | WARN_ON(1); |
@@ -403,44 +399,15 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
403 | cond_resched(); | 399 | cond_resched(); |
404 | 400 | ||
405 | trans = btrfs_start_transaction(root, 1); | 401 | trans = btrfs_start_transaction(root, 1); |
406 | if (ret != -EAGAIN) | 402 | if (root->fs_info->closing || ret != -EAGAIN) |
407 | break; | 403 | break; |
408 | } | 404 | } |
409 | root->defrag_running = 0; | 405 | root->defrag_running = 0; |
410 | smp_mb(); | 406 | smp_mb(); |
411 | radix_tree_tag_clear(&info->fs_roots_radix, | ||
412 | (unsigned long)root->root_key.objectid, | ||
413 | BTRFS_ROOT_DEFRAG_TAG); | ||
414 | btrfs_end_transaction(trans, root); | 407 | btrfs_end_transaction(trans, root); |
415 | return 0; | 408 | return 0; |
416 | } | 409 | } |
417 | 410 | ||
418 | int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info) | ||
419 | { | ||
420 | struct btrfs_root *gang[1]; | ||
421 | struct btrfs_root *root; | ||
422 | int i; | ||
423 | int ret; | ||
424 | int err = 0; | ||
425 | u64 last = 0; | ||
426 | |||
427 | while(1) { | ||
428 | ret = radix_tree_gang_lookup_tag(&info->fs_roots_radix, | ||
429 | (void **)gang, last, | ||
430 | ARRAY_SIZE(gang), | ||
431 | BTRFS_ROOT_DEFRAG_TAG); | ||
432 | if (ret == 0) | ||
433 | break; | ||
434 | for (i = 0; i < ret; i++) { | ||
435 | root = gang[i]; | ||
436 | last = root->root_key.objectid + 1; | ||
437 | btrfs_defrag_root(root, 1); | ||
438 | } | ||
439 | } | ||
440 | btrfs_defrag_root(info->extent_root, 1); | ||
441 | return err; | ||
442 | } | ||
443 | |||
444 | static noinline int drop_dirty_roots(struct btrfs_root *tree_root, | 411 | static noinline int drop_dirty_roots(struct btrfs_root *tree_root, |
445 | struct list_head *list) | 412 | struct list_head *list) |
446 | { | 413 | { |