[PATCH 01/16] squashfs: don't truncate page cache indices in squashfs_copy_cache()
From: Tal Zussman
Date: Tue Nov 03 2026 - 09:24:29 EST
squashfs_copy_cache() keeps the page cache indices of the block it fills
in ints. On 64-bit, once a file is past 8 TiB the index truncates and the
loop never reaches the folio it was called for. That folio is never
unlocked and the read hangs, and the other folios in the block are looked
up and filled at the wrong indices.
Fragments and sparse blocks always go through squashfs_copy_cache(), as
does every block with CONFIG_SQUASHFS_FILE_CACHE, so a large sparse file
is enough to hit this.
Use pgoff_t for the indices.
Fixes: 1701aecb6849 ("Squashfs: regular file operations")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>
---
fs/squashfs/file.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
index d83594ce91d2..9c9a437ab118 100644
--- a/fs/squashfs/file.c
+++ b/fs/squashfs/file.c
@@ -396,8 +396,9 @@ void squashfs_copy_cache(struct folio *folio,
struct address_space *mapping = folio->mapping;
struct inode *inode = mapping->host;
struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
- int i, mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
- int start_index = folio->index & ~mask, end_index = start_index | mask;
+ int mask = (1 << (msblk->block_log - PAGE_SHIFT)) - 1;
+ pgoff_t i, start_index = folio->index & ~mask;
+ pgoff_t end_index = start_index | mask;
/*
* Loop copying datablock into pages. As the datablock likely covers
@@ -411,7 +412,7 @@ void squashfs_copy_cache(struct folio *folio,
size_t avail = buffer ? min(bytes, PAGE_SIZE) : 0;
bool updated = false;
- TRACE("bytes %zu, i %d, available_bytes %zu\n", bytes, i, avail);
+ TRACE("bytes %zu, i %lu, available_bytes %zu\n", bytes, i, avail);
push_folio = (i == folio->index) ? folio :
__filemap_get_folio(mapping, i,
--
2.39.5