[PATCH AUTOSEL 6.18-5.10] jfs: handle set_blocksize failures
From: Sasha Levin
Date: Mon Aug 31 2026 - 11:45:47 EST
From: Christoph Hellwig <hch@xxxxxx>
[ Upstream commit 05107f5602751fcfd3d108c1f579eb45aabead52 ]
jfs uses buffer_heads, which don't handle block size > PAGE_SIZE well.
Without this, mounting we will hit the
BUG_ON(offset >= folio_size(folio));
in folio_set_bh on the first __bread_gfp call.
Signed-off-by: Christoph Hellwig <hch@xxxxxx>
Link: https://patch.msgid.link/20260511071701.2456211-5-hch@xxxxxx
Signed-off-by: Christian Brauner (Amutable) <brauner@xxxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
LLM Generated explanations, may be completely bogus:
## Phase 1: Commit Message Forensics
**Step 1.1 — Subject line**
Record: `[jfs]` `[handle]` — Handle `sb_set_blocksize()` failures during
JFS mount.
**Step 1.2 — Tags**
Record:
- **Signed-off-by:** Christoph Hellwig `<hch@xxxxxx>` (author)
- **Signed-off-by:** Christian Brauner (Amutable) `<brauner@xxxxxxxxxx>`
(merger)
- **Link:** https://patch.msgid.link/20260511071701.2456211-5-hch@xxxxxx
- No Fixes:, Reported-by:, Tested-by:, Reviewed-by:, Cc: stable
- Part of series **"[PATCH 04/10] jfs: handle set_blocksize failures"**
in *"fix crashes when mounting legacy file system with sector size >
PAGE_SIZE"*
**Step 1.3 — Body analysis**
Record:
- **Bug:** JFS ignores `sb_set_blocksize(sb, PSIZE)` failure and
continues mounting.
- **Symptom:** Kernel `BUG_ON(offset >= folio_size(folio))` in
`folio_set_bh()` on the first `__bread_gfp()` call during mount.
- **Root cause:** JFS uses buffer_heads, which do not handle block sizes
> `PAGE_SIZE`. When `sb_set_blocksize()` fails (e.g. device logical
block size is 64K and JFS tries to set 4K), `sb->s_blocksize` stays at
the device size from `setup_bdev_super()`. Mount proceeds and buffer
allocation crashes.
- **Trigger context (cover letter):** Mount/probe on a 64K-sector loop
device with JFS built-in.
**Step 1.4 — Hidden bug fix?**
Record: **Yes.** Despite the neutral "handle" wording, this is a real
crash fix, not cleanup. Same pattern as ext4, UFS, minix, etc.
---
## Phase 2: Diff Analysis
**Step 2.1 — Inventory**
Record:
- **File:** `fs/jfs/super.c` (+2 / −1)
- **Function:** `jfs_fill_super()`
- **Scope:** Single-file, surgical (3-line hunk)
**Step 2.2 — Code flow change**
Record:
- **Before:** `sb_set_blocksize(sb, PSIZE);` — return value ignored;
mount continues on failure.
- **After:** `if (!sb_set_blocksize(sb, PSIZE)) goto out_unload;` —
failed blocksize setup aborts mount via existing cleanup path.
- **Path affected:** Mount initialization, before `jfs_mount()` →
`readSuper()` → `sb_bread()`.
**Step 2.3 — Bug mechanism**
Record: **Logic / error-path fix.** Category: missing error handling
leading to **kernel BUG**.
- `sb_set_blocksize()` returns 0 on failure (`block/bdev.c:220-229`).
- On failure, `sb->s_blocksize` is not updated to `PSIZE` (4096).
- `sb_bread()` uses `sb->s_blocksize`
(`include/linux/buffer_head.h:346`).
- Buffer allocation reaches `folio_set_bh()` with invalid offset vs
folio size → `BUG_ON` (`fs/buffer.c:1582`).
**Step 2.4 — Fix quality**
Record: **Obviously correct.** Matches ext4/ufs/minix pattern. Minimal
risk; `out_unload` already exists and returns `ret = -EINVAL`. No new
locks or APIs.
---
## Phase 3: Git History Investigation
**Step 3.1 — Blame**
Record: Unchecked `sb_set_blocksize(sb, PSIZE)` dates to initial JFS
import (`1da177e4c3f4`, 2005). Bug has been present for the lifetime of
JFS in-tree.
**Step 3.2 — Fixes: tag**
Record: N/A — no Fixes: tag.
**Step 3.3 — Related file history**
Record: Recent `fs/jfs/super.c` changes are mount-API and cleanup only;
none address this. Mainline merge `d90e60ced4c3c` ("fix crashes when
mounting legacy file system with sector size > PAGE_SIZE") contains this
fix but is **not** an ancestor of this tree's HEAD.
**Step 3.4 — Author context**
Record: Christoph Hellwig — senior VFS/filesystem developer. Series
merged by VFS maintainer Christian Brauner. Jan Kara reviewed sibling
patches in the series.
**Step 3.5 — Dependencies**
Record: **Standalone.** Patch 4/10 is independent per filesystem. No
prerequisite commits required for the JFS hunk. Applies cleanly to
current `fs/jfs/super.c` at line 494.
---
## Phase 4: Mailing List and External Research
**Step 4.1 — Original discussion**
Record: Series cover at https://ratatoskr.run/linux-
fsdevel/2026/05/8994157. JFS patch at https://ratatoskr.run/linux-
fsdevel/2026/05/8994161 / spinics msg338004. `b4 dig -c` could not be
used (commit not in this tree). lore.kernel.org blocked by bot
protection.
**Step 4.2 — Reviewers**
Record: Christian Brauner merged the series. Jan Kara reviewed
minix/isofs/bfs patches. David Sterba reviewed affs. No NAKs found.
**Step 4.3 — Bug report**
Record: Author-reproduced crash during FS probe on 64K loop device. No
syzbot report. Real, reproducible trigger described in cover letter.
**Step 4.4 — Series context**
Record: 10-patch series, one filesystem each. JFS patch is self-
contained; other patches not required for this fix.
**Step 4.5 — Stable list**
Record: No stable-list discussion found. Not a negative signal per
instructions.
---
## Phase 5: Code Semantic Analysis
**Step 5.1 — Key functions**
Record: `jfs_fill_super()`, `sb_set_blocksize()`, `jfs_mount()` →
`readSuper()` → `sb_bread()` → `__bread_gfp()` → `bdev_getblk()` →
`grow_buffers()` → `folio_alloc_buffers()` → `folio_set_bh()`.
**Step 5.2 — Callers**
Record: `jfs_fill_super()` called from `get_tree_bdev()`
(`fs/jfs/super.c:635`) during `mount(2)` or filesystem probe. Reachable
from userspace.
**Step 5.3 — Callees**
Record: `sb_set_blocksize()` → `set_blocksize()` →
`bdev_validate_blocksize()`. Fails when requested size < device logical
block size.
**Step 5.4 — Call chain / reachability**
Record: `mount`/`fsopen` → `jfs_get_tree` → `get_tree_bdev` →
`setup_bdev_super` (sets device blocksize) → `jfs_fill_super` →
`jfs_mount` → `sb_bread`. **Userspace-reachable** when `CONFIG_JFS_FS`
is enabled (built-in or module).
**Step 5.5 — Similar patterns**
Record: ext4 (`fs/ext4/super.c:5128`), ufs (`fs/ufs/super.c:927`),
minix, romfs, ocfs2, f2fs all check `sb_set_blocksize()` return value.
JFS was an outlier.
---
## Phase 6: Cross-Reference Against Local Tree (v6.18.44)
**Step 6.1 — Buggy code present?**
Record: **Yes.** Current tree at `fs/jfs/super.c:494` has unchecked
`sb_set_blocksize(sb, PSIZE);`. `folio_set_bh()` BUG_ON present since
`465e5e6a1698f` (in this tree). `sb_set_blocksize()` failure semantics
unchanged in `block/bdev.c:220-229`.
**Step 6.2 — Backport complications**
Record: **Clean apply expected.** Only the 3-line hunk at line 494; no
conflicts with recent stable changes in this file.
**Step 6.3 — Related fixes already present?**
Record: **No.** `git merge-base --is-ancestor d90e60ced4c3c HEAD` → not
ancestor. Sibling fixes in hpfs/bfs also absent. Fix not yet in 6.18.y.
---
## Phase 7: Subsystem and Maintainer Context
**Step 7.1 — Subsystem**
Record: **fs/jfs** — legacy filesystem driver. Criticality:
**IMPORTANT** (not core VFS, but mount path can kernel-BUG the system).
**Step 7.2 — Activity**
Record: Low churn; mature driver. Bug is long-standing, exposed when
large-sector devices are probed.
---
## Phase 8: Impact and Risk Assessment
**Step 8.1 — Who is affected**
Record: Users with `CONFIG_JFS_FS` enabled (built-in or module) mounting
or probing JFS on block devices whose logical sector size prevents
setting 4K (e.g. 64K sectors).
**Step 8.2 — Trigger conditions**
Record: Mount or auto-probe of JFS on device with sector size >
`PAGE_SIZE` or where `sb_set_blocksize(4096)` fails. Unprivileged users
can trigger via `mount` if permitted, or during blkid/probe workflows.
Not extremely common hardware, but loop devices and some storage make it
realistic.
**Step 8.3 — Failure mode severity**
Record: **Kernel BUG()** — system crash/oops. Severity: **CRITICAL**.
**Step 8.4 — Risk vs benefit**
Record:
- **Benefit:** HIGH — prevents kernel crash; graceful mount failure with
`-EINVAL`.
- **Risk:** VERY LOW — 2 lines, established pattern, existing cleanup
path.
- **Ratio:** Strongly favors backport.
---
## Phase 9: Final Synthesis
**Evidence FOR:**
- Real, author-verified kernel BUG on mount/probe
- Long-standing bug in widely shipped legacy FS
- Surgical 2-line fix, obviously correct
- Matches pattern already used by ext4, ufs, etc. in this tree
- Merged to mainline by VFS maintainer
- Buggy code confirmed present in v6.18.44
- Clean apply, no dependencies
**Evidence AGAINST:**
- JFS is a legacy/rare filesystem → lower population
- Trigger requires specific block-device geometry
- None of these outweigh a kernel BUG fix
**Stable rules checklist:**
1. Obviously correct and tested? **PASS** (mainline merged; author
tested crash scenario)
2. Fixes real user-affecting bug? **PASS**
3. Important issue? **PASS** (kernel BUG / crash)
4. Small and contained? **PASS** (3 lines, 1 file)
5. No new features/APIs? **PASS**
6. Can apply to local tree? **PASS**
**Exception category:** N/A (standard bug fix, not device-
ID/quirk/build/doc).
---
## Problem Summary for Stable Users
When JFS mount calls `sb_set_blocksize(sb, 4096)` on a device whose
logical sector size is larger (e.g. 64K loop device), the call fails
silently. Mount continues with the device's block size. The first
`sb_bread()` during `jfs_mount()` hits `BUG_ON(offset >=
folio_size(folio))` in `folio_set_bh()`, crashing the kernel. The fix
checks the return value and aborts mount through the existing
`out_unload` path, returning `-EINVAL` instead of crashing.
---
## Verification
- **[Phase 1]** Parsed subject, tags, body; identified series context
via ratatoskr/spinics
- **[Phase 2]** Diff: 3-line error-check in `jfs_fill_super()`;
classified as missing error handling → BUG
- **[Phase 3]** `git blame`: unchecked call since 2005 (`1da177e4c3f4`)
- **[Phase 3]** `git merge-base --is-ancestor d90e60ced4c3c HEAD` → not
ancestor (fix absent from 6.18.y)
- **[Phase 3]** `git show d90e60ced4c3c:fs/jfs/super.c` → confirms
mainline has the fix
- **[Phase 3]** `git diff d90e60ced4c3c -- fs/jfs/super.c` → only
relevant hunk is the sb_set_blocksize check
- **[Phase 4]** Series cover and patch content from ratatoskr.run;
Christian Brauner merge confirmed
- **[Phase 4]** lore.kernel.org / patch.msgid.link blocked; b4 dig
unusable without commit in tree
- **[Phase 5]** Traced call chain: `jfs_fill_super` → `jfs_mount` →
`readSuper` → `sb_bread` → `__bread_gfp`
- **[Phase 5]** Read `sb_set_blocksize()` at `block/bdev.c:220-229`
(returns 0 on failure)
- **[Phase 5]** Read `folio_set_bh()` BUG_ON at `fs/buffer.c:1582`
- **[Phase 5]** Read `sb_bread` macro at
`include/linux/buffer_head.h:344-346`
- **[Phase 5]** Compared ext4 pattern at `fs/ext4/super.c:5128`
- **[Phase 6]** `git describe HEAD` → v6.18.44; buggy code at
`fs/jfs/super.c:494`
- **[Phase 6]** `folio_set_bh` ancestor check: `465e5e6a1698f` is in
tree
- **[Phase 6]** hpfs/bfs sibling fixes also absent (confirming series
not backported)
- **[Phase 8]** Failure mode: kernel BUG; severity CRITICAL
**YES**The background checks confirmed what the analysis relied on:
- **Grep for related commits** in this tree’s history returned nothing —
the “handle set_blocksize failures” fix isn’t already in 6.18.y.
- **Merge commit `d90e60c`** (the mainline series that includes this JFS
patch) exists in the repo but is **not an ancestor of HEAD**
(v6.18.44). Mainline has the fix; this stable tree still has the
unchecked `sb_set_blocksize(sb, PSIZE)` at `fs/jfs/super.c:494`.
That supports the **YES** backport recommendation: the bug is present
here, the fix is small and self-contained, and it should apply cleanly.
fs/jfs/super.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 3cfb86c5a36e8..20b66fb022244 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -491,7 +491,8 @@ static int jfs_fill_super(struct super_block *sb, struct fs_context *fc)
/*
* Initialize blocksize to 4K.
*/
- sb_set_blocksize(sb, PSIZE);
+ if (!sb_set_blocksize(sb, PSIZE))
+ goto out_unload;
/*
* Set method vectors.
--
2.53.0