Skip to content

Commit 08bab74

Browse files
vwaxakpm00
authored andcommitted
squashfs: fix cache race with migration
Migration replaces the page in the mapping before copying the contents and the flags over from the old page, so check that the page in the page cache is really up to date before using it. Without this, stressing squashfs reads with parallel compaction sometimes results in squashfs reporting data corruption. Link: https://lkml.kernel.org/r/[email protected] Fixes: e994f5b ("squashfs: cache partial compressed blocks") Signed-off-by: Vincent Whitchurch <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Phillip Lougher <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 191fcdb commit 08bab74

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

fs/squashfs/block.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,26 @@ static int squashfs_bio_read_cached(struct bio *fullbio,
166166
return 0;
167167
}
168168

169+
static struct page *squashfs_get_cache_page(struct address_space *mapping,
170+
pgoff_t index)
171+
{
172+
struct page *page;
173+
174+
if (!mapping)
175+
return NULL;
176+
177+
page = find_get_page(mapping, index);
178+
if (!page)
179+
return NULL;
180+
181+
if (!PageUptodate(page)) {
182+
put_page(page);
183+
return NULL;
184+
}
185+
186+
return page;
187+
}
188+
169189
static int squashfs_bio_read(struct super_block *sb, u64 index, int length,
170190
struct bio **biop, int *block_offset)
171191
{
@@ -190,11 +210,10 @@ static int squashfs_bio_read(struct super_block *sb, u64 index, int length,
190210
for (i = 0; i < page_count; ++i) {
191211
unsigned int len =
192212
min_t(unsigned int, PAGE_SIZE - offset, total_len);
193-
struct page *page = NULL;
213+
pgoff_t index = (read_start >> PAGE_SHIFT) + i;
214+
struct page *page;
194215

195-
if (cache_mapping)
196-
page = find_get_page(cache_mapping,
197-
(read_start >> PAGE_SHIFT) + i);
216+
page = squashfs_get_cache_page(cache_mapping, index);
198217
if (!page)
199218
page = alloc_page(GFP_NOIO);
200219

0 commit comments

Comments
 (0)