summaryrefslogtreecommitdiffstats
path: root/fs/f2fs/node.c
diff options
context:
space:
mode:
authorChao Yu <chao2.yu@samsung.com>2016-01-18 18:28:11 +0800
committerJaegeuk Kim <jaegeuk@kernel.org>2016-02-22 16:07:23 -0800
commit0c3a579758362d5c713bb8ecc85ef82eccd56db0 (patch)
tree89b2e2e697d9375f06c7c90201186fd7b2dfa346 /fs/f2fs/node.c
parentd48dfc2073e31f76262204a4c8dc1c7da3834b7c (diff)
downloadlinux-0c3a579758362d5c713bb8ecc85ef82eccd56db0.tar.bz2
f2fs: introduce f2fs_submit_merged_bio_cond
f2fs use single bio buffer per type data (META/NODE/DATA) for caching writes locating in continuous block address as many as possible, after submitting, these writes may be still cached in bio buffer, so we have to flush cached writes in bio buffer by calling f2fs_submit_merged_bio. Unfortunately, in the scenario of high concurrency, bio buffer could be flushed by someone else before we submit it as below reasons: a) there is no space in bio buffer. b) add a request of different type (SYNC, ASYNC). c) add a discontinuous block address. For this condition, f2fs_submit_merged_bio will be devastating, because it could break the following merging of writes in bio buffer, split one big bio into two smaller one. This patch introduces f2fs_submit_merged_bio_cond which can do a conditional submitting with bio buffer, before submitting it will judge whether: - page in DATA type bio buffer is matching with specified page; - page in DATA type bio buffer is belong to specified inode; - page in NODE type bio buffer is belong to specified inode; If there is no eligible page in bio buffer, we will skip submitting step, result in gaining more chance to merge consecutive block IOs in bio cache. Signed-off-by: Chao Yu <chao2.yu@samsung.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/node.c')
-rw-r--r--fs/f2fs/node.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 511c0e7c3ae1..e08b8d5e8ca2 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1337,8 +1337,13 @@ continue_unlock:
goto next_step;
}
- if (wrote)
- f2fs_submit_merged_bio(sbi, NODE, WRITE);
+ if (wrote) {
+ if (ino)
+ f2fs_submit_merged_bio_cond(sbi, NULL, NULL,
+ ino, NODE, WRITE);
+ else
+ f2fs_submit_merged_bio(sbi, NODE, WRITE);
+ }
return nwritten;
}
@@ -1433,9 +1438,13 @@ static int f2fs_write_node_page(struct page *page,
set_node_addr(sbi, &ni, fio.blk_addr, is_fsync_dnode(page));
dec_page_count(sbi, F2FS_DIRTY_NODES);
up_read(&sbi->node_write);
+
+ if (wbc->for_reclaim)
+ f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, NODE, WRITE);
+
unlock_page(page);
- if (wbc->for_reclaim || unlikely(f2fs_cp_error(sbi)))
+ if (unlikely(f2fs_cp_error(sbi)))
f2fs_submit_merged_bio(sbi, NODE, WRITE);
return 0;