+static struct page **z_erofs_parse_in_bvecs(struct erofs_sb_info *sbi,
+ struct z_erofs_pcluster *pcl, struct page **pages,
+ struct page **pagepool, bool *overlapped)
+{
+ unsigned int pclusterpages = z_erofs_pclusterpages(pcl);
+ struct page **compressed_pages;
+ int i, err = 0;
+
+ /* XXX: will have a better approach in the following commits */
+ compressed_pages = kmalloc_array(pclusterpages, sizeof(struct page *),
+ GFP_KERNEL | __GFP_NOFAIL);
+ *overlapped = false;
+
+ for (i = 0; i < pclusterpages; ++i) {
+ unsigned int pagenr;
+ struct page *page = pcl->compressed_pages[i];
+
+ /* compressed pages ought to be present before decompressing */
+ if (!page) {
+ DBG_BUGON(1);
+ continue;
+ }
+ compressed_pages[i] = page;
+
+ if (z_erofs_is_inline_pcluster(pcl)) {
+ if (!PageUptodate(page))
+ err = -EIO;
+ continue;
+ }
+
+ DBG_BUGON(z_erofs_page_is_invalidated(page));
+ if (!z_erofs_is_shortlived_page(page)) {
+ if (erofs_page_is_managed(sbi, page)) {
+ if (!PageUptodate(page))
+ err = -EIO;
+ continue;
+ }
+
+ /*
+ * only if non-head page can be selected
+ * for inplace decompression
+ */
+ pagenr = z_erofs_onlinepage_index(page);
+
+ DBG_BUGON(pagenr >= pcl->nr_pages);
+ if (pages[pagenr]) {
+ DBG_BUGON(1);
+ SetPageError(pages[pagenr]);
+ z_erofs_onlinepage_endio(pages[pagenr]);
+ err = -EFSCORRUPTED;
+ }
+ pages[pagenr] = page;
+
+ *overlapped = true;
+ }
+
+ /* PG_error needs checking for all non-managed pages */
+ if (PageError(page)) {
+ DBG_BUGON(PageUptodate(page));
+ err = -EIO;
+ }
+ }
+
+ if (err) {
+ kfree(compressed_pages);
+ return ERR_PTR(err);
+ }
+ return compressed_pages;
+}
+