diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-08-07 16:15:09 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-08-07 16:15:09 -0400 |
commit | 6702ed490ca0bb44e17131818a5a18b773957c5a (patch) | |
tree | f6bc4b77e58506a68f1ab539ca6c96854f39f92d /fs/btrfs/disk-io.c | |
parent | 3c69faecb8d83cb2ef085a98b196a3fecea67725 (diff) |
Btrfs: Add run time btree defrag, and an ioctl to force btree defrag
This adds two types of btree defrag, a run time form that tries to
defrag recently allocated blocks in the btree when they are still in ram,
and an ioctl that forces defrag of all btree blocks.
File data blocks are not defragged yet, but this can make a huge difference
in sequential btree reads.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 60db85bc4ba8..c948416fea3a 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -273,7 +273,9 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
273 | struct buffer_head *buf) | 273 | struct buffer_head *buf) |
274 | { | 274 | { |
275 | WARN_ON(atomic_read(&buf->b_count) == 0); | 275 | WARN_ON(atomic_read(&buf->b_count) == 0); |
276 | lock_buffer(buf); | ||
276 | clear_buffer_dirty(buf); | 277 | clear_buffer_dirty(buf); |
278 | unlock_buffer(buf); | ||
277 | return 0; | 279 | return 0; |
278 | } | 280 | } |
279 | 281 | ||
@@ -294,6 +296,9 @@ static int __setup_root(int blocksize, | |||
294 | root->last_inode_alloc = 0; | 296 | root->last_inode_alloc = 0; |
295 | memset(&root->root_key, 0, sizeof(root->root_key)); | 297 | memset(&root->root_key, 0, sizeof(root->root_key)); |
296 | memset(&root->root_item, 0, sizeof(root->root_item)); | 298 | memset(&root->root_item, 0, sizeof(root->root_item)); |
299 | memset(&root->defrag_progress, 0, sizeof(root->defrag_progress)); | ||
300 | root->defrag_running = 0; | ||
301 | root->defrag_level = 0; | ||
297 | root->root_key.objectid = objectid; | 302 | root->root_key.objectid = objectid; |
298 | return 0; | 303 | return 0; |
299 | } | 304 | } |
@@ -585,6 +590,7 @@ int close_ctree(struct btrfs_root *root) | |||
585 | fs_info->closing = 1; | 590 | fs_info->closing = 1; |
586 | btrfs_transaction_flush_work(root); | 591 | btrfs_transaction_flush_work(root); |
587 | mutex_lock(&fs_info->fs_mutex); | 592 | mutex_lock(&fs_info->fs_mutex); |
593 | btrfs_defrag_dirty_roots(root->fs_info); | ||
588 | trans = btrfs_start_transaction(root, 1); | 594 | trans = btrfs_start_transaction(root, 1); |
589 | ret = btrfs_commit_transaction(trans, root); | 595 | ret = btrfs_commit_transaction(trans, root); |
590 | /* run commit again to drop the original snapshot */ | 596 | /* run commit again to drop the original snapshot */ |
@@ -616,7 +622,9 @@ void btrfs_mark_buffer_dirty(struct buffer_head *bh) | |||
616 | { | 622 | { |
617 | struct btrfs_root *root = BTRFS_I(bh->b_page->mapping->host)->root; | 623 | struct btrfs_root *root = BTRFS_I(bh->b_page->mapping->host)->root; |
618 | u64 transid = btrfs_header_generation(btrfs_buffer_header(bh)); | 624 | u64 transid = btrfs_header_generation(btrfs_buffer_header(bh)); |
625 | |||
619 | WARN_ON(!atomic_read(&bh->b_count)); | 626 | WARN_ON(!atomic_read(&bh->b_count)); |
627 | |||
620 | if (transid != root->fs_info->generation) { | 628 | if (transid != root->fs_info->generation) { |
621 | printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n", | 629 | printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n", |
622 | (unsigned long long)bh->b_blocknr, | 630 | (unsigned long long)bh->b_blocknr, |