diff options
| author | Jaegeuk Kim <jaegeuk@kernel.org> | 2017-03-24 20:05:13 -0400 |
|---|---|---|
| committer | Moyster <oysterized@gmail.com> | 2017-05-21 18:39:53 +0200 |
| commit | a896223c829b21889069cecd23c3992a0e35d501 (patch) | |
| tree | 23790911a70e30dae9cfbae338388afe148533ef | |
| parent | 9059f2ff363cd465ed2a9bd159e9129e2e3cee5c (diff) | |
f2fs: write small sized IO to hot log
It would better split small and large IOs separately in order to get more
consecutive big writes.
The default threshold is set to 64KB, but configurable by sysfs/min_hot_blocks.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Conflicts:
fs/f2fs/f2fs.h
| -rw-r--r-- | fs/f2fs/data.c | 9 | ||||
| -rw-r--r-- | fs/f2fs/f2fs.h | 2 | ||||
| -rw-r--r-- | fs/f2fs/inline.c | 1 | ||||
| -rw-r--r-- | fs/f2fs/segment.c | 13 | ||||
| -rw-r--r-- | fs/f2fs/segment.h | 1 | ||||
| -rw-r--r-- | fs/f2fs/super.c | 2 |
6 files changed, 21 insertions, 7 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8e251d049..bc600520b 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1428,6 +1428,8 @@ write: need_balance_fs = true; else if (has_not_enough_free_secs(sbi, 0, 0)) goto redirty_out; + else + set_inode_flag(inode, FI_HOT_DATA); err = -EAGAIN; if (f2fs_has_inline_data(inode)) { @@ -1453,6 +1455,7 @@ out: if (wbc->for_reclaim) { f2fs_submit_merged_bio_cond(sbi, inode, 0, page->index, DATA, WRITE); + clear_inode_flag(inode, FI_HOT_DATA); remove_dirty_inode(inode); submitted = NULL; } @@ -1507,6 +1510,12 @@ static int f2fs_write_cache_pages(struct address_space *mapping, pagevec_init(&pvec, 0); + if (get_dirty_pages(mapping->host) <= + SM_I(F2FS_M_SB(mapping))->min_hot_blocks) + set_inode_flag(mapping->host, FI_HOT_DATA); + else + clear_inode_flag(mapping->host, FI_HOT_DATA); + if (wbc->range_cyclic) { writeback_index = mapping->writeback_index; /* prev offset */ index = writeback_index; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 02ba19bc3..3dcfd087e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -776,6 +776,7 @@ struct f2fs_sm_info { unsigned int ipu_policy; /* in-place-update policy */ unsigned int min_ipu_util; /* in-place-update threshold */ unsigned int min_fsync_blocks; /* threshold for fsync */ + unsigned int min_hot_blocks; /* threshold for hot block allocation */ /* for flush command control */ struct flush_cmd_control *fcc_info; @@ -1819,6 +1820,7 @@ enum { FI_INLINE_DOTS, /* indicate inline dot dentries */ FI_DO_DEFRAG, /* indicate defragment is running */ FI_DIRTY_FILE, /* indicate regular/symlink has dirty pages */ + FI_HOT_DATA, /* indicate file is hot */ }; static inline void __mark_inode_dirty_flag(struct inode *inode, diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index a3253320f..befc68476 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -137,6 +137,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) /* write data page to try to make data consistent */ set_page_writeback(page); fio.old_blkaddr = dn->data_blkaddr; + set_inode_flag(dn->inode, FI_HOT_DATA); write_data_page(dn, &fio); f2fs_wait_on_page_writeback(page, DATA, true); if (dirty) { diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 969429439..cbe4b288b 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1967,18 +1967,16 @@ static int __get_segment_type_6(struct page *page, enum page_type p_type) if (p_type == DATA) { struct inode *inode = page->mapping->host; - if (S_ISDIR(inode->i_mode)) - return CURSEG_HOT_DATA; - else if (is_cold_data(page) || file_is_cold(inode)) + if (is_cold_data(page) || file_is_cold(inode)) return CURSEG_COLD_DATA; - else - return CURSEG_WARM_DATA; + if (is_inode_flag_set(inode, FI_HOT_DATA)) + return CURSEG_HOT_DATA; + return CURSEG_WARM_DATA; } else { if (IS_DNODE(page)) return is_cold_node(page) ? CURSEG_WARM_NODE : CURSEG_HOT_NODE; - else - return CURSEG_COLD_NODE; + return CURSEG_COLD_NODE; } } @@ -3085,6 +3083,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC; sm_info->min_ipu_util = DEF_MIN_IPU_UTIL; sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS; + sm_info->min_hot_blocks = DEF_MIN_HOT_BLOCKS; sm_info->trim_sections = DEF_BATCHED_TRIM_SECTIONS; diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index f12206a20..92eb9b144 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -539,6 +539,7 @@ static inline int utilization(struct f2fs_sb_info *sbi) */ #define DEF_MIN_IPU_UTIL 70 #define DEF_MIN_FSYNC_BLOCKS 8 +#define DEF_MIN_HOT_BLOCKS 16 enum { F2FS_IPU_FORCE, diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 2f9332fdc..c9ff120d8 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -291,6 +291,7 @@ F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, batched_trim_sections, trim_sections); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, ipu_policy, ipu_policy); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_ipu_util, min_ipu_util); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_fsync_blocks, min_fsync_blocks); +F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, min_hot_blocks, min_hot_blocks); F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ram_thresh, ram_thresh); F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, ra_nid_pages, ra_nid_pages); F2FS_RW_ATTR(NM_INFO, f2fs_nm_info, dirty_nats_ratio, dirty_nats_ratio); @@ -316,6 +317,7 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(ipu_policy), ATTR_LIST(min_ipu_util), ATTR_LIST(min_fsync_blocks), + ATTR_LIST(min_hot_blocks), ATTR_LIST(max_victim_search), ATTR_LIST(dir_level), ATTR_LIST(ram_thresh), |
