Commit ce93692d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'erofs-for-6.19-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs

Pull erofs fix from Gao Xiang:
 "Junbeom reported that synchronous reads could hit unintended EIOs
  under memory pressure due to incorrect error propagation in
  z_erofs_decompress_queue(), where earlier physical clusters in the
  same decompression queue may be served for another readahead.

  This addresses the issue by decompressing each physical cluster
  independently as long as disk I/Os succeed, rather than being impacted
  by the error status of previous physical clusters in the same queue.

  Summary:

   - Fix unexpected EIOs under memory pressure caused by recent
     incorrect error propagation logic"

* tag 'erofs-for-6.19-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: fix unexpected EIO under memory pressure
parents ebb8719c 4012d785
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1262,7 +1262,7 @@ static int z_erofs_parse_in_bvecs(struct z_erofs_backend *be, bool *overlapped)
	return err;
}

static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, int err)
static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, bool eio)
{
	struct erofs_sb_info *const sbi = EROFS_SB(be->sb);
	struct z_erofs_pcluster *pcl = be->pcl;
@@ -1270,7 +1270,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, int err)
	const struct z_erofs_decompressor *alg =
				z_erofs_decomp[pcl->algorithmformat];
	bool try_free = true;
	int i, j, jtop, err2;
	int i, j, jtop, err2, err = eio ? -EIO : 0;
	struct page *page;
	bool overlapped;
	const char *reason;
@@ -1413,12 +1413,12 @@ static int z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io,
		.pcl = io->head,
	};
	struct z_erofs_pcluster *next;
	int err = io->eio ? -EIO : 0;
	int err = 0;

	for (; be.pcl != Z_EROFS_PCLUSTER_TAIL; be.pcl = next) {
		DBG_BUGON(!be.pcl);
		next = READ_ONCE(be.pcl->next);
		err = z_erofs_decompress_pcluster(&be, err) ?: err;
		err = z_erofs_decompress_pcluster(&be, io->eio) ?: err;
	}
	return err;
}