staging: erofs: fix error handling when failed to read compresssed data
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: 3883a79abd
("staging: erofs: introduce VLE decompression support")
Cc: <stable@vger.kernel.org> # 4.19+
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
3b9c2f2e0e
Коммит
b6391ac734
|
@ -972,6 +972,7 @@ repeat:
|
|||
overlapped = false;
|
||||
compressed_pages = grp->compressed_pages;
|
||||
|
||||
err = 0;
|
||||
for (i = 0; i < clusterpages; ++i) {
|
||||
unsigned int pagenr;
|
||||
|
||||
|
@ -981,26 +982,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) {
|
||||
|
@ -1198,6 +1212,7 @@ repeat:
|
|||
if (page->mapping == mc) {
|
||||
WRITE_ONCE(grp->compressed_pages[nr], page);
|
||||
|
||||
ClearPageError(page);
|
||||
if (!PagePrivate(page)) {
|
||||
/*
|
||||
* impossible to be !PagePrivate(page) for
|
||||
|
|
Загрузка…
Ссылка в новой задаче