Commit c9199de8 authored by Phillip Lougher's avatar Phillip Lougher Committed by Andrew Morton

squashfs: fix extending readahead beyond end of file

The readahead code will try to extend readahead to the entire size of the
Squashfs data block.

But, it didn't take into account that the last block at the end of the
file may not be a whole block.  In this case, the code would extend
readahead to beyond the end of the file, leaving trailing pages.

Fix this by only requesting the expected number of pages.

Link: https://lkml.kernel.org/r/20221020223616.7571-3-phillip@squashfs.org.uk
Fixes: 8fc78b6f ("squashfs: implement readahead")
Signed-off-by: default avatarPhillip Lougher <phillip@squashfs.org.uk>
Tested-by: default avatarBagas Sanjaya <bagasdotme@gmail.com>
Reported-by: default avatarMarc Miltenberger <marcmiltenberger@gmail.com>
Cc: Dimitri John Ledkov <dimitri.ledkov@canonical.com>
Cc: Hsin-Yi Wang <hsinyi@chromium.org>
Cc: Mirsad Goran Todorovac <mirsad.todorovac@alu.unizg.hr>
Cc: Slade Watkins <srw@sladewatkins.net>
Cc: Thorsten Leemhuis <regressions@leemhuis.info>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 9ef8eb61
...@@ -559,6 +559,12 @@ static void squashfs_readahead(struct readahead_control *ractl) ...@@ -559,6 +559,12 @@ static void squashfs_readahead(struct readahead_control *ractl)
unsigned int expected; unsigned int expected;
struct page *last_page; struct page *last_page;
expected = start >> msblk->block_log == file_end ?
(i_size_read(inode) & (msblk->block_size - 1)) :
msblk->block_size;
max_pages = (expected + PAGE_SIZE - 1) >> PAGE_SHIFT;
nr_pages = __readahead_batch(ractl, pages, max_pages); nr_pages = __readahead_batch(ractl, pages, max_pages);
if (!nr_pages) if (!nr_pages)
break; break;
...@@ -567,13 +573,10 @@ static void squashfs_readahead(struct readahead_control *ractl) ...@@ -567,13 +573,10 @@ static void squashfs_readahead(struct readahead_control *ractl)
goto skip_pages; goto skip_pages;
index = pages[0]->index >> shift; index = pages[0]->index >> shift;
if ((pages[nr_pages - 1]->index >> shift) != index) if ((pages[nr_pages - 1]->index >> shift) != index)
goto skip_pages; goto skip_pages;
expected = index == file_end ?
(i_size_read(inode) & (msblk->block_size - 1)) :
msblk->block_size;
if (index == file_end && squashfs_i(inode)->fragment_block != if (index == file_end && squashfs_i(inode)->fragment_block !=
SQUASHFS_INVALID_BLK) { SQUASHFS_INVALID_BLK) {
res = squashfs_readahead_fragment(pages, nr_pages, res = squashfs_readahead_fragment(pages, nr_pages,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment