Commit d5097be5 authored by Hyunchul Lee's avatar Hyunchul Lee Committed by Jaegeuk Kim

f2fs: apply write hints to select the type of segment for direct write

When blocks are allocated for direct write, select the type of
segment using the kiocb hint. But if an inode has FI_NO_ALLOC,
use the inode hint.
Signed-off-by: default avatarHyunchul Lee <cheol.lee@lge.com>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 20bb2479
...@@ -783,7 +783,7 @@ struct page *get_new_data_page(struct inode *inode, ...@@ -783,7 +783,7 @@ struct page *get_new_data_page(struct inode *inode,
return page; return page;
} }
static int __allocate_data_block(struct dnode_of_data *dn) static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
struct f2fs_summary sum; struct f2fs_summary sum;
...@@ -808,7 +808,7 @@ static int __allocate_data_block(struct dnode_of_data *dn) ...@@ -808,7 +808,7 @@ static int __allocate_data_block(struct dnode_of_data *dn)
set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version); set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr, allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
&sum, CURSEG_WARM_DATA, NULL, false); &sum, seg_type, NULL, false);
set_data_blkaddr(dn); set_data_blkaddr(dn);
/* update i_size */ /* update i_size */
...@@ -851,12 +851,15 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from) ...@@ -851,12 +851,15 @@ int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
map.m_len = 0; map.m_len = 0;
map.m_next_pgofs = NULL; map.m_next_pgofs = NULL;
map.m_seg_type = NO_CHECK_TYPE;
if (iocb->ki_flags & IOCB_DIRECT) if (iocb->ki_flags & IOCB_DIRECT) {
map.m_seg_type = rw_hint_to_seg_type(iocb->ki_hint);
return f2fs_map_blocks(inode, &map, 1, return f2fs_map_blocks(inode, &map, 1,
__force_buffered_io(inode, WRITE) ? __force_buffered_io(inode, WRITE) ?
F2FS_GET_BLOCK_PRE_AIO : F2FS_GET_BLOCK_PRE_AIO :
F2FS_GET_BLOCK_PRE_DIO); F2FS_GET_BLOCK_PRE_DIO);
}
if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) { if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) {
err = f2fs_convert_inline_inode(inode); err = f2fs_convert_inline_inode(inode);
if (err) if (err)
...@@ -966,7 +969,8 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, ...@@ -966,7 +969,8 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
last_ofs_in_node = dn.ofs_in_node; last_ofs_in_node = dn.ofs_in_node;
} }
} else { } else {
err = __allocate_data_block(&dn); err = __allocate_data_block(&dn,
map->m_seg_type);
if (!err) if (!err)
set_inode_flag(inode, FI_APPEND_WRITE); set_inode_flag(inode, FI_APPEND_WRITE);
} }
...@@ -1059,7 +1063,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, ...@@ -1059,7 +1063,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
static int __get_data_block(struct inode *inode, sector_t iblock, static int __get_data_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh, int create, int flag, struct buffer_head *bh, int create, int flag,
pgoff_t *next_pgofs) pgoff_t *next_pgofs, int seg_type)
{ {
struct f2fs_map_blocks map; struct f2fs_map_blocks map;
int err; int err;
...@@ -1067,6 +1071,7 @@ static int __get_data_block(struct inode *inode, sector_t iblock, ...@@ -1067,6 +1071,7 @@ static int __get_data_block(struct inode *inode, sector_t iblock,
map.m_lblk = iblock; map.m_lblk = iblock;
map.m_len = bh->b_size >> inode->i_blkbits; map.m_len = bh->b_size >> inode->i_blkbits;
map.m_next_pgofs = next_pgofs; map.m_next_pgofs = next_pgofs;
map.m_seg_type = seg_type;
err = f2fs_map_blocks(inode, &map, create, flag); err = f2fs_map_blocks(inode, &map, create, flag);
if (!err) { if (!err) {
...@@ -1082,14 +1087,17 @@ static int get_data_block(struct inode *inode, sector_t iblock, ...@@ -1082,14 +1087,17 @@ static int get_data_block(struct inode *inode, sector_t iblock,
pgoff_t *next_pgofs) pgoff_t *next_pgofs)
{ {
return __get_data_block(inode, iblock, bh_result, create, return __get_data_block(inode, iblock, bh_result, create,
flag, next_pgofs); flag, next_pgofs,
NO_CHECK_TYPE);
} }
static int get_data_block_dio(struct inode *inode, sector_t iblock, static int get_data_block_dio(struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create) struct buffer_head *bh_result, int create)
{ {
return __get_data_block(inode, iblock, bh_result, create, return __get_data_block(inode, iblock, bh_result, create,
F2FS_GET_BLOCK_DEFAULT, NULL); F2FS_GET_BLOCK_DEFAULT, NULL,
rw_hint_to_seg_type(
inode->i_write_hint));
} }
static int get_data_block_bmap(struct inode *inode, sector_t iblock, static int get_data_block_bmap(struct inode *inode, sector_t iblock,
...@@ -1100,7 +1108,8 @@ static int get_data_block_bmap(struct inode *inode, sector_t iblock, ...@@ -1100,7 +1108,8 @@ static int get_data_block_bmap(struct inode *inode, sector_t iblock,
return -EFBIG; return -EFBIG;
return __get_data_block(inode, iblock, bh_result, create, return __get_data_block(inode, iblock, bh_result, create,
F2FS_GET_BLOCK_BMAP, NULL); F2FS_GET_BLOCK_BMAP, NULL,
NO_CHECK_TYPE);
} }
static inline sector_t logical_to_blk(struct inode *inode, loff_t offset) static inline sector_t logical_to_blk(struct inode *inode, loff_t offset)
...@@ -1219,6 +1228,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping, ...@@ -1219,6 +1228,7 @@ static int f2fs_mpage_readpages(struct address_space *mapping,
map.m_len = 0; map.m_len = 0;
map.m_flags = 0; map.m_flags = 0;
map.m_next_pgofs = NULL; map.m_next_pgofs = NULL;
map.m_seg_type = NO_CHECK_TYPE;
for (; nr_pages; nr_pages--) { for (; nr_pages; nr_pages--) {
if (pages) { if (pages) {
......
...@@ -542,6 +542,7 @@ struct f2fs_map_blocks { ...@@ -542,6 +542,7 @@ struct f2fs_map_blocks {
unsigned int m_len; unsigned int m_len;
unsigned int m_flags; unsigned int m_flags;
pgoff_t *m_next_pgofs; /* point next possible non-hole pgofs */ pgoff_t *m_next_pgofs; /* point next possible non-hole pgofs */
int m_seg_type;
}; };
/* for flag in get_data_block */ /* for flag in get_data_block */
...@@ -2674,6 +2675,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi); ...@@ -2674,6 +2675,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi);
void destroy_segment_manager(struct f2fs_sb_info *sbi); void destroy_segment_manager(struct f2fs_sb_info *sbi);
int __init create_segment_manager_caches(void); int __init create_segment_manager_caches(void);
void destroy_segment_manager_caches(void); void destroy_segment_manager_caches(void);
int rw_hint_to_seg_type(enum rw_hint hint);
/* /*
* checkpoint.c * checkpoint.c
......
...@@ -1418,7 +1418,8 @@ static int expand_inode_data(struct inode *inode, loff_t offset, ...@@ -1418,7 +1418,8 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
loff_t len, int mode) loff_t len, int mode)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_map_blocks map = { .m_next_pgofs = NULL }; struct f2fs_map_blocks map = { .m_next_pgofs = NULL,
.m_seg_type = NO_CHECK_TYPE };
pgoff_t pg_end; pgoff_t pg_end;
loff_t new_size = i_size_read(inode); loff_t new_size = i_size_read(inode);
loff_t off_end; loff_t off_end;
...@@ -2066,7 +2067,8 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi, ...@@ -2066,7 +2067,8 @@ static int f2fs_defragment_range(struct f2fs_sb_info *sbi,
struct f2fs_defragment *range) struct f2fs_defragment *range)
{ {
struct inode *inode = file_inode(filp); struct inode *inode = file_inode(filp);
struct f2fs_map_blocks map = { .m_next_pgofs = NULL }; struct f2fs_map_blocks map = { .m_next_pgofs = NULL,
.m_seg_type = NO_CHECK_TYPE };
struct extent_info ei = {0,0,0}; struct extent_info ei = {0,0,0};
pgoff_t pg_start, pg_end; pgoff_t pg_start, pg_end;
unsigned int blk_per_seg = sbi->blocks_per_seg; unsigned int blk_per_seg = sbi->blocks_per_seg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment