f2fs: introduce f2fs_submit_merged_bio_cond
PATCH 2/2 f2fs: introduce f2fs_submit_merged_bio_cond
f2fs use single bio buffer for each META/NODE/DATA type data for caching writes which have continuous block address as many as possible, after submitting blocks, sometimes, the blocks are 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 will could be flushed by someone else as below reasons:
a) there is no space in bio buffer.
b) user add a request of different type (SYNC, ASYNC).
c) user 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, splitting one big bio into two smaller one.
This patch introduces f2fs_submit_merged_bio_cond which can do a conditional submitting with bio buffer, it will judge whether:
- page in DATA type bio buffer is matched 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. So that result in gaining more chance to merge consecutive block IOs in bio cache.
--- fs/f2fs/checkpoint.c | 7 ++++- fs/f2fs/data.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++---- fs/f2fs/f2fs.h | 2 ++ fs/f2fs/node.c | 15 +++++++-- fs/f2fs/segment.c | 44 ++------------------------ 5 files changed, 105 insertions(+), 51 deletions(-)
fs/f2fs/checkpoint.c +6 -1
@@ -235,10 +235,15 @@ static int f2fs_write_meta_page(struct page *page,f2fs_wait_on_page_writeback (page,META );write_meta_page (sbi, page);dec_page_count (sbi,F2FS_DIRTY_META ); + +if (wbc->for_reclaim) +f2fs_submit_merged_bio_cond (sbi,NULL , page,0 ,META ,WRITE ); +unlock_page (page); -if (wbc->for_reclaim ||unlikely (f2fs_cp_error (sbi))) +if (unlikely (f2fs_cp_error (sbi)))f2fs_submit_merged_bio (sbi,META ,WRITE ); +return 0 ; redirty_out:
fs/f2fs/data.c +82 -6
124 lines not on this page · raw message
fs/f2fs/f2fs.h +2 -0
@@ -1883,6 +1883,8 @@ void destroy_checkpoint_caches(void);* data.c */ void f2fs_submit_merged_bio (struct f2fs_sb_info *,enum page_type ,int ); +void f2fs_submit_merged_bio_cond (struct f2fs_sb_info *,struct inode *, +struct page *,nid_t ,enum page_type ,int );int f2fs_submit_page_bio (struct f2fs_io_info *);void f2fs_submit_page_mbio (struct f2fs_io_info *);void set_data_blkaddr (struct dnode_of_data *);
fs/f2fs/node.c +12 -3
@@ -1258,8 +1258,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; }
@@ -1356,9 +1361,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 ;
fs/f2fs/segment.c +3 -41
62 lines not on this page · raw message
Signature · 1 line
2.6.3