Bio flags like REQ_PRIO, REQ_META, and REQ_FUA, determined by f2fs_io_flags(), were not being applied to direct I/O (DIO) writes. This meant that DIO writes would not respect filesystem-level hints (for REQ_META/FUA) or inode-level hints (like F2FS_IOPRIO_WRITE).
This patch refactors f2fs_io_flags() to use a direct inode pointer instead of deriving it from a page. The function is then called from the DIO write path, ensuring that bio flags are handled consistently for both buffered and DIO writes. Signed-off-by: Daniel Lee <chul...@google.com> --- fs/f2fs/data.c | 8 ++++---- fs/f2fs/f2fs.h | 2 ++ fs/f2fs/file.c | 12 ++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 31e892842625..966cea75874c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -416,10 +416,9 @@ int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr) return 0; } -static blk_opf_t f2fs_io_flags(struct f2fs_io_info *fio) +blk_opf_t f2fs_io_flags(struct f2fs_io_info *fio) { unsigned int temp_mask = GENMASK(NR_TEMP_TYPE - 1, 0); - struct folio *fio_folio = page_folio(fio->page); unsigned int fua_flag, meta_flag, io_flag; blk_opf_t op_flags = 0; @@ -446,8 +445,8 @@ static blk_opf_t f2fs_io_flags(struct f2fs_io_info *fio) if (BIT(fio->temp) & fua_flag) op_flags |= REQ_FUA; - if (fio->type == DATA && - F2FS_I(fio_folio->mapping->host)->ioprio_hint == F2FS_IOPRIO_WRITE) + if (fio->inode && fio->type == DATA && + F2FS_I(fio->inode)->ioprio_hint == F2FS_IOPRIO_WRITE) op_flags |= REQ_PRIO; return op_flags; @@ -2783,6 +2782,7 @@ int f2fs_write_single_data_page(struct folio *folio, int *submitted, int err = 0; struct f2fs_io_info fio = { .sbi = sbi, + .inode = inode, .ino = inode->i_ino, .type = DATA, .op = REQ_OP_WRITE, diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9333a22b9a01..162d79a3c1a5 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1233,6 +1233,7 @@ enum iostat_type { struct f2fs_io_info { struct f2fs_sb_info *sbi; /* f2fs_sb_info pointer */ + struct inode *inode; nid_t ino; /* inode number */ enum page_type type; /* contains DATA/NODE/META/META_FLUSH */ enum temp_type temp; /* contains HOT/WARM/COLD */ @@ -3972,6 +3973,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio); struct block_device *f2fs_target_device(struct f2fs_sb_info *sbi, block_t blk_addr, sector_t *sector); int f2fs_target_device_index(struct f2fs_sb_info *sbi, block_t blkaddr); +blk_opf_t f2fs_io_flags(struct f2fs_io_info *fio); void f2fs_set_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr); void f2fs_update_data_blkaddr(struct dnode_of_data *dn, block_t blkaddr); int f2fs_reserve_new_blocks(struct dnode_of_data *dn, blkcnt_t count); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 696131e655ed..4fd45e94661a 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -5015,6 +5015,18 @@ static void f2fs_dio_write_submit_io(const struct iomap_iter *iter, enum log_type type = f2fs_rw_hint_to_seg_type(sbi, inode->i_write_hint); enum temp_type temp = f2fs_get_segment_temp(sbi, type); + /* if fadvise set to hot, override the temperature */ + struct f2fs_io_info fio = { + .sbi = sbi, + .inode = inode, + .type = DATA, + .op = REQ_OP_WRITE, + .temp = file_is_hot(inode) ? HOT : temp, + .op_flags = bio->bi_opf, + .page = NULL, + }; + bio->bi_opf |= f2fs_io_flags(&fio); + bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, DATA, temp); submit_bio(bio); } -- 2.50.0.rc1.591.g9c95f17f64-goog _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel