iomap: constrain the file range passed to iomap_file_unshare

[ Upstream commit a311a08a4237241fb5b9d219d3e33346de6e83e0 ]

File contents can only be shared (i.e. reflinked) below EOF, so it makes
no sense to try to unshare ranges beyond EOF.  Constrain the file range
parameters here so that we don't have to do that in the callers.

Fixes: 5f4e5752a8 ("fs: add iomap_file_dirty")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Link: https://lore.kernel.org/r/20241002150213.GC21853@frogsfrogsfrogs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Darrick J. Wong
2024-10-02 08:02:13 -07:00
committed by Greg Kroah-Hartman
parent 1bec6782a2
commit fcb8a66d83
2 changed files with 10 additions and 2 deletions

View File

@@ -1262,11 +1262,15 @@ int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len,
struct iomap_iter iter = { struct iomap_iter iter = {
.inode = inode, .inode = inode,
.pos = pos, .pos = pos,
.len = len,
.flags = IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX, .flags = IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX,
}; };
loff_t size = i_size_read(inode);
int ret; int ret;
if (pos < 0 || pos >= size)
return 0;
iter.len = min(len, size - pos);
while ((ret = iomap_iter(&iter, ops)) > 0) while ((ret = iomap_iter(&iter, ops)) > 0)
iter.processed = dax_unshare_iter(&iter); iter.processed = dax_unshare_iter(&iter);
return ret; return ret;

View File

@@ -1126,11 +1126,15 @@ iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len,
struct iomap_iter iter = { struct iomap_iter iter = {
.inode = inode, .inode = inode,
.pos = pos, .pos = pos,
.len = len,
.flags = IOMAP_WRITE | IOMAP_UNSHARE, .flags = IOMAP_WRITE | IOMAP_UNSHARE,
}; };
loff_t size = i_size_read(inode);
int ret; int ret;
if (pos < 0 || pos >= size)
return 0;
iter.len = min(len, size - pos);
while ((ret = iomap_iter(&iter, ops)) > 0) while ((ret = iomap_iter(&iter, ops)) > 0)
iter.processed = iomap_unshare_iter(&iter); iter.processed = iomap_unshare_iter(&iter);
return ret; return ret;