Commit c6adc9cc authored by Miao Xie's avatar Miao Xie Committed by Josef Bacik

Btrfs: merge pending IO for tree log write back

Before applying this patch, we flushed the log tree of the fs/file
tree firstly, and then flushed the log root tree. It is ineffective,
especially on the hard disk. This patch improved this problem by wrapping
the above two flushes by the same blk_plug.

By test, the performance of the sync write went up ~60%(2.9MB/s -> 4.6MB/s)
on my scsi disk whose disk buffer was enabled.

Test step:
 # mkfs.btrfs -f -m single <disk>
 # mount <disk> <mnt>
 # dd if=/dev/zero of=<mnt>/file0 bs=32K count=1024 oflag=sync
Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
parent a96fbc72
...@@ -778,9 +778,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, ...@@ -778,9 +778,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root,
struct extent_state *cached_state = NULL; struct extent_state *cached_state = NULL;
u64 start = 0; u64 start = 0;
u64 end; u64 end;
struct blk_plug plug;
blk_start_plug(&plug);
while (!find_first_extent_bit(dirty_pages, start, &start, &end, while (!find_first_extent_bit(dirty_pages, start, &start, &end,
mark, &cached_state)) { mark, &cached_state)) {
convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT,
...@@ -794,7 +792,6 @@ int btrfs_write_marked_extents(struct btrfs_root *root, ...@@ -794,7 +792,6 @@ int btrfs_write_marked_extents(struct btrfs_root *root,
} }
if (err) if (err)
werr = err; werr = err;
blk_finish_plug(&plug);
return werr; return werr;
} }
...@@ -839,8 +836,11 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, ...@@ -839,8 +836,11 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
{ {
int ret; int ret;
int ret2; int ret2;
struct blk_plug plug;
blk_start_plug(&plug);
ret = btrfs_write_marked_extents(root, dirty_pages, mark); ret = btrfs_write_marked_extents(root, dirty_pages, mark);
blk_finish_plug(&plug);
ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark);
if (ret) if (ret)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/list_sort.h> #include <linux/list_sort.h>
#include "ctree.h" #include "ctree.h"
#include "transaction.h" #include "transaction.h"
...@@ -2353,6 +2354,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2353,6 +2354,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
struct btrfs_root *log = root->log_root; struct btrfs_root *log = root->log_root;
struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
unsigned long log_transid = 0; unsigned long log_transid = 0;
struct blk_plug plug;
mutex_lock(&root->log_mutex); mutex_lock(&root->log_mutex);
log_transid = root->log_transid; log_transid = root->log_transid;
...@@ -2396,8 +2398,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2396,8 +2398,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
/* we start IO on all the marked extents here, but we don't actually /* we start IO on all the marked extents here, but we don't actually
* wait for them until later. * wait for them until later.
*/ */
blk_start_plug(&plug);
ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark); ret = btrfs_write_marked_extents(log, &log->dirty_log_pages, mark);
if (ret) { if (ret) {
blk_finish_plug(&plug);
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
btrfs_free_logged_extents(log, log_transid); btrfs_free_logged_extents(log, log_transid);
mutex_unlock(&root->log_mutex); mutex_unlock(&root->log_mutex);
...@@ -2432,6 +2436,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2432,6 +2436,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
} }
if (ret) { if (ret) {
blk_finish_plug(&plug);
if (ret != -ENOSPC) { if (ret != -ENOSPC) {
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
mutex_unlock(&log_root_tree->log_mutex); mutex_unlock(&log_root_tree->log_mutex);
...@@ -2447,6 +2452,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2447,6 +2452,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
index2 = log_root_tree->log_transid % 2; index2 = log_root_tree->log_transid % 2;
if (atomic_read(&log_root_tree->log_commit[index2])) { if (atomic_read(&log_root_tree->log_commit[index2])) {
blk_finish_plug(&plug);
btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
wait_log_commit(trans, log_root_tree, wait_log_commit(trans, log_root_tree,
log_root_tree->log_transid); log_root_tree->log_transid);
...@@ -2469,6 +2475,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2469,6 +2475,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
* check the full commit flag again * check the full commit flag again
*/ */
if (root->fs_info->last_trans_log_full_commit == trans->transid) { if (root->fs_info->last_trans_log_full_commit == trans->transid) {
blk_finish_plug(&plug);
btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
btrfs_free_logged_extents(log, log_transid); btrfs_free_logged_extents(log, log_transid);
mutex_unlock(&log_root_tree->log_mutex); mutex_unlock(&log_root_tree->log_mutex);
...@@ -2476,9 +2483,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2476,9 +2483,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
goto out_wake_log_root; goto out_wake_log_root;
} }
ret = btrfs_write_and_wait_marked_extents(log_root_tree, ret = btrfs_write_marked_extents(log_root_tree,
&log_root_tree->dirty_log_pages, &log_root_tree->dirty_log_pages,
EXTENT_DIRTY | EXTENT_NEW); EXTENT_DIRTY | EXTENT_NEW);
blk_finish_plug(&plug);
if (ret) { if (ret) {
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
btrfs_free_logged_extents(log, log_transid); btrfs_free_logged_extents(log, log_transid);
...@@ -2486,6 +2494,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2486,6 +2494,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
goto out_wake_log_root; goto out_wake_log_root;
} }
btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
btrfs_wait_marked_extents(log_root_tree,
&log_root_tree->dirty_log_pages,
EXTENT_NEW | EXTENT_DIRTY);
btrfs_wait_logged_extents(log, log_transid); btrfs_wait_logged_extents(log, log_transid);
btrfs_set_super_log_root(root->fs_info->super_for_commit, btrfs_set_super_log_root(root->fs_info->super_for_commit,
......
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