Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef095d19 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

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: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent a7eeb823
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -1432,6 +1432,8 @@ static int __write_data_page(struct page *page, bool *submitted,
		need_balance_fs = true;
		need_balance_fs = true;
	else if (has_not_enough_free_secs(sbi, 0, 0))
	else if (has_not_enough_free_secs(sbi, 0, 0))
		goto redirty_out;
		goto redirty_out;
	else
		set_inode_flag(inode, FI_HOT_DATA);


	err = -EAGAIN;
	err = -EAGAIN;
	if (f2fs_has_inline_data(inode)) {
	if (f2fs_has_inline_data(inode)) {
@@ -1457,6 +1459,7 @@ static int __write_data_page(struct page *page, bool *submitted,
	if (wbc->for_reclaim) {
	if (wbc->for_reclaim) {
		f2fs_submit_merged_bio_cond(sbi, inode, 0, page->index,
		f2fs_submit_merged_bio_cond(sbi, inode, 0, page->index,
						DATA, WRITE);
						DATA, WRITE);
		clear_inode_flag(inode, FI_HOT_DATA);
		remove_dirty_inode(inode);
		remove_dirty_inode(inode);
		submitted = NULL;
		submitted = NULL;
	}
	}
@@ -1511,6 +1514,12 @@ static int f2fs_write_cache_pages(struct address_space *mapping,


	pagevec_init(&pvec, 0);
	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) {
	if (wbc->range_cyclic) {
		writeback_index = mapping->writeback_index; /* prev offset */
		writeback_index = mapping->writeback_index; /* prev offset */
		index = writeback_index;
		index = writeback_index;
+2 −0
Original line number Original line Diff line number Diff line
@@ -677,6 +677,7 @@ struct f2fs_sm_info {
	unsigned int ipu_policy;	/* in-place-update policy */
	unsigned int ipu_policy;	/* in-place-update policy */
	unsigned int min_ipu_util;	/* in-place-update threshold */
	unsigned int min_ipu_util;	/* in-place-update threshold */
	unsigned int min_fsync_blocks;	/* threshold for fsync */
	unsigned int min_fsync_blocks;	/* threshold for fsync */
	unsigned int min_hot_blocks;	/* threshold for hot block allocation */


	/* for flush command control */
	/* for flush command control */
	struct flush_cmd_control *fcc_info;
	struct flush_cmd_control *fcc_info;
@@ -1716,6 +1717,7 @@ enum {
	FI_DO_DEFRAG,		/* indicate defragment is running */
	FI_DO_DEFRAG,		/* indicate defragment is running */
	FI_DIRTY_FILE,		/* indicate regular/symlink has dirty pages */
	FI_DIRTY_FILE,		/* indicate regular/symlink has dirty pages */
	FI_NO_PREALLOC,		/* indicate skipped preallocated blocks */
	FI_NO_PREALLOC,		/* indicate skipped preallocated blocks */
	FI_HOT_DATA,		/* indicate file is hot */
};
};


static inline void __mark_inode_dirty_flag(struct inode *inode,
static inline void __mark_inode_dirty_flag(struct inode *inode,
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 */
	/* write data page to try to make data consistent */
	set_page_writeback(page);
	set_page_writeback(page);
	fio.old_blkaddr = dn->data_blkaddr;
	fio.old_blkaddr = dn->data_blkaddr;
	set_inode_flag(dn->inode, FI_HOT_DATA);
	write_data_page(dn, &fio);
	write_data_page(dn, &fio);
	f2fs_wait_on_page_writeback(page, DATA, true);
	f2fs_wait_on_page_writeback(page, DATA, true);
	if (dirty) {
	if (dirty) {
+6 −7
Original line number Original line Diff line number Diff line
@@ -1829,17 +1829,15 @@ static int __get_segment_type_6(struct page *page, enum page_type p_type)
	if (p_type == DATA) {
	if (p_type == DATA) {
		struct inode *inode = page->mapping->host;
		struct inode *inode = page->mapping->host;


		if (S_ISDIR(inode->i_mode))
		if (is_cold_data(page) || file_is_cold(inode))
			return CURSEG_HOT_DATA;
		else if (is_cold_data(page) || file_is_cold(inode))
			return CURSEG_COLD_DATA;
			return CURSEG_COLD_DATA;
		else
		if (is_inode_flag_set(inode, FI_HOT_DATA))
			return CURSEG_HOT_DATA;
		return CURSEG_WARM_DATA;
		return CURSEG_WARM_DATA;
	} else {
	} else {
		if (IS_DNODE(page))
		if (IS_DNODE(page))
			return is_cold_node(page) ? CURSEG_WARM_NODE :
			return is_cold_node(page) ? CURSEG_WARM_NODE :
						CURSEG_HOT_NODE;
						CURSEG_HOT_NODE;
		else
		return CURSEG_COLD_NODE;
		return CURSEG_COLD_NODE;
	}
	}
}
}
@@ -2947,6 +2945,7 @@ int build_segment_manager(struct f2fs_sb_info *sbi)
		sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC;
		sm_info->ipu_policy = 1 << F2FS_IPU_FSYNC;
	sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
	sm_info->min_ipu_util = DEF_MIN_IPU_UTIL;
	sm_info->min_fsync_blocks = DEF_MIN_FSYNC_BLOCKS;
	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;
	sm_info->trim_sections = DEF_BATCHED_TRIM_SECTIONS;


+1 −0
Original line number Original line Diff line number Diff line
@@ -540,6 +540,7 @@ static inline int utilization(struct f2fs_sb_info *sbi)
 */
 */
#define DEF_MIN_IPU_UTIL	70
#define DEF_MIN_IPU_UTIL	70
#define DEF_MIN_FSYNC_BLOCKS	8
#define DEF_MIN_FSYNC_BLOCKS	8
#define DEF_MIN_HOT_BLOCKS	16


enum {
enum {
	F2FS_IPU_FORCE,
	F2FS_IPU_FORCE,
Loading