aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-08-07 16:15:09 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-08-07 16:15:09 -0400
commit6702ed490ca0bb44e17131818a5a18b773957c5a (patch)
treef6bc4b77e58506a68f1ab539ca6c96854f39f92d /fs/btrfs/disk-io.c
parent3c69faecb8d83cb2ef085a98b196a3fecea67725 (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.c8
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,