1
0
Fork 0

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: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
hifive-unleashed-5.1
Jaegeuk Kim 2017-02-01 16:51:22 -08:00
parent d68f735b3b
commit 942fd3192f
5 changed files with 40 additions and 35 deletions

View File

@ -249,7 +249,8 @@ static int f2fs_write_meta_page(struct page *page,
dec_page_count(sbi, F2FS_DIRTY_META);
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);

View File

@ -243,8 +243,8 @@ static void __submit_merged_bio(struct f2fs_bio_info *io)
io->bio = NULL;
}
static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
struct page *page, nid_t ino)
static bool __has_merged_page(struct f2fs_bio_info *io,
struct inode *inode, nid_t ino, pgoff_t idx)
{
struct bio_vec *bvec;
struct page *target;
@ -253,7 +253,7 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode,
if (!io->bio)
return false;
if (!inode && !page && !ino)
if (!inode && !ino)
return true;
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,
else
target = fscrypt_control_page(bvec->bv_page);
if (idx != target->index)
continue;
if (inode && inode == target->mapping->host)
return true;
if (page && page == target)
return true;
if (ino && ino == ino_of_node(target))
return true;
}
@ -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,
struct page *page, nid_t ino,
enum page_type type)
nid_t ino, pgoff_t idx, enum page_type type)
{
enum page_type btype = PAGE_TYPE_OF_BIO(type);
struct f2fs_bio_info *io = &sbi->write_io[btype];
bool ret;
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);
return ret;
}
static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
struct inode *inode, struct page *page,
nid_t ino, enum page_type type, int rw)
struct inode *inode, nid_t ino, pgoff_t idx,
enum page_type type, int rw)
{
enum page_type btype = PAGE_TYPE_OF_BIO(type);
struct f2fs_bio_info *io;
@ -299,7 +299,7 @@ static void __f2fs_submit_merged_bio(struct f2fs_sb_info *sbi,
down_write(&io->io_rwsem);
if (!__has_merged_page(io, inode, page, ino))
if (!__has_merged_page(io, inode, ino, idx))
goto out;
/* change META to META_FLUSH in the checkpoint procedure */
@ -318,15 +318,15 @@ out:
void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type,
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,
struct inode *inode, struct page *page,
nid_t ino, enum page_type type, int rw)
struct inode *inode, nid_t ino, pgoff_t idx,
enum page_type type, int rw)
{
if (has_merged_page(sbi, inode, page, ino, type))
__f2fs_submit_merged_bio(sbi, inode, page, ino, type, rw);
if (has_merged_page(sbi, inode, ino, idx, type))
__f2fs_submit_merged_bio(sbi, inode, ino, idx, type, rw);
}
void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi)
@ -1432,7 +1432,8 @@ out:
ClearPageUptodate(page);
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);
submitted = NULL;
}
@ -1480,10 +1481,10 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
pgoff_t index;
pgoff_t end; /* Inclusive */
pgoff_t done_index;
pgoff_t last_idx = ULONG_MAX;
int cycled;
int range_whole = 0;
int tag;
int nwritten = 0;
pagevec_init(&pvec, 0);
@ -1569,7 +1570,7 @@ continue_unlock:
done = 1;
break;
} else if (submitted) {
nwritten++;
last_idx = page->index;
}
if (--wbc->nr_to_write <= 0 &&
@ -1591,9 +1592,9 @@ continue_unlock:
if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
mapping->writeback_index = done_index;
if (nwritten)
if (last_idx != ULONG_MAX)
f2fs_submit_merged_bio_cond(F2FS_M_SB(mapping), mapping->host,
NULL, 0, DATA, WRITE);
0, last_idx, DATA, WRITE);
return ret;
}

View File

@ -2233,8 +2233,8 @@ void destroy_checkpoint_caches(void);
void f2fs_submit_merged_bio(struct f2fs_sb_info *sbi, enum page_type type,
int rw);
void f2fs_submit_merged_bio_cond(struct f2fs_sb_info *sbi,
struct inode *inode, struct page *page,
nid_t ino, enum page_type type, int rw);
struct inode *inode, nid_t ino, pgoff_t idx,
enum page_type type, int rw);
void f2fs_flush_merged_bios(struct f2fs_sb_info *sbi);
int f2fs_submit_page_bio(struct f2fs_io_info *fio);
int f2fs_submit_page_mbio(struct f2fs_io_info *fio);

View File

@ -1374,7 +1374,8 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted,
up_read(&sbi->node_write);
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;
}
@ -1404,12 +1405,12 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
struct writeback_control *wbc, bool atomic)
{
pgoff_t index, end;
pgoff_t last_idx = ULONG_MAX;
struct pagevec pvec;
int ret = 0;
struct page *last_page = NULL;
bool marked = false;
nid_t ino = inode->i_ino;
int nwritten = 0;
if (atomic) {
last_page = last_fsync_dnode(sbi, ino);
@ -1488,7 +1489,7 @@ continue_unlock:
f2fs_put_page(last_page, 0);
break;
} else if (submitted) {
nwritten++;
last_idx = page->index;
}
if (page == last_page) {
@ -1514,8 +1515,9 @@ continue_unlock:
goto retry;
}
out:
if (nwritten)
f2fs_submit_merged_bio_cond(sbi, NULL, NULL, ino, NODE, WRITE);
if (last_idx != ULONG_MAX)
f2fs_submit_merged_bio_cond(sbi, NULL, ino, last_idx,
NODE, WRITE);
return ret ? -EIO: 0;
}

View File

@ -263,7 +263,7 @@ static int __commit_inmem_pages(struct inode *inode,
.op_flags = REQ_SYNC | REQ_PRIO,
.encrypted_page = NULL,
};
bool submit_bio = false;
pgoff_t last_idx = ULONG_MAX;
int err = 0;
list_for_each_entry_safe(cur, tmp, &fi->inmem_pages, list) {
@ -289,15 +289,15 @@ static int __commit_inmem_pages(struct inode *inode,
/* record old blkaddr for revoking */
cur->old_addr = fio.old_blkaddr;
submit_bio = true;
last_idx = page->index;
}
unlock_page(page);
list_move_tail(&cur->list, revoke_list);
}
if (submit_bio)
f2fs_submit_merged_bio_cond(sbi, inode, NULL, 0, DATA, WRITE);
if (last_idx != ULONG_MAX)
f2fs_submit_merged_bio_cond(sbi, inode, 0, last_idx,
DATA, WRITE);
if (!err)
__revoke_inmem_pages(inode, revoke_list, false, false);
@ -1932,7 +1932,8 @@ void f2fs_wait_on_page_writeback(struct page *page,
if (PageWriteback(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)
wait_on_page_writeback(page);
else