]> git.dujemihanovic.xyz Git - linux.git/commitdiff
Squashfs: Ensure all readahead pages have been used
authorPhillip Lougher <phillip@squashfs.org.uk>
Thu, 22 Aug 2024 23:31:06 +0000 (00:31 +0100)
committerChristian Brauner <brauner@kernel.org>
Fri, 23 Aug 2024 11:11:36 +0000 (13:11 +0200)
In the recent work to remove page->index, a sanity check
that ensured all the readhead pages were covered by the
Squashfs data block was removed [1].

To avoid any regression, this commit adds the sanity check
back in an equivalent way.  Namely the page actor will now
return error if any pages are unused after completion.

[1] https://lore.kernel.org/all/20240818235847.170468-3-phillip@squashfs.org.uk/

--

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
Link: https://lore.kernel.org/r/20240822233106.121522-1-phillip@squashfs.org.uk
V3: last_page should be actor->last_page
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/squashfs/file.c
fs/squashfs/file_direct.c
fs/squashfs/page_actor.h

index 5a3745e5202520ed684fb8c33b8b1820ecca7931..21aaa96856c10605c53a8c5631dd211b081d2742 100644 (file)
@@ -535,7 +535,7 @@ static int squashfs_readahead_fragment(struct page **page,
 
        last_page = squashfs_page_actor_free(actor);
 
-       if (copied == expected) {
+       if (copied == expected && !IS_ERR(last_page)) {
                /* Last page (if present) may have trailing bytes not filled */
                bytes = copied % PAGE_SIZE;
                if (bytes && last_page)
@@ -625,7 +625,7 @@ static void squashfs_readahead(struct readahead_control *ractl)
 
                last_page = squashfs_page_actor_free(actor);
 
-               if (res == expected) {
+               if (res == expected && !IS_ERR(last_page)) {
                        int bytes;
 
                        /* Last page (if present) may have trailing bytes not filled */
index 646d4d421f99797781a2ab6178727df664c985c6..22251743fadfcd5ebfb8aa2fe40f91e2a3fb0735 100644 (file)
@@ -80,7 +80,7 @@ int squashfs_readpage_block(struct page *target_page, u64 block, int bsize,
        if (res < 0)
                goto mark_errored;
 
-       if (res != expected) {
+       if (res != expected || IS_ERR(last_page)) {
                res = -EIO;
                goto mark_errored;
        }
index c6d837f0e9ca9cac6ac3c171fa629f7cd7c33a2c..ffe25eb77c3209ca77d7236971ae3199ef64ce3d 100644 (file)
@@ -33,10 +33,11 @@ extern struct squashfs_page_actor *squashfs_page_actor_init_special(
                                loff_t start_index);
 static inline struct page *squashfs_page_actor_free(struct squashfs_page_actor *actor)
 {
-       struct page *last_page = actor->last_page;
+       struct page *last_page = actor->next_page == actor->pages ? actor->last_page : ERR_PTR(-EIO);
 
        kfree(actor->tmp_buffer);
        kfree(actor);
+
        return last_page;
 }
 static inline void *squashfs_first_page(struct squashfs_page_actor *actor)