Btrfs: smarter transaction writeback
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
06a2f9fa4c
commit
7c4452b9a6
4 changed files with 37 additions and 3 deletions
|
@ -762,6 +762,7 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
|
|||
BUG_ON(ret);
|
||||
buf = btrfs_find_create_tree_block(root, ins.objectid);
|
||||
set_buffer_uptodate(buf);
|
||||
set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -980,7 +980,6 @@ static int btrfs_sync_fs(struct super_block *sb, int wait)
|
|||
filemap_flush(root->fs_info->btree_inode->i_mapping);
|
||||
return 0;
|
||||
}
|
||||
filemap_write_and_wait(root->fs_info->btree_inode->i_mapping);
|
||||
mutex_lock(&root->fs_info->fs_mutex);
|
||||
trans = btrfs_start_transaction(root, 1);
|
||||
ret = btrfs_commit_transaction(trans, root);
|
||||
|
|
|
@ -45,6 +45,7 @@ static int join_transaction(struct btrfs_root *root)
|
|||
cur_trans->use_count = 1;
|
||||
cur_trans->commit_done = 0;
|
||||
list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
|
||||
init_bit_radix(&cur_trans->dirty_pages);
|
||||
}
|
||||
cur_trans->num_writers++;
|
||||
return 0;
|
||||
|
@ -106,8 +107,40 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
|||
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root)
|
||||
{
|
||||
filemap_write_and_wait(root->fs_info->btree_inode->i_mapping);
|
||||
return 0;
|
||||
unsigned long gang[16];
|
||||
int ret;
|
||||
int i;
|
||||
int err;
|
||||
int werr = 0;
|
||||
struct page *page;
|
||||
struct radix_tree_root *dirty_pages;
|
||||
struct inode *btree_inode = root->fs_info->btree_inode;
|
||||
|
||||
if (!trans || !trans->transaction) {
|
||||
return filemap_write_and_wait(btree_inode->i_mapping);
|
||||
}
|
||||
dirty_pages = &trans->transaction->dirty_pages;
|
||||
while(1) {
|
||||
ret = find_first_radix_bit(dirty_pages, gang, ARRAY_SIZE(gang));
|
||||
if (!ret)
|
||||
break;
|
||||
for (i = 0; i < ret; i++) {
|
||||
/* FIXME EIO */
|
||||
clear_radix_bit(dirty_pages, gang[i]);
|
||||
page = find_lock_page(btree_inode->i_mapping,
|
||||
gang[i]);
|
||||
if (!page)
|
||||
continue;
|
||||
err = write_one_page(page, 0);
|
||||
if (err)
|
||||
werr = err;
|
||||
page_cache_release(page);
|
||||
}
|
||||
}
|
||||
err = filemap_fdatawait(btree_inode->i_mapping);
|
||||
if (err)
|
||||
werr = err;
|
||||
return werr;
|
||||
}
|
||||
|
||||
int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
|
||||
|
|
|
@ -9,6 +9,7 @@ struct btrfs_transaction {
|
|||
int commit_done;
|
||||
int magic;
|
||||
struct list_head list;
|
||||
struct radix_tree_root dirty_pages;
|
||||
wait_queue_head_t writer_wait;
|
||||
wait_queue_head_t commit_wait;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue