]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iomap: constrain the file range passed to iomap_file_unshare
authorDarrick J. Wong <djwong@kernel.org>
Wed, 2 Oct 2024 15:02:13 +0000 (08:02 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Oct 2024 10:03:01 +0000 (12:03 +0200)
[ 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
fs/iomap/buffered-io.c

index becb4a6920c6aa1fc0aadb909abefbd8dddd866f..c62acd2812f8d4981aaba82acfeaf972f555362a 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1305,11 +1305,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;
index f420c53d86acc5753a76c34e0c2a05ff9673f36f..389de94715b53da6173c6b2e095dbe6392a66537 100644 (file)
@@ -1382,11 +1382,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;