mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 02:36:02 +00:00
f2fs: assign the write hint per stream by default
This reverts commit 930e260763
("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>
This commit is contained in:
parent
b2cf5a1ff2
commit
7643f3fe27
@ -774,6 +774,35 @@ In order to identify whether the data in the victim segment are valid or not,
|
||||
F2FS manages a bitmap. Each bit represents the validity of a block, and the
|
||||
bitmap is composed of a bit stream covering whole blocks in main area.
|
||||
|
||||
Write-hint Policy
|
||||
-----------------
|
||||
|
||||
F2FS sets the whint all the time with the below policy.
|
||||
|
||||
===================== ======================== ===================
|
||||
User F2FS Block
|
||||
===================== ======================== ===================
|
||||
N/A META WRITE_LIFE_NONE|REQ_META
|
||||
N/A HOT_NODE WRITE_LIFE_NONE
|
||||
N/A WARM_NODE WRITE_LIFE_MEDIUM
|
||||
N/A COLD_NODE WRITE_LIFE_LONG
|
||||
ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
|
||||
extension list " "
|
||||
|
||||
-- buffered io
|
||||
N/A COLD_DATA WRITE_LIFE_EXTREME
|
||||
N/A HOT_DATA WRITE_LIFE_SHORT
|
||||
N/A WARM_DATA WRITE_LIFE_NOT_SET
|
||||
|
||||
-- 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
|
||||
===================== ======================== ===================
|
||||
|
||||
Fallocate(2) Policy
|
||||
-------------------
|
||||
|
||||
|
@ -465,6 +465,8 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
|
||||
} else {
|
||||
bio->bi_end_io = f2fs_write_end_io;
|
||||
bio->bi_private = sbi;
|
||||
bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi,
|
||||
fio->type, fio->temp);
|
||||
}
|
||||
iostat_alloc_and_bind_ctx(sbi, bio, NULL);
|
||||
|
||||
|
@ -3722,6 +3722,7 @@ void f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn,
|
||||
block_t old_addr, block_t new_addr,
|
||||
unsigned char version, bool recover_curseg,
|
||||
bool recover_newaddr);
|
||||
int f2fs_get_segment_temp(int seg_type);
|
||||
int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
|
||||
block_t old_blkaddr, block_t *new_blkaddr,
|
||||
struct f2fs_summary *sum, int type,
|
||||
@ -3745,6 +3746,8 @@ void f2fs_destroy_segment_manager(struct f2fs_sb_info *sbi);
|
||||
int __init f2fs_create_segment_manager_caches(void);
|
||||
void f2fs_destroy_segment_manager_caches(void);
|
||||
int f2fs_rw_hint_to_seg_type(enum rw_hint hint);
|
||||
enum rw_hint f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
|
||||
enum page_type type, enum temp_type temp);
|
||||
unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
|
||||
unsigned int segno);
|
||||
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
|
||||
|
@ -4685,8 +4685,21 @@ static int f2fs_dio_write_end_io(struct kiocb *iocb, ssize_t size, int error,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void f2fs_dio_write_submit_io(const struct iomap_iter *iter,
|
||||
struct bio *bio, loff_t file_offset)
|
||||
{
|
||||
struct inode *inode = iter->inode;
|
||||
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
|
||||
int seg_type = f2fs_rw_hint_to_seg_type(inode->i_write_hint);
|
||||
enum temp_type temp = f2fs_get_segment_temp(seg_type);
|
||||
|
||||
bio->bi_write_hint = f2fs_io_type_to_rw_hint(sbi, DATA, temp);
|
||||
submit_bio(bio);
|
||||
}
|
||||
|
||||
static const struct iomap_dio_ops f2fs_iomap_dio_write_ops = {
|
||||
.end_io = f2fs_dio_write_end_io,
|
||||
.end_io = f2fs_dio_write_end_io,
|
||||
.submit_io = f2fs_dio_write_submit_io,
|
||||
};
|
||||
|
||||
static void f2fs_flush_buffered_write(struct address_space *mapping,
|
||||
|
@ -3364,6 +3364,65 @@ int f2fs_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 as below by default.
|
||||
*
|
||||
* User F2FS Block
|
||||
* ---- ---- -----
|
||||
* META WRITE_LIFE_NONE|REQ_META
|
||||
* HOT_NODE WRITE_LIFE_NONE
|
||||
* WARM_NODE WRITE_LIFE_MEDIUM
|
||||
* COLD_NODE WRITE_LIFE_LONG
|
||||
* ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME
|
||||
* extension list " "
|
||||
*
|
||||
* -- buffered io
|
||||
* COLD_DATA WRITE_LIFE_EXTREME
|
||||
* HOT_DATA WRITE_LIFE_SHORT
|
||||
* WARM_DATA WRITE_LIFE_NOT_SET
|
||||
*
|
||||
* -- 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 f2fs_io_type_to_rw_hint(struct f2fs_sb_info *sbi,
|
||||
enum page_type type, enum temp_type temp)
|
||||
{
|
||||
switch (type) {
|
||||
case DATA:
|
||||
switch (temp) {
|
||||
case WARM:
|
||||
return WRITE_LIFE_NOT_SET;
|
||||
case HOT:
|
||||
return WRITE_LIFE_SHORT;
|
||||
case COLD:
|
||||
return WRITE_LIFE_EXTREME;
|
||||
default:
|
||||
return WRITE_LIFE_NONE;
|
||||
}
|
||||
case NODE:
|
||||
switch (temp) {
|
||||
case WARM:
|
||||
return WRITE_LIFE_MEDIUM;
|
||||
case HOT:
|
||||
return WRITE_LIFE_NONE;
|
||||
case COLD:
|
||||
return WRITE_LIFE_LONG;
|
||||
default:
|
||||
return WRITE_LIFE_NONE;
|
||||
}
|
||||
case META:
|
||||
return WRITE_LIFE_NONE;
|
||||
default:
|
||||
return WRITE_LIFE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static int __get_segment_type_2(struct f2fs_io_info *fio)
|
||||
{
|
||||
if (fio->type == DATA)
|
||||
@ -3443,6 +3502,15 @@ static int __get_segment_type_6(struct f2fs_io_info *fio)
|
||||
}
|
||||
}
|
||||
|
||||
int f2fs_get_segment_temp(int seg_type)
|
||||
{
|
||||
if (IS_HOT(seg_type))
|
||||
return HOT;
|
||||
else if (IS_WARM(seg_type))
|
||||
return WARM;
|
||||
return COLD;
|
||||
}
|
||||
|
||||
static int __get_segment_type(struct f2fs_io_info *fio)
|
||||
{
|
||||
int type = 0;
|
||||
@ -3461,12 +3529,8 @@ static int __get_segment_type(struct f2fs_io_info *fio)
|
||||
f2fs_bug_on(fio->sbi, true);
|
||||
}
|
||||
|
||||
if (IS_HOT(type))
|
||||
fio->temp = HOT;
|
||||
else if (IS_WARM(type))
|
||||
fio->temp = WARM;
|
||||
else
|
||||
fio->temp = COLD;
|
||||
fio->temp = f2fs_get_segment_temp(type);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user