]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fs/libfs: don't assume blocksize <= PAGE_SIZE in generic_check_addressable
authorPankaj Raghav <p.raghav@samsung.com>
Mon, 30 Jun 2025 10:40:18 +0000 (12:40 +0200)
committerChristian Brauner <brauner@kernel.org>
Tue, 8 Jul 2025 14:48:12 +0000 (16:48 +0200)
Since [1], it is possible for filesystems to have blocksize > PAGE_SIZE
of the system.

Remove the assumption and make the check generic for all blocksizes in
generic_check_addressable().

[1] https://lore.kernel.org/linux-xfs/20240822135018.1931258-1-kernel@pankajraghav.com/

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
Link: https://lore.kernel.org/20250630104018.213985-1-p.raghav@samsung.com
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Reviewed-by: Baokun Li <libaokun1@huawei.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/libfs.c

index 4d1862f589e8782c041d850d7cfa383bfc107654..f99ecc3006471d43c827556bdaccf66c5557d430 100644 (file)
@@ -1584,13 +1584,17 @@ EXPORT_SYMBOL(generic_file_fsync);
 int generic_check_addressable(unsigned blocksize_bits, u64 num_blocks)
 {
        u64 last_fs_block = num_blocks - 1;
-       u64 last_fs_page =
-               last_fs_block >> (PAGE_SHIFT - blocksize_bits);
+       u64 last_fs_page, max_bytes;
+
+       if (check_shl_overflow(num_blocks, blocksize_bits, &max_bytes))
+               return -EFBIG;
+
+       last_fs_page = (max_bytes >> PAGE_SHIFT) - 1;
 
        if (unlikely(num_blocks == 0))
                return 0;
 
-       if ((blocksize_bits < 9) || (blocksize_bits > PAGE_SHIFT))
+       if (blocksize_bits < 9)
                return -EINVAL;
 
        if ((last_fs_block > (sector_t)(~0ULL) >> (blocksize_bits - 9)) ||