f2fs: support passing down write hints given by users to block layer
Add the 'whint_mode' mount option that controls which write hints are passed down to block layer. There are "off" and "user-based" mode. The default mode is "off". 1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET. 2) whint_mode=user-based. F2FS tries to pass down hints given by users. User F2FS Block ---- ---- ----- META WRITE_LIFE_NOT_SET HOT_NODE " WARM_NODE " COLD_NODE " ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME extension list " " -- buffered io WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET WRITE_LIFE_NONE " " WRITE_LIFE_MEDIUM " " WRITE_LIFE_LONG " " -- direct io WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET WRITE_LIFE_NONE " WRITE_LIFE_NONE WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM WRITE_LIFE_LONG " WRITE_LIFE_LONG Many thanks to Chao Yu and Jaegeuk Kim for comments to implement this patch. Signed-off-by: Hyunchul Lee <cheol.lee@lge.com> Reviewed-by: Chao Yu <yuchao0@huawei.com> [Jaegeuk Kim: avoid build warning] [Chao Yu: fix to restore whint_mode in ->remount_fs] Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:

committed by
Jaegeuk Kim

parent
cd36d7a17f
commit
0cdd319539
@@ -2456,6 +2456,62 @@ int rw_hint_to_seg_type(enum rw_hint hint)
|
||||
}
|
||||
}
|
||||
|
||||
/* This returns write hints for each segment type. This hints will be
|
||||
* passed down to block layer. There are mapping tables which depend on
|
||||
* the mount option 'whint_mode'.
|
||||
*
|
||||
* 1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET.
|
||||
*
|
||||
* 2) whint_mode=user-based. F2FS tries to pass down hints given by users.
|
||||
*
|
||||
* User F2FS Block
|
||||
* ---- ---- -----
|
||||
* META WRITE_LIFE_NOT_SET
|
||||
* HOT_NODE "
|
||||
* WARM_NODE "
|
||||
* COLD_NODE "
|
||||
* ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
|
||||
* extension list " "
|
||||
*
|
||||
* -- buffered io
|
||||
* WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
|
||||
* WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
|
||||
* WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
|
||||
* WRITE_LIFE_NONE " "
|
||||
* WRITE_LIFE_MEDIUM " "
|
||||
* WRITE_LIFE_LONG " "
|
||||
*
|
||||
* -- direct io
|
||||
* WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME
|
||||
* WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT
|
||||
* WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET
|
||||
* WRITE_LIFE_NONE " WRITE_LIFE_NONE
|
||||
* WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM
|
||||
* WRITE_LIFE_LONG " WRITE_LIFE_LONG
|
||||
*
|
||||
*/
|
||||
|
||||
enum rw_hint io_type_to_rw_hint(struct f2fs_sb_info *sbi,
|
||||
enum page_type type, enum temp_type temp)
|
||||
{
|
||||
if (sbi->whint_mode == WHINT_MODE_USER) {
|
||||
if (type == DATA) {
|
||||
switch (temp) {
|
||||
case COLD:
|
||||
return WRITE_LIFE_EXTREME;
|
||||
case HOT:
|
||||
return WRITE_LIFE_SHORT;
|
||||
default:
|
||||
return WRITE_LIFE_NOT_SET;
|
||||
}
|
||||
} else {
|
||||
return WRITE_LIFE_NOT_SET;
|
||||
}
|
||||
} else {
|
||||
return WRITE_LIFE_NOT_SET;
|
||||
}
|
||||
}
|
||||
|
||||
static int __get_segment_type_2(struct f2fs_io_info *fio)
|
||||
{
|
||||
if (fio->type == DATA)
|
||||
@@ -2643,6 +2699,7 @@ void write_meta_page(struct f2fs_sb_info *sbi, struct page *page,
|
||||
struct f2fs_io_info fio = {
|
||||
.sbi = sbi,
|
||||
.type = META,
|
||||
.temp = HOT,
|
||||
.op = REQ_OP_WRITE,
|
||||
.op_flags = REQ_SYNC | REQ_META | REQ_PRIO,
|
||||
.old_blkaddr = page->index,
|
||||
@@ -2691,6 +2748,8 @@ int rewrite_data_page(struct f2fs_io_info *fio)
|
||||
int err;
|
||||
|
||||
fio->new_blkaddr = fio->old_blkaddr;
|
||||
/* i/o temperature is needed for passing down write hints */
|
||||
__get_segment_type(fio);
|
||||
stat_inc_inplace_blocks(fio->sbi);
|
||||
|
||||
err = f2fs_submit_page_bio(fio);
|
||||
|
Reference in New Issue
Block a user