bio_put(bio);
 }
 
-static struct bio *erofs_grab_raw_bio(struct super_block *sb,
-                                     erofs_blk_t blkaddr,
-                                     unsigned int nr_pages,
-                                     bool ismeta)
-{
-       struct bio *bio = bio_alloc(GFP_NOIO, nr_pages);
-
-       bio->bi_end_io = erofs_readendio;
-       bio_set_dev(bio, sb->s_bdev);
-       bio->bi_iter.bi_sector = (sector_t)blkaddr << LOG_SECTORS_PER_BLOCK;
-       if (ismeta)
-               bio->bi_opf = REQ_OP_READ | REQ_META;
-       else
-               bio->bi_opf = REQ_OP_READ;
-
-       return bio;
-}
-
 struct page *erofs_get_meta_page(struct super_block *sb, erofs_blk_t blkaddr)
 {
        struct inode *const bd_inode = sb->s_bdev->bd_inode;
        struct address_space *const mapping = bd_inode->i_mapping;
-       const gfp_t gfp = mapping_gfp_constraint(mapping, ~__GFP_FS);
-       struct page *page;
-       int err;
-
-repeat:
-       page = find_or_create_page(mapping, blkaddr, gfp);
-       if (!page)
-               return ERR_PTR(-ENOMEM);
-
-       DBG_BUGON(!PageLocked(page));
-
-       if (!PageUptodate(page)) {
-               struct bio *bio;
-
-               bio = erofs_grab_raw_bio(sb, blkaddr, 1, true);
-
-               if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
-                       err = -EFAULT;
-                       goto err_out;
-               }
-
-               submit_bio(bio);
-               lock_page(page);
 
-               /* this page has been truncated by others */
-               if (page->mapping != mapping) {
-                       unlock_page(page);
-                       put_page(page);
-                       goto repeat;
-               }
-
-               /* more likely a read error */
-               if (!PageUptodate(page)) {
-                       err = -EIO;
-                       goto err_out;
-               }
-       }
-       return page;
-
-err_out:
-       unlock_page(page);
-       put_page(page);
-       return ERR_PTR(err);
+       return read_cache_page_gfp(mapping, blkaddr,
+                                  mapping_gfp_constraint(mapping, ~__GFP_FS));
 }
 
 static int erofs_map_blocks_flatmode(struct inode *inode,
                if (nblocks > BIO_MAX_PAGES)
                        nblocks = BIO_MAX_PAGES;
 
-               bio = erofs_grab_raw_bio(sb, blknr, nblocks, false);
+               bio = bio_alloc(GFP_NOIO, nblocks);
+
+               bio->bi_end_io = erofs_readendio;
+               bio_set_dev(bio, sb->s_bdev);
+               bio->bi_iter.bi_sector = (sector_t)blknr <<
+                       LOG_SECTORS_PER_BLOCK;
+               bio->bi_opf = REQ_OP_READ;
        }
 
        err = bio_add_page(bio, page, PAGE_SIZE, 0);