aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-06-25 16:01:31 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:04 -0400
commit3f157a2fd2ad731e1ed9964fecdc5f459f04a4a4 (patch)
treedf9421e7b1d0c06d5efb8659f4317438d3d511d7 /fs/btrfs/transaction.c
parent1b1e2135dc1e4efbcf25ac9ac9979316d4e1193e (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.c35
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;
30extern struct kmem_cache *btrfs_transaction_cachep; 30extern 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
35static noinline void put_transaction(struct btrfs_transaction *transaction) 34static 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
418int 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
444static noinline int drop_dirty_roots(struct btrfs_root *tree_root, 411static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
445 struct list_head *list) 412 struct list_head *list)
446{ 413{