5.0-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Gao Xiang <gaoxian...@huawei.com>

commit b6391ac73400eff38377a4a7364bd3df5efb5178 upstream.

Complete read error handling paths for all three kinds of
compressed pages:

 1) For cache-managed pages, PG_uptodate will be checked since
    read_endio will unlock and SetPageUptodate for these pages;

 2) For inplaced pages, read_endio cannot SetPageUptodate directly
    since it should be used to mark the final decompressed data,
    PG_error will be set with page locked for IO error instead;

 3) For staging pages, PG_error is used, which is similar to
    what we do for inplaced pages.

Fixes: 3883a79abd02 ("staging: erofs: introduce VLE decompression support")
Cc: <sta...@vger.kernel.org> # 4.19+
Reviewed-by: Chao Yu <yuch...@huawei.com>
Signed-off-by: Gao Xiang <gaoxian...@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/staging/erofs/unzip_vle.c |   41 +++++++++++++++++++++++++-------------
 1 file changed, 28 insertions(+), 13 deletions(-)

--- a/drivers/staging/erofs/unzip_vle.c
+++ b/drivers/staging/erofs/unzip_vle.c
@@ -977,6 +977,7 @@ repeat:
        overlapped = false;
        compressed_pages = grp->compressed_pages;
 
+       err = 0;
        for (i = 0; i < clusterpages; ++i) {
                unsigned int pagenr;
 
@@ -986,26 +987,39 @@ repeat:
                DBG_BUGON(!page);
                DBG_BUGON(!page->mapping);
 
-               if (z_erofs_is_stagingpage(page))
-                       continue;
+               if (!z_erofs_is_stagingpage(page)) {
 #ifdef EROFS_FS_HAS_MANAGED_CACHE
-               if (page->mapping == MNGD_MAPPING(sbi)) {
-                       DBG_BUGON(!PageUptodate(page));
-                       continue;
-               }
+                       if (page->mapping == MNGD_MAPPING(sbi)) {
+                               if (unlikely(!PageUptodate(page)))
+                                       err = -EIO;
+                               continue;
+                       }
 #endif
 
-               /* only non-head page could be reused as a compressed page */
-               pagenr = z_erofs_onlinepage_index(page);
+                       /*
+                        * only if non-head page can be selected
+                        * for inplace decompression
+                        */
+                       pagenr = z_erofs_onlinepage_index(page);
+
+                       DBG_BUGON(pagenr >= nr_pages);
+                       DBG_BUGON(pages[pagenr]);
+                       ++sparsemem_pages;
+                       pages[pagenr] = page;
 
-               DBG_BUGON(pagenr >= nr_pages);
-               DBG_BUGON(pages[pagenr]);
-               ++sparsemem_pages;
-               pages[pagenr] = page;
+                       overlapped = true;
+               }
 
-               overlapped = true;
+               /* PG_error needs checking for inplaced and staging pages */
+               if (unlikely(PageError(page))) {
+                       DBG_BUGON(PageUptodate(page));
+                       err = -EIO;
+               }
        }
 
+       if (unlikely(err))
+               goto out;
+
        llen = (nr_pages << PAGE_SHIFT) - work->pageofs;
 
        if (z_erofs_vle_workgrp_fmt(grp) == Z_EROFS_VLE_WORKGRP_FMT_PLAIN) {
@@ -1203,6 +1217,7 @@ repeat:
        if (page->mapping == mc) {
                WRITE_ONCE(grp->compressed_pages[nr], page);
 
+               ClearPageError(page);
                if (!PagePrivate(page)) {
                        /*
                         * impossible to be !PagePrivate(page) for


Reply via email to