|
@@ -282,27 +282,32 @@ static bool has_merged_page(struct f2fs_sb_info *sbi, struct inode *inode,
|
|
|
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;
|
|
|
+ enum temp_type temp;
|
|
|
+ struct f2fs_bio_info *io;
|
|
|
+ bool ret = false;
|
|
|
|
|
|
- down_read(&io->io_rwsem);
|
|
|
- ret = __has_merged_page(io, inode, ino, idx);
|
|
|
- up_read(&io->io_rwsem);
|
|
|
+ for (temp = HOT; temp < NR_TEMP_TYPE; temp++) {
|
|
|
+ io = sbi->write_io[btype] + temp;
|
|
|
+
|
|
|
+ down_read(&io->io_rwsem);
|
|
|
+ ret = __has_merged_page(io, inode, ino, idx);
|
|
|
+ up_read(&io->io_rwsem);
|
|
|
+
|
|
|
+ /* TODO: use HOT temp only for meta pages now. */
|
|
|
+ if (ret || btype == META)
|
|
|
+ break;
|
|
|
+ }
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
static void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi,
|
|
|
- struct inode *inode, nid_t ino, pgoff_t idx,
|
|
|
- enum page_type type)
|
|
|
+ enum page_type type, enum temp_type temp)
|
|
|
{
|
|
|
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] + temp;
|
|
|
|
|
|
down_write(&io->io_rwsem);
|
|
|
|
|
|
- if (!__has_merged_page(io, inode, ino, idx))
|
|
|
- goto out;
|
|
|
-
|
|
|
/* change META to META_FLUSH in the checkpoint procedure */
|
|
|
if (type >= META_FLUSH) {
|
|
|
io->fio.type = META_FLUSH;
|
|
@@ -312,21 +317,38 @@ static void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi,
|
|
|
io->fio.op_flags |= REQ_PREFLUSH | REQ_FUA;
|
|
|
}
|
|
|
__submit_merged_bio(io);
|
|
|
-out:
|
|
|
up_write(&io->io_rwsem);
|
|
|
}
|
|
|
|
|
|
+static void __submit_merged_write_cond(struct f2fs_sb_info *sbi,
|
|
|
+ struct inode *inode, nid_t ino, pgoff_t idx,
|
|
|
+ enum page_type type, bool force)
|
|
|
+{
|
|
|
+ enum temp_type temp;
|
|
|
+
|
|
|
+ if (!force && !has_merged_page(sbi, inode, ino, idx, type))
|
|
|
+ return;
|
|
|
+
|
|
|
+ for (temp = HOT; temp < NR_TEMP_TYPE; temp++) {
|
|
|
+
|
|
|
+ __f2fs_submit_merged_write(sbi, type, temp);
|
|
|
+
|
|
|
+ /* TODO: use HOT temp only for meta pages now. */
|
|
|
+ if (type >= META)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type)
|
|
|
{
|
|
|
- __f2fs_submit_merged_write(sbi, NULL, 0, 0, type);
|
|
|
+ __submit_merged_write_cond(sbi, NULL, 0, 0, type, true);
|
|
|
}
|
|
|
|
|
|
void f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi,
|
|
|
struct inode *inode, nid_t ino, pgoff_t idx,
|
|
|
enum page_type type)
|
|
|
{
|
|
|
- if (has_merged_page(sbi, inode, ino, idx, type))
|
|
|
- __f2fs_submit_merged_write(sbi, inode, ino, idx, type);
|
|
|
+ __submit_merged_write_cond(sbi, inode, ino, idx, type, false);
|
|
|
}
|
|
|
|
|
|
void f2fs_flush_merged_writes(struct f2fs_sb_info *sbi)
|
|
@@ -369,7 +391,7 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
|
|
|
{
|
|
|
struct f2fs_sb_info *sbi = fio->sbi;
|
|
|
enum page_type btype = PAGE_TYPE_OF_BIO(fio->type);
|
|
|
- struct f2fs_bio_info *io = &sbi->write_io[btype];
|
|
|
+ struct f2fs_bio_info *io = sbi->write_io[btype] + fio->temp;
|
|
|
struct page *bio_page;
|
|
|
int err = 0;
|
|
|
|
|
@@ -405,8 +427,7 @@ alloc_new:
|
|
|
io->fio = *fio;
|
|
|
}
|
|
|
|
|
|
- if (bio_add_page(io->bio, bio_page, PAGE_SIZE, 0) <
|
|
|
- PAGE_SIZE) {
|
|
|
+ if (bio_add_page(io->bio, bio_page, PAGE_SIZE, 0) < PAGE_SIZE) {
|
|
|
__submit_merged_bio(io);
|
|
|
goto alloc_new;
|
|
|
}
|