Skip to content

Commit 7643f3f

Browse files
author
Jaegeuk Kim
committed
f2fs: assign the write hint per stream by default
This reverts commit 930e260 ("f2fs: remove obsolete whint_mode"), as we decide to pass write hints to the disk. Cc: Hyunchul Lee <cheol.lee@lge.com> Signed-off-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent b2cf5a1 commit 7643f3f

5 files changed

Lines changed: 118 additions & 7 deletions

File tree

Documentation/filesystems/f2fs.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,35 @@ In order to identify whether the data in the victim segment are valid or not,
774774
F2FS manages a bitmap. Each bit represents the validity of a block, and the
775775
bitmap is composed of a bit stream covering whole blocks in main area.
776776

777+
Write-hint Policy
778+
-----------------
779+
780+
F2FS sets the whint all the time with the below policy.
781+
782+
===================== ======================== ===================
783+
User F2FS Block
784+
===================== ======================== ===================
785+
N/A META WRITE_LIFE_NONE|REQ_META
786+
N/A HOT_NODE WRITE_LIFE_NONE
787+
N/A WARM_NODE WRITE_LIFE_MEDIUM
788+
N/A COLD_NODE WRITE_LIFE_LONG
789+
ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
790+
extension list " "
791+
792+
-- buffered io
793+
N/A COLD_DATA WRITE_LIFE_EXTREME
794+
N/A HOT_DATA WRITE_LIFE_SHORT
795+
N/A WARM_DATA WRITE_LIFE_NOT_SET
796+
797+
-- direct io
798+
WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
799+
WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
800+
WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
801+
WRITE_LIFE_NONE " WRITE_LIFE_NONE
802+
WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM
803+
WRITE_LIFE_LONG " WRITE_LIFE_LONG
804+
===================== ======================== ===================
805+
777806
Fallocate(2) Policy
778807
-------------------
779808

fs/f2fs/data.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,8 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
465465
} else {
466466
bio->bi_end_io = f2fs_write_end_io;
467467
bio->bi_private = sbi;
468+
bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi,
469+
fio->type, fio->temp);
468470
}
469471
iostat_alloc_and_bind_ctx(sbi, bio, NULL);
470472

fs/f2fs/f2fs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3722,6 +3722,7 @@ void f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
37223722
block_t old_addr, block_t new_addr,
37233723
unsigned char version, bool recover_curseg,
37243724
bool recover_newaddr);
3725+
int f2fs_get_segment_temp(int seg_type);
37253726
int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
37263727
block_t old_blkaddr, block_t *new_blkaddr,
37273728
struct f2fs_summary *sum, int type,
@@ -3745,6 +3746,8 @@ void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi);
37453746
int __init f2fs_create_segment_manager_caches(void);
37463747
void f2fs_destroy_segment_manager_caches(void);
37473748
int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
3749+
enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
3750+
enum page_type type, enum temp_type temp);
37483751
unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
37493752
unsigned int segno);
37503753
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,

fs/f2fs/file.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4685,8 +4685,21 @@ static int f2fs_dio_write_end_io(struct kiocb *iocb, ssize_t size, int error,
46854685
return 0;
46864686
}
46874687

4688+
static void f2fs_dio_write_submit_io(const struct iomap_iter *iter,
4689+
struct bio *bio, loff_t file_offset)
4690+
{
4691+
struct inode *inode = iter->inode;
4692+
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
4693+
int seg_type = f2fs_rw_hint_to_seg_type(inode->i_write_hint);
4694+
enum temp_type temp = f2fs_get_segment_temp(seg_type);
4695+
4696+
bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, DATA, temp);
4697+
submit_bio(bio);
4698+
}
4699+
46884700
static const struct iomap_dio_ops f2fs_iomap_dio_write_ops = {
4689-
.end_io = f2fs_dio_write_end_io,
4701+
.end_io = f2fs_dio_write_end_io,
4702+
.submit_io = f2fs_dio_write_submit_io,
46904703
};
46914704

46924705
static void f2fs_flush_buffered_write(struct address_space *mapping,

fs/f2fs/segment.c

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3364,6 +3364,65 @@ int f2fs_rw_hint_to_seg_type(enum rw_hint hint)
33643364
}
33653365
}
33663366

3367+
/*
3368+
* This returns write hints for each segment type. This hints will be
3369+
* passed down to block layer as below by default.
3370+
*
3371+
* User F2FS Block
3372+
* ---- ---- -----
3373+
* META WRITE_LIFE_NONE|REQ_META
3374+
* HOT_NODE WRITE_LIFE_NONE
3375+
* WARM_NODE WRITE_LIFE_MEDIUM
3376+
* COLD_NODE WRITE_LIFE_LONG
3377+
* ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
3378+
* extension list " "
3379+
*
3380+
* -- buffered io
3381+
* COLD_DATA WRITE_LIFE_EXTREME
3382+
* HOT_DATA WRITE_LIFE_SHORT
3383+
* WARM_DATA WRITE_LIFE_NOT_SET
3384+
*
3385+
* -- direct io
3386+
* WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
3387+
* WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
3388+
* WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
3389+
* WRITE_LIFE_NONE " WRITE_LIFE_NONE
3390+
* WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM
3391+
* WRITE_LIFE_LONG " WRITE_LIFE_LONG
3392+
*/
3393+
enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
3394+
enum page_type type, enum temp_type temp)
3395+
{
3396+
switch (type) {
3397+
case DATA:
3398+
switch (temp) {
3399+
case WARM:
3400+
return WRITE_LIFE_NOT_SET;
3401+
case HOT:
3402+
return WRITE_LIFE_SHORT;
3403+
case COLD:
3404+
return WRITE_LIFE_EXTREME;
3405+
default:
3406+
return WRITE_LIFE_NONE;
3407+
}
3408+
case NODE:
3409+
switch (temp) {
3410+
case WARM:
3411+
return WRITE_LIFE_MEDIUM;
3412+
case HOT:
3413+
return WRITE_LIFE_NONE;
3414+
case COLD:
3415+
return WRITE_LIFE_LONG;
3416+
default:
3417+
return WRITE_LIFE_NONE;
3418+
}
3419+
case META:
3420+
return WRITE_LIFE_NONE;
3421+
default:
3422+
return WRITE_LIFE_NONE;
3423+
}
3424+
}
3425+
33673426
static int __get_segment_type_2(struct f2fs_io_info *fio)
33683427
{
33693428
if (fio->type == DATA)
@@ -3443,6 +3502,15 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
34433502
}
34443503
}
34453504

3505+
int f2fs_get_segment_temp(int seg_type)
3506+
{
3507+
if (IS_HOT(seg_type))
3508+
return HOT;
3509+
else if (IS_WARM(seg_type))
3510+
return WARM;
3511+
return COLD;
3512+
}
3513+
34463514
static int __get_segment_type(struct f2fs_io_info *fio)
34473515
{
34483516
int type = 0;
@@ -3461,12 +3529,8 @@ static int __get_segment_type(struct f2fs_io_info *fio)
34613529
f2fs_bug_on(fio->sbi, true);
34623530
}
34633531

3464-
if (IS_HOT(type))
3465-
fio->temp = HOT;
3466-
else if (IS_WARM(type))
3467-
fio->temp = WARM;
3468-
else
3469-
fio->temp = COLD;
3532+
fio->temp = f2fs_get_segment_temp(type);
3533+
34703534
return type;
34713535
}
34723536

0 commit comments

Comments
 (0)