Commit d860974a authored by Yeongjin Gil's avatar Yeongjin Gil Committed by Jaegeuk Kim
Browse files

f2fs: optimize f2fs_overwrite_io() for f2fs_iomap_begin



When overwriting already allocated blocks, f2fs_iomap_begin() calls
f2fs_overwrite_io() to check block mappings. However,
f2fs_overwrite_io() iterates through all mapped blocks in the range,
which can be inefficient for fragmented files with large I/O requests.

This patch optimizes f2fs_overwrite_io() by adding a 'check_first'
parameter and introducing __f2fs_overwrite_io() helper. When called from
f2fs_iomap_begin(), we only check the first mapping to determine if the
range is already allocated, which is sufficient for setting
map.m_may_create.

This optimization significantly reduces the number of f2fs_map_blocks()
calls in f2fs_overwrite_io() when called from f2fs_iomap_begin(),
especially for fragmented files with large I/O requests.

Cc: stable@kernel.org
Fixes: 351bc761 ("f2fs: optimize f2fs DIO overwrites")
Reviewed-by: default avatarSungjong Seo <sj1557.seo@samsung.com>
Reviewed-by: default avatarSunmin Jeong <s_min.jeong@samsung.com>
Signed-off-by: default avatarYeongjin Gil <youngjin.gil@samsung.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 91b76f10
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -1865,7 +1865,8 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
	return err;
}

bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len)
static bool __f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len,
				bool check_first)
{
	struct f2fs_map_blocks map;
	block_t last_lblk;
@@ -1887,10 +1888,17 @@ bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len)
		if (err || map.m_len == 0)
			return false;
		map.m_lblk += map.m_len;
		if (check_first)
			break;
	}
	return true;
}

bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len)
{
	return __f2fs_overwrite_io(inode, pos, len, false);
}

static int f2fs_xattr_fiemap(struct inode *inode,
				struct fiemap_extent_info *fieinfo)
{
@@ -4487,7 +4495,7 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
	 * f2fs_map_lock and f2fs_balance_fs are not necessary.
	 */
	if ((flags & IOMAP_WRITE) &&
		!f2fs_overwrite_io(inode, offset, length))
		!__f2fs_overwrite_io(inode, offset, length, true))
		map.m_may_create = true;

	err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_DIO);