From c95f8b60a97a7988e401d82de6ab7dd5ad5d1eb7 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" <djwong@kernel.org> Date: Wed, 2 Oct 2024 08:02:13 -0700 Subject: [PATCH] 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: 5f4e5752a8a3 ("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> --- fs/dax.c | 6 +++++- fs/iomap/buffered-io.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 626745bc1ad86..7ecad1a28a894 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -1262,11 +1262,15 @@ int dax_file_unshare(struct inode *inode, loff_t pos, loff_t len, struct iomap_iter iter = { .inode = inode, .pos = pos, - .len = len, .flags = IOMAP_WRITE | IOMAP_UNSHARE | IOMAP_DAX, }; + loff_t size = i_size_read(inode); int ret; + if (pos < 0 || pos >= size) + return 0; + + iter.len = min(len, size - pos); while ((ret = iomap_iter(&iter, ops)) > 0) iter.processed = dax_unshare_iter(&iter); return ret; diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 0f7dabc6c764e..98617f00101d6 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -1126,11 +1126,15 @@ iomap_file_unshare(struct inode *inode, loff_t pos, loff_t len, struct iomap_iter iter = { .inode = inode, .pos = pos, - .len = len, .flags = IOMAP_WRITE | IOMAP_UNSHARE, }; + loff_t size = i_size_read(inode); int ret; + if (pos < 0 || pos >= size) + return 0; + + iter.len = min(len, size - pos); while ((ret = iomap_iter(&iter, ops)) > 0) iter.processed = iomap_unshare_iter(&iter); return ret; -- GitLab