Commit 7c4452b9 authored by Chris Mason's avatar Chris Mason Committed by David Woodhouse

Btrfs: smarter transaction writeback

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 06a2f9fa
......@@ -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;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment