--- /dev/null
+From 5ff79e8bdc75db51e30298a75939e2308e7658e0 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro@orcam.me.uk>
+Date: Wed, 6 May 2026 23:42:23 +0100
+Subject: MIPS: DEC: Ensure 32-bit stack location for o32 prom_printf()
+
+From: Maciej W. Rozycki <macro@orcam.me.uk>
+
+commit 5ff79e8bdc75db51e30298a75939e2308e7658e0 upstream.
+
+In 64-bit configurations calling any firmware entry points from a kernel
+thread other than the initial one will result in a situation where the
+stack has been placed in the XKPHYS 64-bit memory segment.
+
+Consequently the stack pointer is no longer a 32-bit value and when the
+32-bit firmware code called uses 32-bit ALU operations to manipulate the
+stack pointer, the calculated result is incorrect (in fact in the 64-bit
+MIPS ISA almost all 32-bit ALU operations will produce an unpredictable
+result when executed on 64-bit data) and control goes astray.
+
+This may happen when no final console driver has been enabled in the
+configuration and consequently the initial console continues being used
+late into bootstrap, or with an upcoming change that will switch the zs
+driver to use a platform device, which in turn will make the console
+handover happen only after other kernel threads have already been
+started, and the kernel will hang at:
+
+ pid_max: default: 32768 minimum: 301
+
+or somewhat later, but always before:
+
+ cblist_init_generic: Setting adjustable number of callback queues.
+
+has been printed.
+
+It seems that only the prom_printf() entry point is affected. Of all
+the other entry points wired only rex_slot_address() and rex_gettcinfo()
+are called from a kernel thread other than the initial one, specifically
+kernel_init(), and they are leaf functions that do no business with the
+stack, having worked with no issue ever since 64-bit support was added
+for the platform back in 2002.
+
+To address this issue then, arrange for the stack to be switched in the
+o32 wrapper as required for prom_printf() only, by supplying call_o32()
+with a pointer to a chunk of initdata space, which is placed in the
+CKSEG0 32-bit compatibility segment, observing that prom_printf() is
+only called from console output handler and therefore with the console
+lock held, implying no need for this code to be reentrant.
+
+Other firmware entry points may be called with interrupts enabled and no
+lock held, and may therefore require that call_o32() be reentrant. They
+trigger no issue at this point and "if it ain't broke, don't fix it," so
+just leave them alone.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk>
+Cc: stable@vger.kernel.org # v2.6.12+
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/dec/prom/init.c | 6 +++++-
+ arch/mips/include/asm/dec/prom.h | 15 +++++++++++++--
+ 2 files changed, 18 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/dec/prom/init.c
++++ b/arch/mips/dec/prom/init.c
+@@ -3,7 +3,7 @@
+ * init.c: PROM library initialisation code.
+ *
+ * Copyright (C) 1998 Harald Koerfgen
+- * Copyright (C) 2002, 2004 Maciej W. Rozycki
++ * Copyright (C) 2002, 2004, 2026 Maciej W. Rozycki
+ */
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -20,6 +20,10 @@
+ #include <asm/dec/prom.h>
+
+
++#ifdef CONFIG_64BIT
++unsigned long o32_stk[O32_STK_SIZE] __initdata = { 0 };
++#endif
++
+ int (*__rex_bootinit)(void);
+ int (*__rex_bootread)(void);
+ int (*__rex_getbitmap)(memmap *);
+--- a/arch/mips/include/asm/dec/prom.h
++++ b/arch/mips/include/asm/dec/prom.h
+@@ -4,7 +4,7 @@
+ *
+ * DECstation PROM interface.
+ *
+- * Copyright (C) 2002 Maciej W. Rozycki
++ * Copyright (C) 2002, 2026 Maciej W. Rozycki
+ *
+ * Based on arch/mips/dec/prom/prom.h by the Anonymous.
+ */
+@@ -97,6 +97,17 @@ extern int (*__pmax_close)(int);
+
+ #ifdef CONFIG_64BIT
+
++#define O32_STK_SIZE 512
++extern unsigned long o32_stk[];
++
++/* Switch the stack if outside the 32-bit address space. */
++static inline unsigned long *o32_get_stk(void)
++{
++ long fp = (long)__builtin_frame_address(0);
++
++ return fp != (int)fp ? o32_stk + O32_STK_SIZE : NULL;
++}
++
+ /*
+ * On MIPS64 we have to call PROM functions via a helper
+ * dispatcher to accommodate ABI incompatibilities.
+@@ -128,7 +139,7 @@ int __DEC_PROM_O32(_prom_printf, (int (*
+
+ #define prom_getchar() _prom_getchar(__prom_getchar, NULL)
+ #define prom_getenv(x) _prom_getenv(__prom_getenv, NULL, x)
+-#define prom_printf(x...) _prom_printf(__prom_printf, NULL, x)
++#define prom_printf(x...) _prom_printf(__prom_printf, o32_get_stk(), x)
+
+ #else /* !CONFIG_64BIT */
+
--- /dev/null
+From b82930a4c5dbc5c4df39c0f93d968c239f2c6885 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 24 Apr 2026 12:28:47 +0200
+Subject: MIPS: ip22-gio: fix device reference leak in probe
+
+From: Johan Hovold <johan@kernel.org>
+
+commit b82930a4c5dbc5c4df39c0f93d968c239f2c6885 upstream.
+
+The gio probe function needlessly takes a device reference which is
+never released and therefore prevents unbound gio devices from being
+freed.
+
+Fixes: e84de0c61905 ("MIPS: GIO bus support for SGI IP22/28")
+Cc: stable@vger.kernel.org # 3.3
+Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/sgi-ip22/ip22-gio.c | 4 ----
+ 1 file changed, 4 deletions(-)
+
+--- a/arch/mips/sgi-ip22/ip22-gio.c
++++ b/arch/mips/sgi-ip22/ip22-gio.c
+@@ -133,13 +133,9 @@ static int gio_device_probe(struct devic
+ if (!drv->probe)
+ return error;
+
+- gio_dev_get(gio_dev);
+-
+ match = gio_match_device(drv->id_table, gio_dev);
+ if (match)
+ error = drv->probe(gio_dev, match);
+- if (error)
+- gio_dev_put(gio_dev);
+
+ return error;
+ }
--- /dev/null
+From 7de9a1b45f5a95b58145653c525c8fb80292d9ab Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 24 Apr 2026 12:28:46 +0200
+Subject: MIPS: ip22-gio: fix gio device memory leak
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 7de9a1b45f5a95b58145653c525c8fb80292d9ab upstream.
+
+The gio device release callback was never wired up so gio devices are
+not freed when the last reference is dropped.
+
+Fixes: e84de0c61905 ("MIPS: GIO bus support for SGI IP22/28")
+Cc: stable@vger.kernel.org # 3.3
+Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/sgi-ip22/ip22-gio.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/mips/sgi-ip22/ip22-gio.c
++++ b/arch/mips/sgi-ip22/ip22-gio.c
+@@ -101,6 +101,8 @@ int gio_device_register(struct gio_devic
+ {
+ giodev->dev.bus = &gio_bus_type;
+ giodev->dev.parent = &gio_bus;
++ giodev->dev.release = gio_release_dev;
++
+ return device_register(&giodev->dev);
+ }
+ EXPORT_SYMBOL_GPL(gio_device_register);
--- /dev/null
+From c62cdd3e919bdf84c37ec46810f87cdb1736e822 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 24 Apr 2026 12:28:45 +0200
+Subject: MIPS: ip22-gio: fix kfree() of static object
+
+From: Johan Hovold <johan@kernel.org>
+
+commit c62cdd3e919bdf84c37ec46810f87cdb1736e822 upstream.
+
+The gio bus root device is a statically allocated object which must not
+be freed by kfree() on failure to register the device or bus.
+
+Fixes: 82242d28ff8b ("MIPS: IP22: Add missing put_device call")
+Cc: stable@vger.kernel.org # 3.17
+Cc: Levente Kurusa <levex@linux.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/sgi-ip22/ip22-gio.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/arch/mips/sgi-ip22/ip22-gio.c
++++ b/arch/mips/sgi-ip22/ip22-gio.c
+@@ -30,7 +30,6 @@ static struct {
+
+ static void gio_bus_release(struct device *dev)
+ {
+- kfree(dev);
+ }
+
+ static struct device gio_bus = {
--- /dev/null
+From 8507c2cc9e4fa402401819f44d1e8a5ef4d11d8b Mon Sep 17 00:00:00 2001
+From: Arseniy Krasnov <avkrasnov@rulkc.org>
+Date: Tue, 5 May 2026 11:30:30 +0300
+Subject: mtd: rawnand: fix condition in 'nand_select_target()'
+
+From: Arseniy Krasnov <avkrasnov@rulkc.org>
+
+commit 8507c2cc9e4fa402401819f44d1e8a5ef4d11d8b upstream.
+
+'cs' here must be in range [0:nanddev_ntargets[.
+
+Cc: stable@vger.kernel.org
+Fixes: 32813e288414 ("mtd: rawnand: Get rid of chip->numchips")
+Signed-off-by: Arseniy Krasnov <avkrasnov@rulkc.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/nand/raw/nand_base.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/mtd/nand/raw/nand_base.c
++++ b/drivers/mtd/nand/raw/nand_base.c
+@@ -174,7 +174,7 @@ void nand_select_target(struct nand_chip
+ * cs should always lie between 0 and nanddev_ntargets(), when that's
+ * not the case it's a bug and the caller should be fixed.
+ */
+- if (WARN_ON(cs > nanddev_ntargets(&chip->base)))
++ if (WARN_ON(cs >= nanddev_ntargets(&chip->base)))
+ return;
+
+ chip->cur_cs = cs;
--- /dev/null
+From 36f1648644d769c496a8e47e53603e863e358d73 Mon Sep 17 00:00:00 2001
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+Date: Tue, 9 Jun 2026 16:45:27 +0800
+Subject: mtd: slram: remove failed entries from the device list
+
+From: Ruoyu Wang <ruoyuw560@gmail.com>
+
+commit 36f1648644d769c496a8e47e53603e863e358d73 upstream.
+
+register_device() links a new slram_mtdlist entry before allocating all
+of the state needed by the entry. If a later allocation, memremap(), or
+mtd_device_register() fails, the partially initialized entry remains on
+the global list. A later cleanup can then dereference or free invalid
+state from that failed entry.
+
+Unwind the partially initialized entry and clear the list tail on each
+failure path after the entry has been linked.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/devices/slram.c | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+--- a/drivers/mtd/devices/slram.c
++++ b/drivers/mtd/devices/slram.c
+@@ -129,6 +129,7 @@ static int slram_write(struct mtd_info *
+ static int register_device(char *name, unsigned long start, unsigned long length)
+ {
+ slram_mtd_list_t **curmtd;
++ int ret = -ENOMEM;
+
+ curmtd = &slram_mtdlist;
+ while (*curmtd) {
+@@ -155,14 +156,15 @@ static int register_device(char *name, u
+
+ if (!(*curmtd)->mtdinfo) {
+ E("slram: Cannot allocate new MTD device.\n");
+- return(-ENOMEM);
++ goto err_free_list;
+ }
+
+ if (!(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start =
+ memremap(start, length,
+ MEMREMAP_WB | MEMREMAP_WT | MEMREMAP_WC))) {
+ E("slram: memremap failed\n");
+- return -EIO;
++ ret = -EIO;
++ goto err_free_priv;
+ }
+ ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end =
+ ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start + length;
+@@ -183,10 +185,8 @@ static int register_device(char *name, u
+
+ if (mtd_device_register((*curmtd)->mtdinfo, NULL, 0)) {
+ E("slram: Failed to register new device\n");
+- memunmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start);
+- kfree((*curmtd)->mtdinfo->priv);
+- kfree((*curmtd)->mtdinfo);
+- return(-EAGAIN);
++ ret = -EAGAIN;
++ goto err_unmap;
+ }
+ T("slram: Registered device %s from %luKiB to %luKiB\n", name,
+ (start / 1024), ((start + length) / 1024));
+@@ -194,6 +194,16 @@ static int register_device(char *name, u
+ ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start,
+ ((slram_priv_t *)(*curmtd)->mtdinfo->priv)->end);
+ return(0);
++
++err_unmap:
++ memunmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start);
++err_free_priv:
++ kfree((*curmtd)->mtdinfo->priv);
++err_free_list:
++ kfree((*curmtd)->mtdinfo);
++ kfree(*curmtd);
++ *curmtd = NULL;
++ return ret;
+ }
+
+ static void unregister_devices(void)
--- /dev/null
+From 22920541c35a9f23f219038ba5874c843a7c4419 Mon Sep 17 00:00:00 2001
+From: Kyle Zeng <kylebot@openai.com>
+Date: Thu, 11 Jun 2026 14:35:10 -0700
+Subject: ocfs2: avoid moving extents to occupied clusters
+
+From: Kyle Zeng <kylebot@openai.com>
+
+commit 22920541c35a9f23f219038ba5874c843a7c4419 upstream.
+
+For non-auto OCFS2_IOC_MOVE_EXT operations, userspace supplies a physical
+me_goal. ocfs2_move_extent() initializes new_phys_cpos from that goal and
+expects ocfs2_probe_alloc_group() to replace it with a free run in the
+target block group.
+
+The probe currently leaves *phys_cpos unchanged if the scan reaches the
+end of the group without finding a free run. An occupied goal at the last
+bit can therefore survive the probe and be passed to
+__ocfs2_move_extent(), which copies file data into a cluster still owned
+by another inode before the bitmap is updated.
+
+When the probe does find a free run, it also subtracts move_len from the
+ending bit. The start of an N-bit run ending at i is i - N + 1, so the
+current calculation can report the bit immediately before the free run.
+
+Clear *phys_cpos before scanning and use the correct free-run start.
+Callers already treat a zero result as -ENOSPC, so failed probes no longer
+continue with an occupied caller-controlled goal.
+
+Link: https://lore.kernel.org/20260611213510.16956-1-kylebot@openai.com
+Fixes: e6b5859cccfa ("Ocfs2/move_extents: helper to probe a proper region to move in an alloc group.")
+Fixes: 236b9254f8d1 ("ocfs2: fix non-auto defrag path not working issue")
+Assisted-by: Codex:gpt-5.5
+Signed-off-by: Kyle Zeng <kylebot@openai.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/move_extents.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/ocfs2/move_extents.c
++++ b/fs/ocfs2/move_extents.c
+@@ -536,6 +536,8 @@ static void ocfs2_probe_alloc_group(stru
+ u32 base_cpos = ocfs2_blocks_to_clusters(inode->i_sb,
+ le64_to_cpu(gd->bg_blkno));
+
++ *phys_cpos = 0;
++
+ for (i = base_bit; i < le16_to_cpu(gd->bg_bits); i++) {
+
+ used = ocfs2_test_bit(i, (unsigned long *)gd->bg_bitmap);
+@@ -557,7 +559,7 @@ static void ocfs2_probe_alloc_group(stru
+ last_free_bits++;
+
+ if (last_free_bits == move_len) {
+- i -= move_len;
++ i = i - move_len + 1;
+ *goal_bit = i;
+ *phys_cpos = base_cpos + i;
+ break;
--- /dev/null
+From f9ab30c96b0f00c20c6dac93681bdae3a033d229 Mon Sep 17 00:00:00 2001
+From: Ian Bridges <icb@fastmail.org>
+Date: Thu, 11 Jun 2026 09:46:38 -0500
+Subject: ocfs2: fix NULL h_transaction deref in ocfs2_assure_trans_credits
+
+From: Ian Bridges <icb@fastmail.org>
+
+commit f9ab30c96b0f00c20c6dac93681bdae3a033d229 upstream.
+
+[BUG]
+A direct write over unwritten extents can panic the kernel in
+ocfs2_assure_trans_credits() when the journal aborts during DIO
+completion. The crash is a general protection fault from a NULL pointer
+dereference.
+
+[CAUSE]
+ocfs2_dio_end_io_write() loops over a direct write's unwritten extents,
+marking each written under a single journal handle. If the journal
+aborts (for example after an I/O error) while the extent tree is being
+updated, the handle is left aborted with its transaction pointer
+cleared. The extent merge treats that failure as not critical and
+reports success, so the loop keeps using the handle.
+ocfs2_assure_trans_credits() reads the handle's remaining credits
+without first checking whether the handle is aborted, and that read
+dereferences the cleared transaction pointer.
+
+[FIX]
+A journal abort is recorded in the handle itself, so callers are
+expected to test the handle rather than rely on a returned error.
+Make ocfs2_assure_trans_credits() do that, as the other ocfs2 journal
+helpers already do, and return -EROFS when the handle is aborted.
+
+Link: https://lore.kernel.org/airKTsM1fRVN-Wj7@dev
+Fixes: be346c1a6eeb ("ocfs2: fix DIO failure due to insufficient transaction credits")
+Signed-off-by: Ian Bridges <icb@fastmail.org>
+Reported-by: syzbot+e9c15ff790cea6a0cfae@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=e9c15ff790cea6a0cfae
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/journal.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/ocfs2/journal.c
++++ b/fs/ocfs2/journal.c
+@@ -480,8 +480,12 @@ bail:
+ */
+ int ocfs2_assure_trans_credits(handle_t *handle, int nblocks)
+ {
+- int old_nblks = jbd2_handle_buffer_credits(handle);
++ int old_nblks;
+
++ if (is_handle_aborted(handle))
++ return -EROFS;
++
++ old_nblks = jbd2_handle_buffer_credits(handle);
+ trace_ocfs2_assure_trans_credits(old_nblks);
+ if (old_nblks >= nblocks)
+ return 0;
--- /dev/null
+From 51407c2d249987a466416890a5c931a2354a46aa Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Tue, 19 May 2026 07:04:03 -0400
+Subject: ocfs2: reject dinodes whose i_rdev disagrees with the file type
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 51407c2d249987a466416890a5c931a2354a46aa upstream.
+
+id1.dev1.i_rdev is the device-number arm of the ocfs2_dinode id1 union.
+It is only meaningful for character and block device inodes. For any
+other user-visible file type the on-disk value must be zero.
+
+ocfs2_populate_inode() currently copies id1.dev1.i_rdev into inode->i_rdev
+before the S_IFMT switch decides whether the inode is a special file. A
+non-device inode with a non-zero i_rdev can therefore publish stale or
+attacker-controlled device state into the in-core inode.
+
+System inodes legitimately use other arms of the same union, so keep the
+cross-check restricted to non-system inodes. Factor that predicate into a
+helper and use it in both the normal validator and online filecheck path;
+filecheck reports the malformed dinode through
+OCFS2_FILECHECK_ERR_INVALIDINO instead of ocfs2_error().
+
+Link: https://lore.kernel.org/20260519110404.1803902-3-michael.bommarito@gmail.com
+Fixes: b657c95c1108 ("ocfs2: Wrap inode block reads in a dedicated function.")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Assisted-by: Claude:claude-opus-4-7
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -75,6 +75,16 @@ static bool ocfs2_valid_inode_mode(umode
+ return fs_umode_to_ftype(mode) != FT_UNKNOWN;
+ }
+
++static bool ocfs2_dinode_has_unexpected_rdev(struct ocfs2_dinode *di)
++{
++ umode_t mode = le16_to_cpu(di->i_mode);
++
++ if (le32_to_cpu(di->i_flags) & OCFS2_SYSTEM_FL)
++ return false;
++
++ return !S_ISCHR(mode) && !S_ISBLK(mode) && di->id1.dev1.i_rdev != 0;
++}
++
+ void ocfs2_set_inode_flags(struct inode *inode)
+ {
+ unsigned int flags = OCFS2_I(inode)->ip_attr;
+@@ -1441,6 +1451,41 @@ int ocfs2_validate_inode_block(struct su
+ goto bail;
+ }
+
++ /*
++ * id1.dev1.i_rdev is the device-number arm of the id1 union and
++ * is only meaningful for character and block device inodes. For
++ * any other regular user-visible file type the on-disk value
++ * must be zero. ocfs2_populate_inode() currently runs
++ *
++ * inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
++ *
++ * unconditionally, before the S_IFMT switch decides whether the
++ * inode is a special file. As a result, an i_rdev value present
++ * on a non-device inode is silently published into the in-core
++ * inode; a subsequent forced re-read or in-core mode mutation
++ * (cluster peer with raw write access to the shared LUN,
++ * on-disk corruption, or a separately forged dinode) can then
++ * expose the attacker-controlled device number to
++ * init_special_inode() without ever showing an unusual i_mode
++ * at validation time.
++ *
++ * System inodes (OCFS2_SYSTEM_FL) legitimately use the bitmap1
++ * and journal1 arms of the same union (allocator i_used /
++ * i_total counters and the journal ij_flags /
++ * ij_recovery_generation pair); those bytes are not an i_rdev
++ * and must not be checked here. Restrict the cross-check to
++ * non-system inodes, which is the full attacker-controllable
++ * surface.
++ */
++ if (ocfs2_dinode_has_unexpected_rdev(di)) {
++ rc = ocfs2_error(sb,
++ "Invalid dinode #%llu: non-device mode 0%o with i_rdev %llu\n",
++ (unsigned long long)bh->b_blocknr,
++ le16_to_cpu(di->i_mode),
++ (unsigned long long)le64_to_cpu(di->id1.dev1.i_rdev));
++ goto bail;
++ }
++
+ if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) {
+ struct ocfs2_inline_data *data = &di->id2.i_data;
+
+@@ -1546,6 +1591,16 @@ static int ocfs2_filecheck_validate_inod
+ (unsigned long long)bh->b_blocknr,
+ le16_to_cpu(di->i_mode));
+ rc = -OCFS2_FILECHECK_ERR_INVALIDINO;
++ goto bail;
++ }
++
++ if (ocfs2_dinode_has_unexpected_rdev(di)) {
++ mlog(ML_ERROR,
++ "Filecheck: invalid dinode #%llu: non-device mode 0%o with i_rdev %llu\n",
++ (unsigned long long)bh->b_blocknr,
++ le16_to_cpu(di->i_mode),
++ (unsigned long long)le64_to_cpu(di->id1.dev1.i_rdev));
++ rc = -OCFS2_FILECHECK_ERR_INVALIDINO;
+ }
+
+ bail:
--- /dev/null
+From 5366a017099c6a3c443be908a05f26fd72af12a1 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Tue, 19 May 2026 07:04:02 -0400
+Subject: ocfs2: reject dinodes with non-canonical i_mode type
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 5366a017099c6a3c443be908a05f26fd72af12a1 upstream.
+
+Patch series "ocfs2: harden inode validators against forged metadata", v2.
+
+This series adds three structural checks to OCFS2 dinode validation so
+malformed on-disk fields are rejected before ocfs2_populate_inode() copies
+them into the in-core inode.
+
+The checks cover:
+
+ - i_mode values whose type bits do not name a canonical POSIX file
+ type;
+ - non-device dinodes whose id1.dev1.i_rdev field is non-zero; and
+ - non-inline dinodes that claim non-zero i_size while i_clusters is
+ zero, covering directories unconditionally and regular files on
+ non-sparse volumes.
+
+The normal read path reports these through ocfs2_error(), matching the
+existing suballoc-slot, inline-data, chain-list, and refcount checks. The
+online filecheck path uses the same structural predicates but keeps its
+own reporting contract, returning OCFS2_FILECHECK_ERR_INVALIDINO instead
+of calling ocfs2_error().
+
+
+This patch (of 3):
+
+ocfs2_validate_inode_block() currently accepts any non-zero i_mode value.
+ocfs2_populate_inode() then copies that mode verbatim into inode->i_mode
+and dispatches on i_mode & S_IFMT to the file/dir/symlink/special_file
+iops; an unrecognised type falls through to ocfs2_special_file_iops and
+init_special_inode().
+
+Reject dinodes whose type bits do not name one of the seven canonical
+POSIX file types. Use fs_umode_to_ftype(), the same generic file-type
+conversion helper OCFS2 already uses for directory entries, so the
+accepted inode type set matches the kernel file-type vocabulary instead of
+open-coding a local switch.
+
+Apply the same structural check to the online filecheck read path.
+filecheck keeps its own error namespace, so it reports malformed i_mode
+through the filecheck logger and OCFS2_FILECHECK_ERR_INVALIDINO instead of
+calling ocfs2_error(), but it must not allow a malformed dinode to proceed
+into ocfs2_populate_inode().
+
+Link: https://lore.kernel.org/20260519110404.1803902-1-michael.bommarito@gmail.com
+Link: https://lore.kernel.org/20260519110404.1803902-2-michael.bommarito@gmail.com
+Fixes: b657c95c1108 ("ocfs2: Wrap inode block reads in a dedicated function.")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://sashiko.dev/#/patchset/20260517111015.3187935-1-michael.bommarito%40gmail.com
+Assisted-by: Claude:claude-opus-4-7
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c | 35 +++++++++++++++++++++++++++++++++--
+ 1 file changed, 33 insertions(+), 2 deletions(-)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -68,7 +68,12 @@ static int ocfs2_filecheck_read_inode_bl
+ static int ocfs2_filecheck_validate_inode_block(struct super_block *sb,
+ struct buffer_head *bh);
+ static int ocfs2_filecheck_repair_inode_block(struct super_block *sb,
+- struct buffer_head *bh);
++ struct buffer_head *bh);
++
++static bool ocfs2_valid_inode_mode(umode_t mode)
++{
++ return fs_umode_to_ftype(mode) != FT_UNKNOWN;
++}
+
+ void ocfs2_set_inode_flags(struct inode *inode)
+ {
+@@ -1418,6 +1423,24 @@ int ocfs2_validate_inode_block(struct su
+ goto bail;
+ }
+
++ /*
++ * Reject dinodes whose i_mode does not name one of the seven
++ * canonical POSIX file types. ocfs2_populate_inode() copies
++ * i_mode verbatim into inode->i_mode and then dispatches via
++ * switch (mode & S_IFMT) to file/dir/symlink/special_file iops;
++ * an unrecognised type falls into ocfs2_special_file_iops with
++ * init_special_inode(), which interprets i_rdev. Constrain the
++ * type here so the dispatch only ever sees a value mkfs.ocfs2 /
++ * VFS can produce.
++ */
++ if (!ocfs2_valid_inode_mode(le16_to_cpu(di->i_mode))) {
++ rc = ocfs2_error(sb,
++ "Invalid dinode #%llu: mode 0%o has unknown file type\n",
++ (unsigned long long)bh->b_blocknr,
++ le16_to_cpu(di->i_mode));
++ goto bail;
++ }
++
+ if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) {
+ struct ocfs2_inline_data *data = &di->id2.i_data;
+
+@@ -1514,6 +1537,15 @@ static int ocfs2_filecheck_validate_inod
+ (unsigned long long)bh->b_blocknr,
+ le32_to_cpu(di->i_fs_generation));
+ rc = -OCFS2_FILECHECK_ERR_GENERATION;
++ goto bail;
++ }
++
++ if (!ocfs2_valid_inode_mode(le16_to_cpu(di->i_mode))) {
++ mlog(ML_ERROR,
++ "Filecheck: invalid dinode #%llu: mode 0%o has unknown file type\n",
++ (unsigned long long)bh->b_blocknr,
++ le16_to_cpu(di->i_mode));
++ rc = -OCFS2_FILECHECK_ERR_INVALIDINO;
+ }
+
+ bail:
+@@ -1689,4 +1721,3 @@ const struct ocfs2_caching_operations oc
+ .co_io_lock = ocfs2_inode_cache_io_lock,
+ .co_io_unlock = ocfs2_inode_cache_io_unlock,
+ };
+-
--- /dev/null
+From 7ebc672fab7a76e1e47e0f2fc1ee48118d27fde4 Mon Sep 17 00:00:00 2001
+From: Michael Bommarito <michael.bommarito@gmail.com>
+Date: Tue, 19 May 2026 07:04:04 -0400
+Subject: ocfs2: reject non-inline dinodes with i_size and zero i_clusters
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+commit 7ebc672fab7a76e1e47e0f2fc1ee48118d27fde4 upstream.
+
+On a volume mounted without OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC, a
+non-inline regular file with non-zero i_size and zero i_clusters is
+structurally malformed: the extent map declares no allocated clusters yet
+the size header claims content exists. Keep rejecting that shape, but
+express it through a shared predicate so the same invariant is available
+to normal inode reads and online filecheck.
+
+The same zero-cluster shape is also malformed for non-inline directories.
+ocfs2 directory growth allocates backing storage before advancing i_size,
+and ocfs2_dir_foreach_blk_el() later walks until ctx->pos reaches
+i_size_read(inode). A forged directory dinode with a huge i_size and no
+clusters would repeatedly fail on holes while advancing through the
+claimed size.
+
+Sparse regular files remain exempt: on sparse-alloc volumes, truncate can
+legitimately grow i_size without allocating clusters. System inodes and
+inline-data dinodes also retain their separate storage rules.
+
+Mirror the check in ocfs2_filecheck_validate_inode_block() as well.
+filecheck reports through its own error namespace, so malformed
+size/cluster state is logged as a filecheck invalid-inode result rather
+than via ocfs2_error(), but it must not proceed into
+ocfs2_populate_inode().
+
+Link: https://lore.kernel.org/20260519110404.1803902-4-michael.bommarito@gmail.com
+Fixes: b657c95c1108 ("ocfs2: Wrap inode block reads in a dedicated function.")
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://sashiko.dev/#/patchset/20260517111015.3187935-1-michael.bommarito%40gmail.com
+Assisted-by: Claude:claude-opus-4-7
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 60 insertions(+)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -85,6 +85,24 @@ static bool ocfs2_dinode_has_unexpected_
+ return !S_ISCHR(mode) && !S_ISBLK(mode) && di->id1.dev1.i_rdev != 0;
+ }
+
++static bool ocfs2_dinode_has_size_without_clusters(struct super_block *sb,
++ struct ocfs2_dinode *di)
++{
++ umode_t mode = le16_to_cpu(di->i_mode);
++
++ if (le32_to_cpu(di->i_flags) & OCFS2_SYSTEM_FL)
++ return false;
++ if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL)
++ return false;
++ if (!le64_to_cpu(di->i_size) || le32_to_cpu(di->i_clusters))
++ return false;
++
++ if (S_ISDIR(mode))
++ return true;
++
++ return !ocfs2_sparse_alloc(OCFS2_SB(sb)) && S_ISREG(mode);
++}
++
+ void ocfs2_set_inode_flags(struct inode *inode)
+ {
+ unsigned int flags = OCFS2_I(inode)->ip_attr;
+@@ -1486,6 +1504,33 @@ int ocfs2_validate_inode_block(struct su
+ goto bail;
+ }
+
++ /*
++ * Non-inline directories must not have i_size without allocated
++ * clusters: directory growth adds storage before advancing i_size,
++ * and readdir walks i_size block-by-block. A forged directory
++ * with zero clusters and a huge i_size would repeatedly fault on
++ * holes while advancing through the claimed size.
++ *
++ * Non-inline regular files have the same invariant on non-sparse
++ * volumes. Sparse regular files are different: truncate can
++ * legitimately grow i_size without allocating clusters, so keep
++ * the sparse-alloc carveout for S_IFREG only. System inodes and
++ * inline-data dinodes have their own storage rules.
++ */
++ if (ocfs2_dinode_has_size_without_clusters(sb, di)) {
++ if (S_ISDIR(le16_to_cpu(di->i_mode)))
++ rc = ocfs2_error(sb,
++ "Invalid dinode #%llu: directory i_size %llu with i_clusters 0 and no inline-data flag\n",
++ (unsigned long long)bh->b_blocknr,
++ (unsigned long long)le64_to_cpu(di->i_size));
++ else
++ rc = ocfs2_error(sb,
++ "Invalid dinode #%llu: regular file i_size %llu with i_clusters 0 and no inline-data flag on non-sparse volume\n",
++ (unsigned long long)bh->b_blocknr,
++ (unsigned long long)le64_to_cpu(di->i_size));
++ goto bail;
++ }
++
+ if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) {
+ struct ocfs2_inline_data *data = &di->id2.i_data;
+
+@@ -1601,6 +1646,21 @@ static int ocfs2_filecheck_validate_inod
+ le16_to_cpu(di->i_mode),
+ (unsigned long long)le64_to_cpu(di->id1.dev1.i_rdev));
+ rc = -OCFS2_FILECHECK_ERR_INVALIDINO;
++ goto bail;
++ }
++
++ if (ocfs2_dinode_has_size_without_clusters(sb, di)) {
++ if (S_ISDIR(le16_to_cpu(di->i_mode)))
++ mlog(ML_ERROR,
++ "Filecheck: invalid dinode #%llu: directory i_size %llu with i_clusters 0 and no inline-data flag\n",
++ (unsigned long long)bh->b_blocknr,
++ (unsigned long long)le64_to_cpu(di->i_size));
++ else
++ mlog(ML_ERROR,
++ "Filecheck: invalid dinode #%llu: regular file i_size %llu with i_clusters 0 and no inline-data flag on non-sparse volume\n",
++ (unsigned long long)bh->b_blocknr,
++ (unsigned long long)le64_to_cpu(di->i_size));
++ rc = -OCFS2_FILECHECK_ERR_INVALIDINO;
+ }
+
+ bail:
--- /dev/null
+From 93c8c6ea90be9e9df8fe14048ad4e3caad0770a6 Mon Sep 17 00:00:00 2001
+From: Tristan Madani <tristan@talencesecurity.com>
+Date: Sat, 18 Apr 2026 13:10:48 +0000
+Subject: ocfs2: use kzalloc for quota recovery bitmap allocation
+
+From: Tristan Madani <tristan@talencesecurity.com>
+
+commit 93c8c6ea90be9e9df8fe14048ad4e3caad0770a6 upstream.
+
+ocfs2 quota recovery allocates a bitmap buffer with kmalloc and does not
+fully initialize it. This can lead to use of uninitialized bits during
+quota recovery from a corrupted filesystem image.
+
+Use kzalloc instead to ensure the bitmap is zero-initialized.
+
+Link: https://lore.kernel.org/20260418131048.1052507-1-tristmd@gmail.com
+Reported-by: syzbot+7ea0b96c4ddb49fd1a70@syzkaller.appspotmail.com
+Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/quota_local.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ocfs2/quota_local.c
++++ b/fs/ocfs2/quota_local.c
+@@ -302,7 +302,7 @@ static int ocfs2_add_recovery_chunk(stru
+ if (!rc)
+ return -ENOMEM;
+ rc->rc_chunk = chunk;
+- rc->rc_bitmap = kmalloc(sb->s_blocksize, GFP_NOFS);
++ rc->rc_bitmap = kzalloc(sb->s_blocksize, GFP_NOFS);
+ if (!rc->rc_bitmap) {
+ kfree(rc);
+ return -ENOMEM;
--- /dev/null
+From 4373cfa38ead58f980362c841b0d0bdf8c4d956c Mon Sep 17 00:00:00 2001
+From: WenTao Liang <vulab@iscas.ac.cn>
+Date: Thu, 11 Jun 2026 08:53:21 +0800
+Subject: power: supply: charger-manager: fix refcount leak in is_full_charged()
+
+From: WenTao Liang <vulab@iscas.ac.cn>
+
+commit 4373cfa38ead58f980362c841b0d0bdf8c4d956c upstream.
+
+In is_full_charged(), power_supply_get_by_name() is called to
+obtain a reference to the fuel_gauge power supply. If the
+voltage check (uV >= desc->fullbatt_uV) succeeds, the function
+returns true directly without releasing the reference, leaking
+the refcount.
+
+Fix this by setting a flag and jumping to the out label where
+power_supply_put() properly drops the reference.
+
+Cc: stable@vger.kernel.org
+Fixes: e132fc6bb89b ("power: supply: charger-manager: Make decisions focussed on battery status")
+Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20260611005322.53096-1-vulab@iscas.ac.cn
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/power/supply/charger-manager.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/power/supply/charger-manager.c
++++ b/drivers/power/supply/charger-manager.c
+@@ -302,8 +302,10 @@ static bool is_full_charged(struct charg
+ if (cm->battery_status == POWER_SUPPLY_STATUS_FULL
+ && desc->fullbatt_vchkdrop_uV)
+ uV += desc->fullbatt_vchkdrop_uV;
+- if (uV >= desc->fullbatt_uV)
+- return true;
++ if (uV >= desc->fullbatt_uV) {
++ is_full = true;
++ goto out;
++ }
+ }
+ }
+
--- /dev/null
+From 16b02eb4b9b272c221255c20d34ccd5db53a3ed3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Krzysztof=20Wilczy=C5=84ski?= <kwilczynski@kernel.org>
+Date: Sat, 13 Jun 2026 21:10:05 +0000
+Subject: proc: only bump parent nlink when registering directories
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Krzysztof Wilczyński <kwilczynski@kernel.org>
+
+commit 16b02eb4b9b272c221255c20d34ccd5db53a3ed3 upstream.
+
+proc_register() increments the parent directory's link count for every
+entry it registers, while remove_proc_entry() and remove_proc_subtree()
+decrement it only when the removed entry is a directory. Regular files
+thus inflate the parent's count while they exist, and leak one link
+permanently on every create and remove cycle.
+
+For example, /proc/bus/pci/00 with twenty-two device files and no
+subdirectories reports nlink 24 instead of 2, and SR-IOV VF enable
+and disable cycles, each creating and removing the VF config space
+entries under /proc/bus/pci/<bus>, inflate the link count of that
+directory without bound.
+
+Before commit e06689bf5701 ("proc: change ->nlink under
+proc_subdir_lock"), the increment lived in proc_mkdir_data() and
+proc_create_mount_point(), and was therefore applied only to
+directories. Moving it into proc_register() to bring it under
+proc_subdir_lock dropped the S_ISDIR check.
+
+Thus, move the nlink accounting into pde_subdir_insert() and
+pde_erase(), only updating it for directories in both, so the link
+count is always changed together with the directory entry itself.
+
+Fixes: e06689bf5701 ("proc: change ->nlink under proc_subdir_lock")
+Cc: stable@vger.kernel.org # v5.5+
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Link: https://patch.msgid.link/20260613211005.921692-1-kwilczynski@kernel.org
+Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/proc/generic.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/fs/proc/generic.c
++++ b/fs/proc/generic.c
+@@ -112,6 +112,8 @@ static bool pde_subdir_insert(struct pro
+ /* Add new node and rebalance tree. */
+ rb_link_node(&de->subdir_node, parent, new);
+ rb_insert_color(&de->subdir_node, root);
++ if (S_ISDIR(de->mode))
++ dir->nlink++;
+ return true;
+ }
+
+@@ -383,7 +385,6 @@ struct proc_dir_entry *proc_register(str
+ write_unlock(&proc_subdir_lock);
+ goto out_free_inum;
+ }
+- dir->nlink++;
+ write_unlock(&proc_subdir_lock);
+
+ return dp;
+@@ -697,6 +698,8 @@ static void pde_erase(struct proc_dir_en
+ {
+ rb_erase(&pde->subdir_node, &parent->subdir);
+ RB_CLEAR_NODE(&pde->subdir_node);
++ if (S_ISDIR(pde->mode))
++ parent->nlink--;
+ }
+
+ /*
+@@ -722,8 +725,6 @@ void remove_proc_entry(const char *name,
+ de = NULL;
+ } else {
+ pde_erase(de, parent);
+- if (S_ISDIR(de->mode))
+- parent->nlink--;
+ }
+ }
+ write_unlock(&proc_subdir_lock);
+@@ -782,8 +783,6 @@ int remove_proc_subtree(const char *name
+ continue;
+ }
+ next = de->parent;
+- if (S_ISDIR(de->mode))
+- next->nlink--;
+ write_unlock(&proc_subdir_lock);
+
+ proc_entry_rundown(de);
--- /dev/null
+From 57db1307afb1f83d45f5ff53b93f8d040100d13e Mon Sep 17 00:00:00 2001
+From: Martin Wilck <martin.wilck@suse.com>
+Date: Wed, 13 May 2026 19:42:35 +0200
+Subject: scsi: smartpqi: Use shost_to_hba() in pqi_scan_finished()
+
+From: Martin Wilck <martin.wilck@suse.com>
+
+commit 57db1307afb1f83d45f5ff53b93f8d040100d13e upstream.
+
+shost_to_hba() is used everywhere except to obtain pqi_ctrl_info from
+shosti, except in pqi_scan_finished(), where shost_priv() is used. This
+causes one pointer dereference to be missed, as shost->hostdata is a
+pointer in smartpqi. Fix it.
+
+Fixes: 6c223761eb54 ("smartpqi: initial commit of Microsemi smartpqi driver")
+Signed-off-by: Martin Wilck <martin.wilck@suse.com>
+Reviewed-by: Don Brace <don.brace@microchip.com>
+Cc: Don Brace <don.brace@microchip.com>
+Cc: storagedev@microchip.com
+Cc: stable@vger.kernel.org
+Reviewed-by: Hannes Reinecke <hare@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Link: https://patch.msgid.link/20260513174236.430465-2-mwilck@suse.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -2191,7 +2191,7 @@ static int pqi_scan_finished(struct Scsi
+ {
+ struct pqi_ctrl_info *ctrl_info;
+
+- ctrl_info = shost_priv(shost);
++ ctrl_info = shost_to_hba(shost);
+
+ return !mutex_is_locked(&ctrl_info->scan_mutex);
+ }
nvdimm-btt-free-arena-sub-allocations-on-discover_arenas-error-path.patch
lockd-plug-nlm_file-leak-when-nlm_do_fopen-fails.patch
lockd-plug-nlm_file-refcount-leak-on-cached-nlm_do_fopen-failure.patch
+mips-ip22-gio-fix-gio-device-memory-leak.patch
+mips-ip22-gio-fix-kfree-of-static-object.patch
+mips-ip22-gio-fix-device-reference-leak-in-probe.patch
+mips-dec-ensure-32-bit-stack-location-for-o32-prom_printf.patch
+power-supply-charger-manager-fix-refcount-leak-in-is_full_charged.patch
+proc-only-bump-parent-nlink-when-registering-directories.patch
+mtd-slram-remove-failed-entries-from-the-device-list.patch
+scsi-smartpqi-use-shost_to_hba-in-pqi_scan_finished.patch
+ocfs2-use-kzalloc-for-quota-recovery-bitmap-allocation.patch
+mtd-rawnand-fix-condition-in-nand_select_target.patch
+ocfs2-avoid-moving-extents-to-occupied-clusters.patch
+ocfs2-fix-null-h_transaction-deref-in-ocfs2_assure_trans_credits.patch
+ocfs2-reject-dinodes-with-non-canonical-i_mode-type.patch
+ocfs2-reject-dinodes-whose-i_rdev-disagrees-with-the-file-type.patch
+ocfs2-reject-non-inline-dinodes-with-i_size-and-zero-i_clusters.patch