Btrfs: smarter transaction writeback
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
06a2f9fa4c
commit
7c4452b9a6
|
@ -762,6 +762,7 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
|
||||||
BUG_ON(ret);
|
BUG_ON(ret);
|
||||||
buf = btrfs_find_create_tree_block(root, ins.objectid);
|
buf = btrfs_find_create_tree_block(root, ins.objectid);
|
||||||
set_buffer_uptodate(buf);
|
set_buffer_uptodate(buf);
|
||||||
|
set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index);
|
||||||
return buf;
|
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);
|
filemap_flush(root->fs_info->btree_inode->i_mapping);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
filemap_write_and_wait(root->fs_info->btree_inode->i_mapping);
|
|
||||||
mutex_lock(&root->fs_info->fs_mutex);
|
mutex_lock(&root->fs_info->fs_mutex);
|
||||||
trans = btrfs_start_transaction(root, 1);
|
trans = btrfs_start_transaction(root, 1);
|
||||||
ret = btrfs_commit_transaction(trans, root);
|
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->use_count = 1;
|
||||||
cur_trans->commit_done = 0;
|
cur_trans->commit_done = 0;
|
||||||
list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
|
list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
|
||||||
|
init_bit_radix(&cur_trans->dirty_pages);
|
||||||
}
|
}
|
||||||
cur_trans->num_writers++;
|
cur_trans->num_writers++;
|
||||||
return 0;
|
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,
|
int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *root)
|
struct btrfs_root *root)
|
||||||
{
|
{
|
||||||
filemap_write_and_wait(root->fs_info->btree_inode->i_mapping);
|
unsigned long gang[16];
|
||||||
return 0;
|
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,
|
int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
|
||||||
|
|
|
@ -9,6 +9,7 @@ struct btrfs_transaction {
|
||||||
int commit_done;
|
int commit_done;
|
||||||
int magic;
|
int magic;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct radix_tree_root dirty_pages;
|
||||||
wait_queue_head_t writer_wait;
|
wait_queue_head_t writer_wait;
|
||||||
wait_queue_head_t commit_wait;
|
wait_queue_head_t commit_wait;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue