Skip to content

Commit 2349d2f

Browse files
committed
erofs: sunset unneeded NOFAILs
With iterative development, our codebase can now deal with compressed buffer misses properly if both in-place I/O and compressed buffer allocation fail. Note that if readahead fails (with non-uptodate folios), the original request will then fall back to synchronous read, and `.read_folio()` should return appropriate errnos; otherwise -EIO will be passed to user space, which is unexpected. To simplify rarely encountered failure paths, a mimic decompression will be just used. Before that, failure reasons are recorded in compressed_bvecs[] and they also act as placeholders to avoid in-place pages. They will be parsed just before decompression and then pass back to `.read_folio()`. Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20240905084732.2684515-1-hsiangkao@linux.alibaba.com
1 parent 8bdb6a8 commit 2349d2f

File tree

1 file changed

+31
-26
lines changed

1 file changed

+31
-26
lines changed

fs/erofs/zdata.c

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,9 +1154,10 @@ static int z_erofs_parse_in_bvecs(struct z_erofs_decompress_backend *be,
11541154
struct z_erofs_bvec *bvec = &pcl->compressed_bvecs[i];
11551155
struct page *page = bvec->page;
11561156

1157-
/* compressed data ought to be valid before decompressing */
1158-
if (!page) {
1159-
err = -EIO;
1157+
/* compressed data ought to be valid when decompressing */
1158+
if (IS_ERR(page) || !page) {
1159+
bvec->page = NULL; /* clear the failure reason */
1160+
err = page ? PTR_ERR(page) : -EIO;
11601161
continue;
11611162
}
11621163
be->compressed_pages[i] = page;
@@ -1232,8 +1233,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,
12321233
.inplace_io = overlapped,
12331234
.partial_decoding = pcl->partial,
12341235
.fillgaps = pcl->multibases,
1235-
.gfp = pcl->besteffort ?
1236-
GFP_KERNEL | __GFP_NOFAIL :
1236+
.gfp = pcl->besteffort ? GFP_KERNEL :
12371237
GFP_NOWAIT | __GFP_NORETRY
12381238
}, be->pagepool);
12391239

@@ -1297,8 +1297,8 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,
12971297
return err;
12981298
}
12991299

1300-
static void z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io,
1301-
struct page **pagepool)
1300+
static int z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io,
1301+
struct page **pagepool)
13021302
{
13031303
struct z_erofs_decompress_backend be = {
13041304
.sb = io->sb,
@@ -1307,19 +1307,21 @@ static void z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io,
13071307
LIST_HEAD_INIT(be.decompressed_secondary_bvecs),
13081308
};
13091309
z_erofs_next_pcluster_t owned = io->head;
1310+
int err = io->eio ? -EIO : 0;
13101311

13111312
while (owned != Z_EROFS_PCLUSTER_TAIL) {
13121313
DBG_BUGON(owned == Z_EROFS_PCLUSTER_NIL);
13131314

13141315
be.pcl = container_of(owned, struct z_erofs_pcluster, next);
13151316
owned = READ_ONCE(be.pcl->next);
13161317

1317-
z_erofs_decompress_pcluster(&be, io->eio ? -EIO : 0);
1318+
err = z_erofs_decompress_pcluster(&be, err) ?: err;
13181319
if (z_erofs_is_inline_pcluster(be.pcl))
13191320
z_erofs_free_pcluster(be.pcl);
13201321
else
13211322
erofs_workgroup_put(&be.pcl->obj);
13221323
}
1324+
return err;
13231325
}
13241326

13251327
static void z_erofs_decompressqueue_work(struct work_struct *work)
@@ -1462,17 +1464,21 @@ static void z_erofs_fill_bio_vec(struct bio_vec *bvec,
14621464
folio_unlock(folio);
14631465
folio_put(folio);
14641466
out_allocfolio:
1465-
page = erofs_allocpage(&f->pagepool, gfp | __GFP_NOFAIL);
1467+
page = erofs_allocpage(&f->pagepool, gfp);
14661468
spin_lock(&pcl->obj.lockref.lock);
14671469
if (unlikely(pcl->compressed_bvecs[nr].page != zbv.page)) {
1468-
erofs_pagepool_add(&f->pagepool, page);
1470+
if (page)
1471+
erofs_pagepool_add(&f->pagepool, page);
14691472
spin_unlock(&pcl->obj.lockref.lock);
14701473
cond_resched();
14711474
goto repeat;
14721475
}
1473-
bvec->bv_page = pcl->compressed_bvecs[nr].page = page;
1474-
folio = page_folio(page);
1476+
pcl->compressed_bvecs[nr].page = page ? page : ERR_PTR(-ENOMEM);
14751477
spin_unlock(&pcl->obj.lockref.lock);
1478+
bvec->bv_page = page;
1479+
if (!page)
1480+
return;
1481+
folio = page_folio(page);
14761482
out_tocache:
14771483
if (!tocache || bs != PAGE_SIZE ||
14781484
filemap_add_folio(mc, folio, pcl->obj.index + nr, gfp)) {
@@ -1698,26 +1704,28 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f,
16981704
z_erofs_decompress_kickoff(q[JQ_SUBMIT], nr_bios);
16991705
}
17001706

1701-
static void z_erofs_runqueue(struct z_erofs_decompress_frontend *f,
1702-
bool force_fg, bool ra)
1707+
static int z_erofs_runqueue(struct z_erofs_decompress_frontend *f,
1708+
unsigned int ra_folios)
17031709
{
17041710
struct z_erofs_decompressqueue io[NR_JOBQUEUES];
1711+
struct erofs_sb_info *sbi = EROFS_I_SB(f->inode);
1712+
bool force_fg = z_erofs_is_sync_decompress(sbi, ra_folios);
1713+
int err;
17051714

17061715
if (f->owned_head == Z_EROFS_PCLUSTER_TAIL)
1707-
return;
1708-
z_erofs_submit_queue(f, io, &force_fg, ra);
1716+
return 0;
1717+
z_erofs_submit_queue(f, io, &force_fg, !!ra_folios);
17091718

17101719
/* handle bypass queue (no i/o pclusters) immediately */
1711-
z_erofs_decompress_queue(&io[JQ_BYPASS], &f->pagepool);
1712-
1720+
err = z_erofs_decompress_queue(&io[JQ_BYPASS], &f->pagepool);
17131721
if (!force_fg)
1714-
return;
1722+
return err;
17151723

17161724
/* wait until all bios are completed */
17171725
wait_for_completion_io(&io[JQ_SUBMIT].u.done);
17181726

17191727
/* handle synchronous decompress queue in the caller context */
1720-
z_erofs_decompress_queue(&io[JQ_SUBMIT], &f->pagepool);
1728+
return z_erofs_decompress_queue(&io[JQ_SUBMIT], &f->pagepool) ?: err;
17211729
}
17221730

17231731
/*
@@ -1779,7 +1787,6 @@ static void z_erofs_pcluster_readmore(struct z_erofs_decompress_frontend *f,
17791787
static int z_erofs_read_folio(struct file *file, struct folio *folio)
17801788
{
17811789
struct inode *const inode = folio->mapping->host;
1782-
struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
17831790
struct z_erofs_decompress_frontend f = DECOMPRESS_FRONTEND_INIT(inode);
17841791
int err;
17851792

@@ -1791,9 +1798,8 @@ static int z_erofs_read_folio(struct file *file, struct folio *folio)
17911798
z_erofs_pcluster_readmore(&f, NULL, false);
17921799
z_erofs_pcluster_end(&f);
17931800

1794-
/* if some compressed cluster ready, need submit them anyway */
1795-
z_erofs_runqueue(&f, z_erofs_is_sync_decompress(sbi, 0), false);
1796-
1801+
/* if some pclusters are ready, need submit them anyway */
1802+
err = z_erofs_runqueue(&f, 0) ?: err;
17971803
if (err && err != -EINTR)
17981804
erofs_err(inode->i_sb, "read error %d @ %lu of nid %llu",
17991805
err, folio->index, EROFS_I(inode)->nid);
@@ -1806,7 +1812,6 @@ static int z_erofs_read_folio(struct file *file, struct folio *folio)
18061812
static void z_erofs_readahead(struct readahead_control *rac)
18071813
{
18081814
struct inode *const inode = rac->mapping->host;
1809-
struct erofs_sb_info *const sbi = EROFS_I_SB(inode);
18101815
struct z_erofs_decompress_frontend f = DECOMPRESS_FRONTEND_INIT(inode);
18111816
struct folio *head = NULL, *folio;
18121817
unsigned int nr_folios;
@@ -1836,7 +1841,7 @@ static void z_erofs_readahead(struct readahead_control *rac)
18361841
z_erofs_pcluster_readmore(&f, rac, false);
18371842
z_erofs_pcluster_end(&f);
18381843

1839-
z_erofs_runqueue(&f, z_erofs_is_sync_decompress(sbi, nr_folios), true);
1844+
(void)z_erofs_runqueue(&f, nr_folios);
18401845
erofs_put_metabuf(&f.map.buf);
18411846
erofs_release_pages(&f.pagepool);
18421847
}

0 commit comments

Comments
 (0)