]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Jan 2026 14:01:26 +0000 (15:01 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Jan 2026 14:01:26 +0000 (15:01 +0100)
added patches:
erofs-fix-unexpected-eio-under-memory-pressure.patch

queue-6.18/erofs-fix-unexpected-eio-under-memory-pressure.patch [new file with mode: 0644]
queue-6.18/series

diff --git a/queue-6.18/erofs-fix-unexpected-eio-under-memory-pressure.patch b/queue-6.18/erofs-fix-unexpected-eio-under-memory-pressure.patch
new file mode 100644 (file)
index 0000000..4707063
--- /dev/null
@@ -0,0 +1,132 @@
+From 4012d78562193ef5eb613bad4b0c0fa187637cfe Mon Sep 17 00:00:00 2001
+From: Junbeom Yeom <junbeom.yeom@samsung.com>
+Date: Fri, 19 Dec 2025 21:40:31 +0900
+Subject: erofs: fix unexpected EIO under memory pressure
+
+From: Junbeom Yeom <junbeom.yeom@samsung.com>
+
+commit 4012d78562193ef5eb613bad4b0c0fa187637cfe upstream.
+
+erofs readahead could fail with ENOMEM under the memory pressure because
+it tries to alloc_page with GFP_NOWAIT | GFP_NORETRY, while GFP_KERNEL
+for a regular read. And if readahead fails (with non-uptodate folios),
+the original request will then fall back to synchronous read, and
+`.read_folio()` should return appropriate errnos.
+
+However, in scenarios where readahead and read operations compete,
+read operation could return an unintended EIO because of an incorrect
+error propagation.
+
+To resolve this, this patch modifies the behavior so that, when the
+PCL is for read(which means pcl.besteffort is true), it attempts actual
+decompression instead of propagating the privios error except initial EIO.
+
+- Page size: 4K
+- The original size of FileA: 16K
+- Compress-ratio per PCL: 50% (Uncompressed 8K -> Compressed 4K)
+[page0, page1] [page2, page3]
+[PCL0]---------[PCL1]
+
+- functions declaration:
+  . pread(fd, buf, count, offset)
+  . readahead(fd, offset, count)
+- Thread A tries to read the last 4K
+- Thread B tries to do readahead 8K from 4K
+- RA, besteffort == false
+- R, besteffort == true
+
+        <process A>                   <process B>
+
+pread(FileA, buf, 4K, 12K)
+  do readahead(page3) // failed with ENOMEM
+  wait_lock(page3)
+    if (!uptodate(page3))
+      goto do_read
+                               readahead(FileA, 4K, 8K)
+                               // Here create PCL-chain like below:
+                               // [null, page1] [page2, null]
+                               //   [PCL0:RA]-----[PCL1:RA]
+...
+  do read(page3)        // found [PCL1:RA] and add page3 into it,
+                        // and then, change PCL1 from RA to R
+...
+                               // Now, PCL-chain is as below:
+                               // [null, page1] [page2, page3]
+                               //   [PCL0:RA]-----[PCL1:R]
+
+                                 // try to decompress PCL-chain...
+                                 z_erofs_decompress_queue
+                                   err = 0;
+
+                                   // failed with ENOMEM, so page 1
+                                   // only for RA will not be uptodated.
+                                   // it's okay.
+                                   err = decompress([PCL0:RA], err)
+
+                                   // However, ENOMEM propagated to next
+                                   // PCL, even though PCL is not only
+                                   // for RA but also for R. As a result,
+                                   // it just failed with ENOMEM without
+                                   // trying any decompression, so page2
+                                   // and page3 will not be uptodated.
+                ** BUG HERE ** --> err = decompress([PCL1:R], err)
+
+                                   return err as ENOMEM
+...
+    wait_lock(page3)
+      if (!uptodate(page3))
+        return EIO      <-- Return an unexpected EIO!
+...
+
+Fixes: 2349d2fa02db ("erofs: sunset unneeded NOFAILs")
+Cc: stable@vger.kernel.org
+Reviewed-by: Jaewook Kim <jw5454.kim@samsung.com>
+Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
+Signed-off-by: Junbeom Yeom <junbeom.yeom@samsung.com>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/zdata.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/fs/erofs/zdata.c
++++ b/fs/erofs/zdata.c
+@@ -1262,17 +1262,17 @@ static int z_erofs_parse_in_bvecs(struct
+       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;
+       unsigned int pclusterpages = z_erofs_pclusterpages(pcl);
+       const struct z_erofs_decompressor *decomp =
+                               z_erofs_decomp[pcl->algorithmformat];
+-      int i, j, jtop, err2;
++      bool try_free = true;
++      int i, j, jtop, err2, err = eio ? -EIO : 0;
+       struct page *page;
+       bool overlapped;
+-      bool try_free = true;
+       mutex_lock(&pcl->lock);
+       be->nr_pages = PAGE_ALIGN(pcl->length + pcl->pageofs_out) >> PAGE_SHIFT;
+@@ -1400,12 +1400,12 @@ static int z_erofs_decompress_queue(cons
+               .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;
+ }
index 18b2b3db6218ff459d0d632c7c8f3208af316a3e..172bfd4bca50d0085757bc1982f49e78d284695e 100644 (file)
@@ -302,3 +302,4 @@ drm-xe-svm-fix-a-debug-printout.patch
 drm-pagemap-drm-xe-ensure-that-the-devmem-allocation-is-idle-before-use.patch
 drm-nouveau-dispnv50-don-t-call-drm_atomic_get_crtc_state-in-prepare_fb.patch
 drm-imagination-disallow-exporting-of-pm-fw-protected-objects.patch
+erofs-fix-unexpected-eio-under-memory-pressure.patch