Commit 942fd319 authored by Jaegeuk Kim's avatar Jaegeuk Kim

f2fs: check last page index in cached bio to decide submission

If the cached bio has the last page's index, then we need to submit it.
Otherwise, we don't need to submit it and can wait for further IO merges.
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent d68f735b
...@@ -249,7 +249,8 @@ static int f2fs_write_meta_page(struct page *page, ...@@ -249,7 +249,8 @@ static int f2fs_write_meta_page(struct page *page,
dec_page_count(sbi, F2FS_DIRTY_META); dec_page_count(sbi, F2FS_DIRTY_META);
if (wbc->for_reclaim) if (wbc->for_reclaim)
f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, META, WRITE); f2fs_submit_merged_bio_cond(sbi, page->mapping->host,
0, page->index, META, WRITE);
unlock_page(page); unlock_page(page);
......
...@@ -243,8 +243,8 @@ static void __submit_merged_bio(struct f2fs_bio_info *io) ...@@ -243,8 +243,8 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
io->bio = NULL; io->bio = NULL;
} }
static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, static bool __has_merged_page(struct f2fs_bio_info *io,
struct page *page, nid_t ino) struct inode *inode, nid_t ino, pgoff_t idx)
{ {
struct bio_vec *bvec; struct bio_vec *bvec;
struct page *target; struct page *target;
...@@ -253,7 +253,7 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, ...@@ -253,7 +253,7 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
if (!io->bio) if (!io->bio)
return false; return false;
if (!inode && !page && !ino) if (!inode && !ino)
return true; return true;
bio_for_each_segment_all(bvec, io->bio, i) { bio_for_each_segment_all(bvec, io->bio, i) {
...@@ -263,10 +263,11 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, ...@@ -263,10 +263,11 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
else else
target = fscrypt_control_page(bvec->bv_page); target = fscrypt_control_page(bvec->bv_page);
if (idx != target->index)
continue;
if (inode && inode == target->mapping->host) if (inode && inode == target->mapping->host)
return true; return true;
if (page && page == target)
return true;
if (ino && ino == ino_of_node(target)) if (ino && ino == ino_of_node(target))
return true; return true;
} }
...@@ -275,22 +276,21 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, ...@@ -275,22 +276,21 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
} }
static bool has_merged_page(struct f2fs_sb_info *sbi, struct inode *inode, static bool has_merged_page(struct f2fs_sb_info *sbi, struct inode *inode,
struct page *page, nid_t ino, nid_t ino, pgoff_t idx, enum page_type type)
enum page_type type)
{ {
enum page_type btype = PAGE_TYPE_OF_BIO(type); enum page_type btype = PAGE_TYPE_OF_BIO(type);
struct f2fs_bio_info *io = &sbi->write_io[btype]; struct f2fs_bio_info *io = &sbi->write_io[btype];
bool ret; bool ret;
down_read(&io->io_rwsem); down_read(&io->io_rwsem);
ret = __has_merged_page(io, inode, page, ino); ret = __has_merged_page(io, inode, ino, idx);
up_read(&io->io_rwsem); up_read(&io->io_rwsem);
return ret; return ret;
} }
static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
struct inode *inode, struct page *page, struct inode *inode, nid_t ino, pgoff_t idx,
nid_t ino, enum page_type type, int rw) enum page_type type, int rw)
{ {
enum page_type btype = PAGE_TYPE_OF_BIO(type); enum page_type btype = PAGE_TYPE_OF_BIO(type);
struct f2fs_bio_info *io; struct f2fs_bio_info *io;
...@@ -299,7 +299,7 @@ static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, ...@@ -299,7 +299,7 @@ static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
down_write(&io->io_rwsem); down_write(&io->io_rwsem);
if (!__has_merged_page(io, inode, page, ino)) if (!__has_merged_page(io, inode, ino, idx))
goto out; goto out;
/* change META to META_FLUSH in the checkpoint procedure */ /* change META to META_FLUSH in the checkpoint procedure */
...@@ -318,15 +318,15 @@ static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, ...@@ -318,15 +318,15 @@ static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type, void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type,
int rw) int rw)
{ {
__f2fs_submit_merged_bio(sbi, NULL, NULL, 0, type, rw); __f2fs_submit_merged_bio(sbi, NULL, 0, 0, type, rw);
} }
void f2fs_submit_merged_bio_cond(struct f2fs_sb_info *sbi, void f2fs_submit_merged_bio_cond(struct f2fs_sb_info *sbi,
struct inode *inode, struct page *page, struct inode *inode, nid_t ino, pgoff_t idx,
nid_t ino, enum page_type type, int rw) enum page_type type, int rw)
{ {
if (has_merged_page(sbi, inode, page, ino, type)) if (has_merged_page(sbi, inode, ino, idx, type))
__f2fs_submit_merged_bio(sbi, inode, page, ino, type, rw); __f2fs_submit_merged_bio(sbi, inode, ino, idx, type, rw);
} }
void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi) void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi)
...@@ -1432,7 +1432,8 @@ static int __write_data_page(struct page *page, bool *submitted, ...@@ -1432,7 +1432,8 @@ static int __write_data_page(struct page *page, bool *submitted,
ClearPageUptodate(page); ClearPageUptodate(page);
if (wbc->for_reclaim) { if (wbc->for_reclaim) {
f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, DATA, WRITE); f2fs_submit_merged_bio_cond(sbi, inode, 0, page->index,
DATA, WRITE);
remove_dirty_inode(inode); remove_dirty_inode(inode);
submitted = NULL; submitted = NULL;
} }
...@@ -1480,10 +1481,10 @@ static int f2fs_write_cache_pages(struct address_space *mapping, ...@@ -1480,10 +1481,10 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
pgoff_t index; pgoff_t index;
pgoff_t end; /* Inclusive */ pgoff_t end; /* Inclusive */
pgoff_t done_index; pgoff_t done_index;
pgoff_t last_idx = ULONG_MAX;
int cycled; int cycled;
int range_whole = 0; int range_whole = 0;
int tag; int tag;
int nwritten = 0;
pagevec_init(&pvec, 0); pagevec_init(&pvec, 0);
...@@ -1569,7 +1570,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping, ...@@ -1569,7 +1570,7 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
done = 1; done = 1;
break; break;
} else if (submitted) { } else if (submitted) {
nwritten++; last_idx = page->index;
} }
if (--wbc->nr_to_write <= 0 && if (--wbc->nr_to_write <= 0 &&
...@@ -1591,9 +1592,9 @@ static int f2fs_write_cache_pages(struct address_space *mapping, ...@@ -1591,9 +1592,9 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
mapping->writeback_index = done_index; mapping->writeback_index = done_index;
if (nwritten) if (last_idx != ULONG_MAX)
f2fs_submit_merged_bio_cond(F2FS_M_SB(mapping), mapping->host, f2fs_submit_merged_bio_cond(F2FS_M_SB(mapping), mapping->host,
NULL, 0, DATA, WRITE); 0, last_idx, DATA, WRITE);
return ret; return ret;
} }
......
...@@ -2233,8 +2233,8 @@ void destroy_checkpoint_caches(void); ...@@ -2233,8 +2233,8 @@ void destroy_checkpoint_caches(void);
void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type, void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type,
int rw); int rw);
void f2fs_submit_merged_bio_cond(struct f2fs_sb_info *sbi, void f2fs_submit_merged_bio_cond(struct f2fs_sb_info *sbi,
struct inode *inode, struct page *page, struct inode *inode, nid_t ino, pgoff_t idx,
nid_t ino, enum page_type type, int rw); enum page_type type, int rw);
void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi); void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi);
int f2fs_submit_page_bio(struct f2fs_io_info *fio); int f2fs_submit_page_bio(struct f2fs_io_info *fio);
int f2fs_submit_page_mbio(struct f2fs_io_info *fio); int f2fs_submit_page_mbio(struct f2fs_io_info *fio);
......
...@@ -1374,7 +1374,8 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, ...@@ -1374,7 +1374,8 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
up_read(&sbi->node_write); up_read(&sbi->node_write);
if (wbc->for_reclaim) { if (wbc->for_reclaim) {
f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, NODE, WRITE); f2fs_submit_merged_bio_cond(sbi, page->mapping->host, 0,
page->index, NODE, WRITE);
submitted = NULL; submitted = NULL;
} }
...@@ -1404,12 +1405,12 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, ...@@ -1404,12 +1405,12 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
struct writeback_control *wbc, bool atomic) struct writeback_control *wbc, bool atomic)
{ {
pgoff_t index, end; pgoff_t index, end;
pgoff_t last_idx = ULONG_MAX;
struct pagevec pvec; struct pagevec pvec;
int ret = 0; int ret = 0;
struct page *last_page = NULL; struct page *last_page = NULL;
bool marked = false; bool marked = false;
nid_t ino = inode->i_ino; nid_t ino = inode->i_ino;
int nwritten = 0;
if (atomic) { if (atomic) {
last_page = last_fsync_dnode(sbi, ino); last_page = last_fsync_dnode(sbi, ino);
...@@ -1488,7 +1489,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, ...@@ -1488,7 +1489,7 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
f2fs_put_page(last_page, 0); f2fs_put_page(last_page, 0);
break; break;
} else if (submitted) { } else if (submitted) {
nwritten++; last_idx = page->index;
} }
if (page == last_page) { if (page == last_page) {
...@@ -1514,8 +1515,9 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, ...@@ -1514,8 +1515,9 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
goto retry; goto retry;
} }
out: out:
if (nwritten) if (last_idx != ULONG_MAX)
f2fs_submit_merged_bio_cond(sbi, NULL, NULL, ino, NODE, WRITE); f2fs_submit_merged_bio_cond(sbi, NULL, ino, last_idx,
NODE, WRITE);
return ret ? -EIO: 0; return ret ? -EIO: 0;
} }
......
...@@ -263,7 +263,7 @@ static int __commit_inmem_pages(struct inode *inode, ...@@ -263,7 +263,7 @@ static int __commit_inmem_pages(struct inode *inode,
.op_flags = REQ_SYNC | REQ_PRIO, .op_flags = REQ_SYNC | REQ_PRIO,
.encrypted_page = NULL, .encrypted_page = NULL,
}; };
bool submit_bio = false; pgoff_t last_idx = ULONG_MAX;
int err = 0; int err = 0;
list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) { list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) {
...@@ -289,15 +289,15 @@ static int __commit_inmem_pages(struct inode *inode, ...@@ -289,15 +289,15 @@ static int __commit_inmem_pages(struct inode *inode,
/* record old blkaddr for revoking */ /* record old blkaddr for revoking */
cur->old_addr = fio.old_blkaddr; cur->old_addr = fio.old_blkaddr;
last_idx = page->index;
submit_bio = true;
} }
unlock_page(page); unlock_page(page);
list_move_tail(&cur->list, revoke_list); list_move_tail(&cur->list, revoke_list);
} }
if (submit_bio) if (last_idx != ULONG_MAX)
f2fs_submit_merged_bio_cond(sbi, inode, NULL, 0, DATA, WRITE); f2fs_submit_merged_bio_cond(sbi, inode, 0, last_idx,
DATA, WRITE);
if (!err) if (!err)
__revoke_inmem_pages(inode, revoke_list, false, false); __revoke_inmem_pages(inode, revoke_list, false, false);
...@@ -1932,7 +1932,8 @@ void f2fs_wait_on_page_writeback(struct page *page, ...@@ -1932,7 +1932,8 @@ void f2fs_wait_on_page_writeback(struct page *page,
if (PageWriteback(page)) { if (PageWriteback(page)) {
struct f2fs_sb_info *sbi = F2FS_P_SB(page); struct f2fs_sb_info *sbi = F2FS_P_SB(page);
f2fs_submit_merged_bio_cond(sbi, NULL, page, 0, type, WRITE); f2fs_submit_merged_bio_cond(sbi, page->mapping->host,
0, page->index, type, WRITE);
if (ordered) if (ordered)
wait_on_page_writeback(page); wait_on_page_writeback(page);
else else
......
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