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

Commit 87d6f890 authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: avoid small data writes by skipping writepages



This patch introduces nr_pages_to_skip(sbi, type) to determine writepages can
be skipped.
The dentry, node, and meta pages can be conrolled by F2FS without breaking the
FS consistency.

Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
parent f8b2c1f9
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -187,7 +187,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
				struct writeback_control *wbc)
				struct writeback_control *wbc)
{
{
	struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb);
	struct f2fs_sb_info *sbi = F2FS_SB(mapping->host->i_sb);
	int nrpages = MAX_BIO_BLOCKS(max_hw_blocks(sbi));
	int nrpages = nr_pages_to_skip(sbi, META);
	long written;
	long written;


	if (wbc->for_kupdate)
	if (wbc->for_kupdate)
@@ -682,7 +682,7 @@ retry:
	inode = igrab(entry->inode);
	inode = igrab(entry->inode);
	spin_unlock(&sbi->dir_inode_lock);
	spin_unlock(&sbi->dir_inode_lock);
	if (inode) {
	if (inode) {
		filemap_flush(inode->i_mapping);
		filemap_fdatawrite(inode->i_mapping);
		iput(inode);
		iput(inode);
	} else {
	} else {
		/*
		/*
+4 −0
Original line number Original line Diff line number Diff line
@@ -868,6 +868,10 @@ static int f2fs_write_data_pages(struct address_space *mapping,
	if (!mapping->a_ops->writepage)
	if (!mapping->a_ops->writepage)
		return 0;
		return 0;


	if (S_ISDIR(inode->i_mode) && wbc->sync_mode == WB_SYNC_NONE &&
			get_dirty_dents(inode) < nr_pages_to_skip(sbi, DATA))
		return 0;

	if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) {
	if (wbc->nr_to_write < MAX_DESIRED_PAGES_WP) {
		desired_nrtw = MAX_DESIRED_PAGES_WP;
		desired_nrtw = MAX_DESIRED_PAGES_WP;
		excess_nrtw = desired_nrtw - wbc->nr_to_write;
		excess_nrtw = desired_nrtw - wbc->nr_to_write;
+1 −7
Original line number Original line Diff line number Diff line
@@ -1198,12 +1198,6 @@ redirty_out:
	return AOP_WRITEPAGE_ACTIVATE;
	return AOP_WRITEPAGE_ACTIVATE;
}
}


/*
 * It is very important to gather dirty pages and write at once, so that we can
 * submit a big bio without interfering other data writes.
 * Be default, 512 pages (2MB) * 3 node types, is more reasonable.
 */
#define COLLECT_DIRTY_NODES	1536
static int f2fs_write_node_pages(struct address_space *mapping,
static int f2fs_write_node_pages(struct address_space *mapping,
			    struct writeback_control *wbc)
			    struct writeback_control *wbc)
{
{
@@ -1214,7 +1208,7 @@ static int f2fs_write_node_pages(struct address_space *mapping,
	f2fs_balance_fs_bg(sbi);
	f2fs_balance_fs_bg(sbi);


	/* collect a number of dirty node pages and write together */
	/* collect a number of dirty node pages and write together */
	if (get_pages(sbi, F2FS_DIRTY_NODES) < COLLECT_DIRTY_NODES)
	if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE))
		return 0;
		return 0;


	/* if mounting is failed, skip writing node pages */
	/* if mounting is failed, skip writing node pages */
+19 −0
Original line number Original line Diff line number Diff line
@@ -664,3 +664,22 @@ static inline unsigned int max_hw_blocks(struct f2fs_sb_info *sbi)
	struct request_queue *q = bdev_get_queue(bdev);
	struct request_queue *q = bdev_get_queue(bdev);
	return SECTOR_TO_BLOCK(sbi, queue_max_sectors(q));
	return SECTOR_TO_BLOCK(sbi, queue_max_sectors(q));
}
}

/*
 * It is very important to gather dirty pages and write at once, so that we can
 * submit a big bio without interfering other data writes.
 * By default, 512 pages for directory data,
 * 512 pages (2MB) * 3 for three types of nodes, and
 * max_bio_blocks for meta are set.
 */
static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type)
{
	if (type == DATA)
		return sbi->blocks_per_seg;
	else if (type == NODE)
		return 3 * sbi->blocks_per_seg;
	else if (type == META)
		return MAX_BIO_BLOCKS(max_hw_blocks(sbi));
	else
		return 0;
}