]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Feb 2026 21:54:43 +0000 (13:54 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Feb 2026 21:54:43 +0000 (13:54 -0800)
added patches:
alsa-hda-conexant-fix-headphone-jack-handling-on-acer-swift-sf314.patch
alsa-hda-realtek-add-quirk-for-gigabyte-g5-kf5-2023.patch
alsa-hda-realtek-add-quirk-for-samsung-galaxy-book3-pro-360-np965qfg.patch
asoc-dt-bindings-asahi-kasei-ak4458-fix-the-supply-names.patch
asoc-dt-bindings-asahi-kasei-ak4458-set-unevaluatedproperties-false.patch
asoc-dt-bindings-asahi-kasei-ak5558-fix-the-supply-names.patch
ata-libata-scsi-avoid-non-ncq-command-starvation.patch
ata-libata-scsi-refactor-ata_scsi_translate.patch
ata-pata_ftide010-fix-some-dma-timings.patch
dt-bindings-media-qcom-qcs8300-camss-add-missing-power-supplies.patch
dt-bindings-phy-qcom-edp-add-missing-clock-for-x-elite.patch
ext4-always-allocate-blocks-only-from-groups-inode-can-use.patch
ext4-don-t-cache-extent-during-splitting-extent.patch
ext4-don-t-zero-the-entire-extent-if-ext4_ext_data_partial_valid1.patch
ext4-drop-extent-cache-after-doing-partial_valid1-zeroout.patch
ext4-drop-extent-cache-when-splitting-extent-fails.patch
ext4-fix-dirtyclusters-double-decrement-on-fs-shutdown.patch
ext4-fix-e4b-bitmap-inconsistency-reports.patch
ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch
ext4-subdivide-ext4_ext_data_valid1.patch
ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch
mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch
sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch
sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch
usb-cdns3-fix-role-switching-during-resume.patch

26 files changed:
queue-6.18/alsa-hda-conexant-fix-headphone-jack-handling-on-acer-swift-sf314.patch [new file with mode: 0644]
queue-6.18/alsa-hda-realtek-add-quirk-for-gigabyte-g5-kf5-2023.patch [new file with mode: 0644]
queue-6.18/alsa-hda-realtek-add-quirk-for-samsung-galaxy-book3-pro-360-np965qfg.patch [new file with mode: 0644]
queue-6.18/asoc-dt-bindings-asahi-kasei-ak4458-fix-the-supply-names.patch [new file with mode: 0644]
queue-6.18/asoc-dt-bindings-asahi-kasei-ak4458-set-unevaluatedproperties-false.patch [new file with mode: 0644]
queue-6.18/asoc-dt-bindings-asahi-kasei-ak5558-fix-the-supply-names.patch [new file with mode: 0644]
queue-6.18/ata-libata-scsi-avoid-non-ncq-command-starvation.patch [new file with mode: 0644]
queue-6.18/ata-libata-scsi-refactor-ata_scsi_translate.patch [new file with mode: 0644]
queue-6.18/ata-pata_ftide010-fix-some-dma-timings.patch [new file with mode: 0644]
queue-6.18/dt-bindings-media-qcom-qcs8300-camss-add-missing-power-supplies.patch [new file with mode: 0644]
queue-6.18/dt-bindings-phy-qcom-edp-add-missing-clock-for-x-elite.patch [new file with mode: 0644]
queue-6.18/ext4-always-allocate-blocks-only-from-groups-inode-can-use.patch [new file with mode: 0644]
queue-6.18/ext4-don-t-cache-extent-during-splitting-extent.patch [new file with mode: 0644]
queue-6.18/ext4-don-t-zero-the-entire-extent-if-ext4_ext_data_partial_valid1.patch [new file with mode: 0644]
queue-6.18/ext4-drop-extent-cache-after-doing-partial_valid1-zeroout.patch [new file with mode: 0644]
queue-6.18/ext4-drop-extent-cache-when-splitting-extent-fails.patch [new file with mode: 0644]
queue-6.18/ext4-fix-dirtyclusters-double-decrement-on-fs-shutdown.patch [new file with mode: 0644]
queue-6.18/ext4-fix-e4b-bitmap-inconsistency-reports.patch [new file with mode: 0644]
queue-6.18/ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch [new file with mode: 0644]
queue-6.18/ext4-subdivide-ext4_ext_data_valid1.patch [new file with mode: 0644]
queue-6.18/ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch [new file with mode: 0644]
queue-6.18/mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch [new file with mode: 0644]
queue-6.18/series
queue-6.18/sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch [new file with mode: 0644]
queue-6.18/sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch [new file with mode: 0644]
queue-6.18/usb-cdns3-fix-role-switching-during-resume.patch [new file with mode: 0644]

diff --git a/queue-6.18/alsa-hda-conexant-fix-headphone-jack-handling-on-acer-swift-sf314.patch b/queue-6.18/alsa-hda-conexant-fix-headphone-jack-handling-on-acer-swift-sf314.patch
new file mode 100644 (file)
index 0000000..da98760
--- /dev/null
@@ -0,0 +1,56 @@
+From 7bc0df86c2384bc1e2012a2c946f82305054da64 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 17 Feb 2026 11:44:11 +0100
+Subject: ALSA: hda/conexant: Fix headphone jack handling on Acer Swift SF314
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 7bc0df86c2384bc1e2012a2c946f82305054da64 upstream.
+
+Acer Swift SF314 (SSID 1025:136d) needs a bit of tweaks of the pin
+configurations for NID 0x16 and 0x19 to make the headphone / headset
+jack working.  NID 0x17 can remain as is for the working speaker, and
+the built-in mic is supported via SOF.
+
+Cc: <stable@vger.kernel.org>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=221086
+Link: https://patch.msgid.link/20260217104414.62911-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/codecs/conexant.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/sound/hda/codecs/conexant.c
++++ b/sound/hda/codecs/conexant.c
+@@ -299,6 +299,7 @@ enum {
+       CXT_PINCFG_SWS_JS201D,
+       CXT_PINCFG_TOP_SPEAKER,
+       CXT_FIXUP_HP_A_U,
++      CXT_FIXUP_ACER_SWIFT_HP,
+ };
+ /* for hda_fixup_thinkpad_acpi() */
+@@ -1024,6 +1025,14 @@ static const struct hda_fixup cxt_fixups
+               .type = HDA_FIXUP_FUNC,
+               .v.func = cxt_fixup_hp_a_u,
+       },
++      [CXT_FIXUP_ACER_SWIFT_HP] = {
++              .type = HDA_FIXUP_PINS,
++              .v.pins = (const struct hda_pintbl[]) {
++                      { 0x16, 0x0321403f }, /* Headphone */
++                      { 0x19, 0x40f001f0 }, /* Mic */
++                      { }
++              },
++      },
+ };
+ static const struct hda_quirk cxt5045_fixups[] = {
+@@ -1073,6 +1082,7 @@ static const struct hda_quirk cxt5066_fi
+       SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
+       SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
++      SND_PCI_QUIRK(0x1025, 0x136d, "Acer Swift SF314", CXT_FIXUP_ACER_SWIFT_HP),
+       SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
+       SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
+       SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
diff --git a/queue-6.18/alsa-hda-realtek-add-quirk-for-gigabyte-g5-kf5-2023.patch b/queue-6.18/alsa-hda-realtek-add-quirk-for-gigabyte-g5-kf5-2023.patch
new file mode 100644 (file)
index 0000000..ecef721
--- /dev/null
@@ -0,0 +1,31 @@
+From 405d59fdd2038a65790eaad8c1013d37a2af6561 Mon Sep 17 00:00:00 2001
+From: Eric Naim <dnaim@cachyos.org>
+Date: Tue, 10 Feb 2026 17:34:02 +0800
+Subject: ALSA: hda/realtek: Add quirk for Gigabyte G5 KF5 (2023)
+
+From: Eric Naim <dnaim@cachyos.org>
+
+commit 405d59fdd2038a65790eaad8c1013d37a2af6561 upstream.
+
+Fixes microphone detection when a headset is connected to the audio jack
+using the ALC256.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Eric Naim <dnaim@cachyos.org>
+Link: https://patch.msgid.link/20260210093403.21514-1-dnaim@cachyos.org
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/codecs/realtek/alc269.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/hda/codecs/realtek/alc269.c
++++ b/sound/hda/codecs/realtek/alc269.c
+@@ -6952,6 +6952,7 @@ static const struct hda_quirk alc269_fix
+       SND_PCI_QUIRK(0x144d, 0xc886, "Samsung Galaxy Book3 Pro (NP964XFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
+       SND_PCI_QUIRK(0x144d, 0xc1ca, "Samsung Galaxy Book3 Pro 360 (NP960QFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
+       SND_PCI_QUIRK(0x144d, 0xc1cc, "Samsung Galaxy Book3 Ultra (NT960XFH)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
++      SND_PCI_QUIRK(0x1458, 0x900e, "Gigabyte G5 KF5 (2023)", ALC2XX_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
diff --git a/queue-6.18/alsa-hda-realtek-add-quirk-for-samsung-galaxy-book3-pro-360-np965qfg.patch b/queue-6.18/alsa-hda-realtek-add-quirk-for-samsung-galaxy-book3-pro-360-np965qfg.patch
new file mode 100644 (file)
index 0000000..74e171a
--- /dev/null
@@ -0,0 +1,33 @@
+From 3a6b7dc431aab90744e973254604855e654294ae Mon Sep 17 00:00:00 2001
+From: Lewis Mason <mason8110@gmail.com>
+Date: Tue, 10 Feb 2026 23:13:37 +0000
+Subject: ALSA: hda/realtek: Add quirk for Samsung Galaxy Book3 Pro 360 (NP965QFG)
+
+From: Lewis Mason <mason8110@gmail.com>
+
+commit 3a6b7dc431aab90744e973254604855e654294ae upstream.
+
+The Samsung Galaxy Book3 Pro 360 NP965QFG (subsystem ID 0x144d:0xc1cb)
+uses the same Realtek ALC298 codec and amplifier configuration as the
+NP960QFG (0x144d:0xc1ca). Apply the same ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS
+fixup to enable the internal speakers.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Lewis Mason <lewis@ocuru.co.uk>
+Link: https://patch.msgid.link/20260210231337.7265-1-lewis@ocuru.co.uk
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/hda/codecs/realtek/alc269.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/hda/codecs/realtek/alc269.c
++++ b/sound/hda/codecs/realtek/alc269.c
+@@ -6951,6 +6951,7 @@ static const struct hda_quirk alc269_fix
+       SND_PCI_QUIRK(0x144d, 0xc872, "Samsung Galaxy Book2 Pro (NP950XEE)", ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS),
+       SND_PCI_QUIRK(0x144d, 0xc886, "Samsung Galaxy Book3 Pro (NP964XFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
+       SND_PCI_QUIRK(0x144d, 0xc1ca, "Samsung Galaxy Book3 Pro 360 (NP960QFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
++      SND_PCI_QUIRK(0x144d, 0xc1cb, "Samsung Galaxy Book3 Pro 360 (NP965QFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
+       SND_PCI_QUIRK(0x144d, 0xc1cc, "Samsung Galaxy Book3 Ultra (NT960XFH)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS),
+       SND_PCI_QUIRK(0x1458, 0x900e, "Gigabyte G5 KF5 (2023)", ALC2XX_FIXUP_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
diff --git a/queue-6.18/asoc-dt-bindings-asahi-kasei-ak4458-fix-the-supply-names.patch b/queue-6.18/asoc-dt-bindings-asahi-kasei-ak4458-fix-the-supply-names.patch
new file mode 100644 (file)
index 0000000..bc902e6
--- /dev/null
@@ -0,0 +1,42 @@
+From e570a5ca307f6d7a6acd080fc219db2ce3c0737b Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Thu, 12 Feb 2026 10:18:28 +0800
+Subject: ASoC: dt-bindings: asahi-kasei,ak4458: Fix the supply names
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit e570a5ca307f6d7a6acd080fc219db2ce3c0737b upstream.
+
+In the original txt format binding document ak4458.txt, the supply names
+are 'AVDD-supply', 'DVDD-supply', and they are also used in driver. But in
+the commit converting to yaml format, they are changed to 'avdd-supply',
+'dvdd-supply'. After search all the dts file, these names 'AVDD-supply',
+'DVDD-supply', 'avdd-supply', 'dvdd-supply' are not used in any dts
+file. So it is safe to fix this yaml binding document.
+
+Fixes: 009e83b591dd ("ASoC: dt-bindings: ak4458: Convert to dtschema")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260212021829.3244736-3-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
++++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
+@@ -21,10 +21,10 @@ properties:
+   reg:
+     maxItems: 1
+-  avdd-supply:
++  AVDD-supply:
+     description: Analog power supply
+-  dvdd-supply:
++  DVDD-supply:
+     description: Digital power supply
+   reset-gpios:
diff --git a/queue-6.18/asoc-dt-bindings-asahi-kasei-ak4458-set-unevaluatedproperties-false.patch b/queue-6.18/asoc-dt-bindings-asahi-kasei-ak4458-set-unevaluatedproperties-false.patch
new file mode 100644 (file)
index 0000000..60ee9f1
--- /dev/null
@@ -0,0 +1,35 @@
+From 50a634f1d795721ce68583c78ba493f1d7aa8bc2 Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Thu, 12 Feb 2026 10:18:27 +0800
+Subject: ASoC: dt-bindings: asahi-kasei,ak4458: set unevaluatedProperties:false
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit 50a634f1d795721ce68583c78ba493f1d7aa8bc2 upstream.
+
+When including the dai-common.yaml, and allow '#sound-dai-cells' and
+"sound-name-prefix' to be used, should use unevaluatedProperties:false
+according to writing-bindings.rst.
+
+Fixes: 8d7de4a014f5 ("ASoC: dt-bindings: asahi-kasei,ak4458: Reference common DAI properties")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260212021829.3244736-2-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
++++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml
+@@ -60,7 +60,7 @@ allOf:
+       properties:
+         dsd-path: false
+-additionalProperties: false
++unevaluatedProperties: false
+ examples:
+   - |
diff --git a/queue-6.18/asoc-dt-bindings-asahi-kasei-ak5558-fix-the-supply-names.patch b/queue-6.18/asoc-dt-bindings-asahi-kasei-ak5558-fix-the-supply-names.patch
new file mode 100644 (file)
index 0000000..dee7aac
--- /dev/null
@@ -0,0 +1,42 @@
+From 80ca113671a005430207d351cb403c1637106212 Mon Sep 17 00:00:00 2001
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+Date: Thu, 12 Feb 2026 10:18:29 +0800
+Subject: ASoC: dt-bindings: asahi-kasei,ak5558: Fix the supply names
+
+From: Shengjiu Wang <shengjiu.wang@nxp.com>
+
+commit 80ca113671a005430207d351cb403c1637106212 upstream.
+
+In the original txt format binding document ak4458.txt, the supply names
+are 'AVDD-supply', 'DVDD-supply', and they are also used in driver. But in
+the commit converting to yaml format, they are changed to 'avdd-supply',
+'dvdd-supply'. After search all the dts file, these names 'AVDD-supply',
+'DVDD-supply', 'avdd-supply', 'dvdd-supply' are not used in any dts
+file. So it is safe to fix the yaml binding document.
+
+Fixes: 829d78e3ea32 ("ASoC: dt-bindings: ak5558: Convert to dtschema")
+Cc: stable@vger.kernel.org
+Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260212021829.3244736-4-shengjiu.wang@nxp.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml
++++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml
+@@ -19,10 +19,10 @@ properties:
+   reg:
+     maxItems: 1
+-  avdd-supply:
++  AVDD-supply:
+     description: A 1.8V supply that powers up the AVDD pin.
+-  dvdd-supply:
++  DVDD-supply:
+     description: A 1.2V supply that powers up the DVDD pin.
+   reset-gpios:
diff --git a/queue-6.18/ata-libata-scsi-avoid-non-ncq-command-starvation.patch b/queue-6.18/ata-libata-scsi-avoid-non-ncq-command-starvation.patch
new file mode 100644 (file)
index 0000000..a14e65a
--- /dev/null
@@ -0,0 +1,261 @@
+From 0ea84089dbf62a92dc7889c79e6b18fc89260808 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Wed, 17 Dec 2025 16:40:48 +0900
+Subject: ata: libata-scsi: avoid Non-NCQ command starvation
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit 0ea84089dbf62a92dc7889c79e6b18fc89260808 upstream.
+
+When a non-NCQ command is issued while NCQ commands are being executed,
+ata_scsi_qc_issue() indicates to the SCSI layer that the command issuing
+should be deferred by returning SCSI_MLQUEUE_XXX_BUSY.  This command
+deferring is correct and as mandated by the ACS specifications since
+NCQ and non-NCQ commands cannot be mixed.
+
+However, in the case of a host adapter using multiple submission queues,
+when the target device is under a constant load of NCQ commands, there
+are no guarantees that requeueing the non-NCQ command will be executed
+later and it may be deferred again repeatedly as other submission queues
+can constantly issue NCQ commands from different CPUs ahead of the
+non-NCQ command. This can lead to very long delays for the execution of
+non-NCQ commands, and even complete starvation for these commands in the
+worst case scenario.
+
+Since the block layer and the SCSI layer do not distinguish between
+queueable (NCQ) and non queueable (non-NCQ) commands, libata-scsi SAT
+implementation must ensure forward progress for non-NCQ commands in the
+presence of NCQ command traffic. This is similar to what SAS HBAs with a
+hardware/firmware based SAT implementation do.
+
+Implement such forward progress guarantee by limiting requeueing of
+non-NCQ commands from ata_scsi_qc_issue(): when a non-NCQ command is
+received and NCQ commands are in-flight, do not force a requeue of the
+non-NCQ command by returning SCSI_MLQUEUE_XXX_BUSY and instead return 0
+to indicate that the command was accepted but hold on to the qc using
+the new deferred_qc field of struct ata_port.
+
+This deferred qc will be issued using the work item deferred_qc_work
+running the function ata_scsi_deferred_qc_work() once all in-flight
+commands complete, which is checked with the port qc_defer() callback
+return value indicating that no further delay is necessary. This check
+is done using the helper function ata_scsi_schedule_deferred_qc() which
+is called from ata_scsi_qc_complete(). This thus excludes this mechanism
+from all internal non-NCQ commands issued by ATA EH.
+
+When a port deferred_qc is non NULL, that is, the port has a command
+waiting for the device queue to drain, the issuing of all incoming
+commands (both NCQ and non-NCQ) is deferred using the regular busy
+mechanism. This simplifies the code and also avoids potential denial of
+service problems if a user issues too many non-NCQ commands.
+
+Finally, whenever ata EH is scheduled, regardless of the reason, a
+deferred qc is always requeued so that it can be retried once EH
+completes. This is done by calling the function
+ata_scsi_requeue_deferred_qc() from ata_eh_set_pending(). This avoids
+the need for any special processing for the deferred qc in case of NCQ
+error, link or device reset, or device timeout.
+
+Reported-by: Xingui Yang <yangxingui@huawei.com>
+Reported-by: Igor Pylypiv <ipylypiv@google.com>
+Fixes: bdb01301f3ea ("scsi: Add host and host template flag 'host_tagset'")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Tested-by: Igor Pylypiv <ipylypiv@google.com>
+Tested-by: Xingui Yang <yangxingui@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-core.c |    5 ++
+ drivers/ata/libata-eh.c   |    6 ++
+ drivers/ata/libata-scsi.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/ata/libata.h      |    2 
+ include/linux/libata.h    |    3 +
+ 5 files changed, 109 insertions(+)
+
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -5552,6 +5552,7 @@ struct ata_port *ata_port_alloc(struct a
+       mutex_init(&ap->scsi_scan_mutex);
+       INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
+       INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
++      INIT_WORK(&ap->deferred_qc_work, ata_scsi_deferred_qc_work);
+       INIT_LIST_HEAD(&ap->eh_done_q);
+       init_waitqueue_head(&ap->eh_wait_q);
+       init_completion(&ap->park_req_pending);
+@@ -6162,6 +6163,10 @@ static void ata_port_detach(struct ata_p
+               }
+       }
++      /* Make sure the deferred qc work finished. */
++      cancel_work_sync(&ap->deferred_qc_work);
++      WARN_ON(ap->deferred_qc);
++
+       /* Tell EH to disable all devices */
+       ap->pflags |= ATA_PFLAG_UNLOADING;
+       ata_port_schedule_eh(ap);
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -917,6 +917,12 @@ static void ata_eh_set_pending(struct at
+       ap->pflags |= ATA_PFLAG_EH_PENDING;
++      /*
++       * If we have a deferred qc, requeue it so that it is retried once EH
++       * completes.
++       */
++      ata_scsi_requeue_deferred_qc(ap);
++
+       if (!fastdrain)
+               return;
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -1657,8 +1657,77 @@ static void ata_qc_done(struct ata_queue
+       done(cmd);
+ }
++void ata_scsi_deferred_qc_work(struct work_struct *work)
++{
++      struct ata_port *ap =
++              container_of(work, struct ata_port, deferred_qc_work);
++      struct ata_queued_cmd *qc;
++      unsigned long flags;
++
++      spin_lock_irqsave(ap->lock, flags);
++
++      /*
++       * If we still have a deferred qc and we are not in EH, issue it. In
++       * such case, we should not need any more deferring the qc, so warn if
++       * qc_defer() says otherwise.
++       */
++      qc = ap->deferred_qc;
++      if (qc && !ata_port_eh_scheduled(ap)) {
++              WARN_ON_ONCE(ap->ops->qc_defer(qc));
++              ap->deferred_qc = NULL;
++              ata_qc_issue(qc);
++      }
++
++      spin_unlock_irqrestore(ap->lock, flags);
++}
++
++void ata_scsi_requeue_deferred_qc(struct ata_port *ap)
++{
++      struct ata_queued_cmd *qc = ap->deferred_qc;
++      struct scsi_cmnd *scmd;
++
++      lockdep_assert_held(ap->lock);
++
++      /*
++       * If we have a deferred qc when a reset occurs or NCQ commands fail,
++       * do not try to be smart about what to do with this deferred command
++       * and simply retry it by completing it with DID_SOFT_ERROR.
++       */
++      if (!qc)
++              return;
++
++      scmd = qc->scsicmd;
++      ap->deferred_qc = NULL;
++      ata_qc_free(qc);
++      scmd->result = (DID_SOFT_ERROR << 16);
++      scsi_done(scmd);
++}
++
++static void ata_scsi_schedule_deferred_qc(struct ata_port *ap)
++{
++      struct ata_queued_cmd *qc = ap->deferred_qc;
++
++      lockdep_assert_held(ap->lock);
++
++      /*
++       * If we have a deferred qc, then qc_defer() is defined and we can use
++       * this callback to determine if this qc is good to go, unless EH has
++       * been scheduled.
++       */
++      if (!qc)
++              return;
++
++      if (ata_port_eh_scheduled(ap)) {
++              ata_scsi_requeue_deferred_qc(ap);
++              return;
++      }
++      if (!ap->ops->qc_defer(qc))
++              queue_work(system_highpri_wq, &ap->deferred_qc_work);
++}
++
+ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
+ {
++      struct ata_port *ap = qc->ap;
+       struct scsi_cmnd *cmd = qc->scsicmd;
+       u8 *cdb = cmd->cmnd;
+       bool have_sense = qc->flags & ATA_QCFLAG_SENSE_VALID;
+@@ -1688,6 +1757,8 @@ static void ata_scsi_qc_complete(struct
+       }
+       ata_qc_done(qc);
++
++      ata_scsi_schedule_deferred_qc(ap);
+ }
+ static int ata_scsi_qc_issue(struct ata_port *ap, struct ata_queued_cmd *qc)
+@@ -1697,6 +1768,16 @@ static int ata_scsi_qc_issue(struct ata_
+       if (!ap->ops->qc_defer)
+               goto issue;
++      /*
++       * If we already have a deferred qc, then rely on the SCSI layer to
++       * requeue and defer all incoming commands until the deferred qc is
++       * processed, once all on-going commands complete.
++       */
++      if (ap->deferred_qc) {
++              ata_qc_free(qc);
++              return SCSI_MLQUEUE_DEVICE_BUSY;
++      }
++
+       /* Check if the command needs to be deferred. */
+       ret = ap->ops->qc_defer(qc);
+       switch (ret) {
+@@ -1715,6 +1796,18 @@ static int ata_scsi_qc_issue(struct ata_
+       }
+       if (ret) {
++              /*
++               * We must defer this qc: if this is not an NCQ command, keep
++               * this qc as a deferred one and report to the SCSI layer that
++               * we issued it so that it is not requeued. The deferred qc will
++               * be issued with the port deferred_qc_work once all on-going
++               * commands complete.
++               */
++              if (!ata_is_ncq(qc->tf.protocol)) {
++                      ap->deferred_qc = qc;
++                      return 0;
++              }
++
+               /* Force a requeue of the command to defer its execution. */
+               ata_qc_free(qc);
+               return ret;
+--- a/drivers/ata/libata.h
++++ b/drivers/ata/libata.h
+@@ -161,6 +161,8 @@ void ata_scsi_sdev_config(struct scsi_de
+ int ata_scsi_dev_config(struct scsi_device *sdev, struct queue_limits *lim,
+               struct ata_device *dev);
+ int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev);
++void ata_scsi_deferred_qc_work(struct work_struct *work);
++void ata_scsi_requeue_deferred_qc(struct ata_port *ap);
+ /* libata-eh.c */
+ extern unsigned int ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -899,6 +899,9 @@ struct ata_port {
+       u64                     qc_active;
+       int                     nr_active_links; /* #links with active qcs */
++      struct work_struct      deferred_qc_work;
++      struct ata_queued_cmd   *deferred_qc;
++
+       struct ata_link         link;           /* host default link */
+       struct ata_link         *slave_link;    /* see ata_slave_link_init() */
diff --git a/queue-6.18/ata-libata-scsi-refactor-ata_scsi_translate.patch b/queue-6.18/ata-libata-scsi-refactor-ata_scsi_translate.patch
new file mode 100644 (file)
index 0000000..3cc68f1
--- /dev/null
@@ -0,0 +1,155 @@
+From bb3a8154b1a1dc2c86d037482c0a2cf9186829ed Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Wed, 17 Dec 2025 14:05:25 +0900
+Subject: ata: libata-scsi: refactor ata_scsi_translate()
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit bb3a8154b1a1dc2c86d037482c0a2cf9186829ed upstream.
+
+Factor out of ata_scsi_translate() the code handling queued command
+deferral using the port qc_defer callback and issuing the queued
+command with ata_qc_issue() into the new function ata_scsi_qc_issue(),
+and simplify the goto used in ata_scsi_translate().
+While at it, also add a lockdep annotation to check that the port lock
+is held when ata_scsi_translate() is called.
+
+No functional changes.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Reviewed-by: Igor Pylypiv <ipylypiv@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/libata-scsi.c |   81 ++++++++++++++++++++++++++++------------------
+ 1 file changed, 50 insertions(+), 31 deletions(-)
+
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -1690,6 +1690,42 @@ static void ata_scsi_qc_complete(struct
+       ata_qc_done(qc);
+ }
++static int ata_scsi_qc_issue(struct ata_port *ap, struct ata_queued_cmd *qc)
++{
++      int ret;
++
++      if (!ap->ops->qc_defer)
++              goto issue;
++
++      /* Check if the command needs to be deferred. */
++      ret = ap->ops->qc_defer(qc);
++      switch (ret) {
++      case 0:
++              break;
++      case ATA_DEFER_LINK:
++              ret = SCSI_MLQUEUE_DEVICE_BUSY;
++              break;
++      case ATA_DEFER_PORT:
++              ret = SCSI_MLQUEUE_HOST_BUSY;
++              break;
++      default:
++              WARN_ON_ONCE(1);
++              ret = SCSI_MLQUEUE_HOST_BUSY;
++              break;
++      }
++
++      if (ret) {
++              /* Force a requeue of the command to defer its execution. */
++              ata_qc_free(qc);
++              return ret;
++      }
++
++issue:
++      ata_qc_issue(qc);
++
++      return 0;
++}
++
+ /**
+  *    ata_scsi_translate - Translate then issue SCSI command to ATA device
+  *    @dev: ATA device to which the command is addressed
+@@ -1713,66 +1749,49 @@ static void ata_scsi_qc_complete(struct
+  *    spin_lock_irqsave(host lock)
+  *
+  *    RETURNS:
+- *    0 on success, SCSI_ML_QUEUE_DEVICE_BUSY if the command
+- *    needs to be deferred.
++ *    0 on success, SCSI_ML_QUEUE_DEVICE_BUSY or SCSI_MLQUEUE_HOST_BUSY if the
++ *    command needs to be deferred.
+  */
+ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
+                             ata_xlat_func_t xlat_func)
+ {
+       struct ata_port *ap = dev->link->ap;
+       struct ata_queued_cmd *qc;
+-      int rc;
++      lockdep_assert_held(ap->lock);
++
++      /*
++       * ata_scsi_qc_new() calls scsi_done(cmd) in case of failure. So we
++       * have nothing further to do when allocating a qc fails.
++       */
+       qc = ata_scsi_qc_new(dev, cmd);
+       if (!qc)
+-              goto err_mem;
++              return 0;
+       /* data is present; dma-map it */
+       if (cmd->sc_data_direction == DMA_FROM_DEVICE ||
+           cmd->sc_data_direction == DMA_TO_DEVICE) {
+               if (unlikely(scsi_bufflen(cmd) < 1)) {
+                       ata_dev_warn(dev, "WARNING: zero len r/w req\n");
+-                      goto err_did;
++                      cmd->result = (DID_ERROR << 16);
++                      goto done;
+               }
+               ata_sg_init(qc, scsi_sglist(cmd), scsi_sg_count(cmd));
+-
+               qc->dma_dir = cmd->sc_data_direction;
+       }
+       qc->complete_fn = ata_scsi_qc_complete;
+       if (xlat_func(qc))
+-              goto early_finish;
+-
+-      if (ap->ops->qc_defer) {
+-              if ((rc = ap->ops->qc_defer(qc)))
+-                      goto defer;
+-      }
+-
+-      /* select device, send command to hardware */
+-      ata_qc_issue(qc);
+-
+-      return 0;
++              goto done;
+-early_finish:
+-      ata_qc_free(qc);
+-      scsi_done(cmd);
+-      return 0;
++      return ata_scsi_qc_issue(ap, qc);
+-err_did:
++done:
+       ata_qc_free(qc);
+-      cmd->result = (DID_ERROR << 16);
+       scsi_done(cmd);
+-err_mem:
+       return 0;
+-
+-defer:
+-      ata_qc_free(qc);
+-      if (rc == ATA_DEFER_LINK)
+-              return SCSI_MLQUEUE_DEVICE_BUSY;
+-      else
+-              return SCSI_MLQUEUE_HOST_BUSY;
+ }
+ /**
diff --git a/queue-6.18/ata-pata_ftide010-fix-some-dma-timings.patch b/queue-6.18/ata-pata_ftide010-fix-some-dma-timings.patch
new file mode 100644 (file)
index 0000000..14b418c
--- /dev/null
@@ -0,0 +1,39 @@
+From ff4a46c278ac6a4b3f39be1492a4568b6dcc6105 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linusw@kernel.org>
+Date: Tue, 3 Feb 2026 11:23:01 +0100
+Subject: ata: pata_ftide010: Fix some DMA timings
+
+From: Linus Walleij <linusw@kernel.org>
+
+commit ff4a46c278ac6a4b3f39be1492a4568b6dcc6105 upstream.
+
+The FTIDE010 has been missing some timing settings since its
+inception, since the upstream OpenWrt patch was missing these.
+
+The community has since come up with the appropriate timings.
+
+Fixes: be4e456ed3a5 ("ata: Add driver for Faraday Technology FTIDE010")
+Cc: stable@vger.kernel.org
+Signed-off-by: Linus Walleij <linusw@kernel.org>
+Signed-off-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ata/pata_ftide010.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/ata/pata_ftide010.c
++++ b/drivers/ata/pata_ftide010.c
+@@ -122,10 +122,10 @@ static const u8 mwdma_50_active_time[3]
+ static const u8 mwdma_50_recovery_time[3] = {6, 2, 1};
+ static const u8 mwdma_66_active_time[3] = {8, 3, 3};
+ static const u8 mwdma_66_recovery_time[3] = {8, 2, 1};
+-static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 1};
++static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 9};
+ static const u8 udma_50_hold_time[6] = {3, 1, 1, 1, 1, 1};
+-static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, };
+-static const u8 udma_66_hold_time[7] = {};
++static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, 1, 9, 9};
++static const u8 udma_66_hold_time[7] = {4, 2, 1, 1, 1, 1, 1};
+ /*
+  * We set 66 MHz for all MWDMA modes
diff --git a/queue-6.18/dt-bindings-media-qcom-qcs8300-camss-add-missing-power-supplies.patch b/queue-6.18/dt-bindings-media-qcom-qcs8300-camss-add-missing-power-supplies.patch
new file mode 100644 (file)
index 0000000..1edc484
--- /dev/null
@@ -0,0 +1,62 @@
+From 555e882051a3a7ecc2bcee2b2047822249dcd074 Mon Sep 17 00:00:00 2001
+From: Vikram Sharma <quic_vikramsa@quicinc.com>
+Date: Fri, 7 Nov 2025 21:55:20 +0530
+Subject: dt-bindings: media: qcom,qcs8300-camss: Add missing power supplies
+
+From: Vikram Sharma <quic_vikramsa@quicinc.com>
+
+commit 555e882051a3a7ecc2bcee2b2047822249dcd074 upstream.
+
+Add missing vdda-phy-supply and vdda-pll-supply in the (monaco)qcs8300
+camss binding. While enabling imx412 sensor for qcs8300 we see a need
+to add these supplies which were missing in initial submission.
+
+Fixes: 634a2958fae30 ("media: dt-bindings: Add qcom,qcs8300-camss compatible")
+Cc: stable@vger.kernel.org
+Co-developed-by: Nihal Kumar Gupta <quic_nihalkum@quicinc.com>
+Signed-off-by: Nihal Kumar Gupta <quic_nihalkum@quicinc.com>
+Signed-off-by: Vikram Sharma <quic_vikramsa@quicinc.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/media/qcom,qcs8300-camss.yaml |   13 ++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/Documentation/devicetree/bindings/media/qcom,qcs8300-camss.yaml
++++ b/Documentation/devicetree/bindings/media/qcom,qcs8300-camss.yaml
+@@ -120,6 +120,14 @@ properties:
+     items:
+       - const: top
++  vdda-phy-supply:
++    description:
++      Phandle to a 0.88V regulator supply to CSI PHYs.
++
++  vdda-pll-supply:
++    description:
++      Phandle to 1.2V regulator supply to CSI PHYs pll block.
++
+   ports:
+     $ref: /schemas/graph.yaml#/properties/ports
+@@ -160,6 +168,8 @@ required:
+   - power-domains
+   - power-domain-names
+   - ports
++  - vdda-phy-supply
++  - vdda-pll-supply
+ additionalProperties: false
+@@ -328,6 +338,9 @@ examples:
+             power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+             power-domain-names = "top";
++            vdda-phy-supply = <&vreg_l4a_0p88>;
++            vdda-pll-supply = <&vreg_l1c_1p2>;
++
+             ports {
+                 #address-cells = <1>;
+                 #size-cells = <0>;
diff --git a/queue-6.18/dt-bindings-phy-qcom-edp-add-missing-clock-for-x-elite.patch b/queue-6.18/dt-bindings-phy-qcom-edp-add-missing-clock-for-x-elite.patch
new file mode 100644 (file)
index 0000000..9a0b2e3
--- /dev/null
@@ -0,0 +1,80 @@
+From 6b99eeacf6abb1ff2d6463c84e490343f39cf11a Mon Sep 17 00:00:00 2001
+From: Abel Vesa <abel.vesa@linaro.org>
+Date: Wed, 24 Dec 2025 12:53:27 +0200
+Subject: dt-bindings: phy: qcom-edp: Add missing clock for X Elite
+
+From: Abel Vesa <abel.vesa@linaro.org>
+
+commit 6b99eeacf6abb1ff2d6463c84e490343f39cf11a upstream.
+
+On X Elite platform, the eDP PHY uses one more clock called ref.
+
+The current X Elite devices supported upstream work fine without this
+clock, because the boot firmware leaves this clock enabled. But we should
+not rely on that. Also, even though this change breaks the ABI, it is
+needed in order to make the driver disables this clock along with the
+other ones, for a proper bring-down of the entire PHY.
+
+So attach the this ref clock to the PHY.
+
+Cc: stable@vger.kernel.org # v6.10
+Fixes: 5d5607861350 ("dt-bindings: phy: qcom-edp: Add X1E80100 PHY compatibles")
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
+Link: https://patch.msgid.link/20251224-phy-qcom-edp-add-missing-refclk-v5-1-3f45d349b5ac@oss.qualcomm.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml |   28 +++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+--- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
++++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml
+@@ -37,12 +37,15 @@ properties:
+       - description: PLL register block
+   clocks:
+-    maxItems: 2
++    minItems: 2
++    maxItems: 3
+   clock-names:
++    minItems: 2
+     items:
+       - const: aux
+       - const: cfg_ahb
++      - const: ref
+   "#clock-cells":
+     const: 1
+@@ -64,6 +67,29 @@ required:
+   - "#clock-cells"
+   - "#phy-cells"
++allOf:
++  - if:
++      properties:
++        compatible:
++          enum:
++            - qcom,x1e80100-dp-phy
++    then:
++      properties:
++        clocks:
++          minItems: 3
++          maxItems: 3
++        clock-names:
++          minItems: 3
++          maxItems: 3
++    else:
++      properties:
++        clocks:
++          minItems: 2
++          maxItems: 2
++        clock-names:
++          minItems: 2
++          maxItems: 2
++
+ additionalProperties: false
+ examples:
diff --git a/queue-6.18/ext4-always-allocate-blocks-only-from-groups-inode-can-use.patch b/queue-6.18/ext4-always-allocate-blocks-only-from-groups-inode-can-use.patch
new file mode 100644 (file)
index 0000000..dc32a6e
--- /dev/null
@@ -0,0 +1,103 @@
+From 4865c768b563deff1b6a6384e74a62f143427b42 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 14 Jan 2026 19:28:18 +0100
+Subject: ext4: always allocate blocks only from groups inode can use
+
+From: Jan Kara <jack@suse.cz>
+
+commit 4865c768b563deff1b6a6384e74a62f143427b42 upstream.
+
+For filesystems with more than 2^32 blocks inodes using indirect block
+based format cannot use blocks beyond the 32-bit limit.
+ext4_mb_scan_groups_linear() takes care to not select these unsupported
+groups for such inodes however other functions selecting groups for
+allocation don't. So far this is harmless because the other selection
+functions are used only with mb_optimize_scan and this is currently
+disabled for inodes with indirect blocks however in the following patch
+we want to enable mb_optimize_scan regardless of inode format.
+
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Acked-by: Pedro Falcato <pfalcato@suse.de>
+Cc: stable@kernel.org
+Link: https://patch.msgid.link/20260114182836.14120-3-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c |   29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -892,6 +892,21 @@ mb_update_avg_fragment_size(struct super
+       }
+ }
++static ext4_group_t ext4_get_allocation_groups_count(
++                              struct ext4_allocation_context *ac)
++{
++      ext4_group_t ngroups = ext4_get_groups_count(ac->ac_sb);
++
++      /* non-extent files are limited to low blocks/groups */
++      if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
++              ngroups = EXT4_SB(ac->ac_sb)->s_blockfile_groups;
++
++      /* Pairs with smp_wmb() in ext4_update_super() */
++      smp_rmb();
++
++      return ngroups;
++}
++
+ static int ext4_mb_scan_groups_xa_range(struct ext4_allocation_context *ac,
+                                       struct xarray *xa,
+                                       ext4_group_t start, ext4_group_t end)
+@@ -899,7 +914,7 @@ static int ext4_mb_scan_groups_xa_range(
+       struct super_block *sb = ac->ac_sb;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       enum criteria cr = ac->ac_criteria;
+-      ext4_group_t ngroups = ext4_get_groups_count(sb);
++      ext4_group_t ngroups = ext4_get_allocation_groups_count(ac);
+       unsigned long group = start;
+       struct ext4_group_info *grp;
+@@ -951,7 +966,7 @@ static int ext4_mb_scan_groups_p2_aligne
+       ext4_group_t start, end;
+       start = group;
+-      end = ext4_get_groups_count(ac->ac_sb);
++      end = ext4_get_allocation_groups_count(ac);
+ wrap_around:
+       for (i = ac->ac_2order; i < MB_NUM_ORDERS(ac->ac_sb); i++) {
+               ret = ext4_mb_scan_groups_largest_free_order_range(ac, i,
+@@ -1001,7 +1016,7 @@ static int ext4_mb_scan_groups_goal_fast
+       ext4_group_t start, end;
+       start = group;
+-      end = ext4_get_groups_count(ac->ac_sb);
++      end = ext4_get_allocation_groups_count(ac);
+ wrap_around:
+       i = mb_avg_fragment_size_order(ac->ac_sb, ac->ac_g_ex.fe_len);
+       for (; i < MB_NUM_ORDERS(ac->ac_sb); i++) {
+@@ -1083,7 +1098,7 @@ static int ext4_mb_scan_groups_best_avai
+               min_order = fls(ac->ac_o_ex.fe_len);
+       start = group;
+-      end = ext4_get_groups_count(ac->ac_sb);
++      end = ext4_get_allocation_groups_count(ac);
+ wrap_around:
+       for (i = order; i >= min_order; i--) {
+               int frag_order;
+@@ -1182,11 +1197,7 @@ static int ext4_mb_scan_groups(struct ex
+       int ret = 0;
+       ext4_group_t start;
+       struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
+-      ext4_group_t ngroups = ext4_get_groups_count(ac->ac_sb);
+-
+-      /* non-extent files are limited to low blocks/groups */
+-      if (!(ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)))
+-              ngroups = sbi->s_blockfile_groups;
++      ext4_group_t ngroups = ext4_get_allocation_groups_count(ac);
+       /* searching for the right group start from the goal value specified */
+       start = ac->ac_g_ex.fe_group;
diff --git a/queue-6.18/ext4-don-t-cache-extent-during-splitting-extent.patch b/queue-6.18/ext4-don-t-cache-extent-during-splitting-extent.patch
new file mode 100644 (file)
index 0000000..f93fec7
--- /dev/null
@@ -0,0 +1,74 @@
+From 8b4b19a2f96348d70bfa306ef7d4a13b0bcbea79 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Sat, 29 Nov 2025 18:32:37 +0800
+Subject: ext4: don't cache extent during splitting extent
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 8b4b19a2f96348d70bfa306ef7d4a13b0bcbea79 upstream.
+
+Caching extents during the splitting process is risky, as it may result
+in stale extents remaining in the status tree. Moreover, in most cases,
+the corresponding extent block entries are likely already cached before
+the split happens, making caching here not particularly useful.
+
+Assume we have an unwritten extent, and then DIO writes the first half.
+
+  [UUUUUUUUUUUUUUUU] on-disk extent        U: unwritten extent
+  [UUUUUUUUUUUUUUUU] extent status tree
+  |<-   ->| ----> dio write this range
+
+First, when ext4_split_extent_at() splits this extent, it truncates the
+existing extent and then inserts a new one. During this process, this
+extent status entry may be shrunk, and calls to ext4_find_extent() and
+ext4_cache_extents() may occur, which could potentially insert the
+truncated range as a hole into the extent status tree. After the split
+is completed, this hole is not replaced with the correct status.
+
+  [UUUUUUU|UUUUUUUU] on-disk extent        U: unwritten extent
+  [UUUUUUU|HHHHHHHH] extent status tree    H: hole
+
+Then, the outer calling functions will not correct this remaining hole
+extent either. Finally, if we perform a delayed buffer write on this
+latter part, it will re-insert the delayed extent and cause an error in
+space accounting.
+
+In adition, if the unwritten extent cache is not shrunk during the
+splitting, ext4_cache_extents() also conflicts with existing extents
+when caching extents. In the future, we will add checks when caching
+extents, which will trigger a warning. Therefore, Do not cache extents
+that are being split.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Message-ID: <20251129103247.686136-6-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3199,6 +3199,9 @@ static struct ext4_ext_path *ext4_split_
+       BUG_ON((split_flag & EXT4_EXT_DATA_VALID1) &&
+              (split_flag & EXT4_EXT_DATA_VALID2));
++      /* Do not cache extents that are in the process of being modified. */
++      flags |= EXT4_EX_NOCACHE;
++
+       ext_debug(inode, "logical block %llu\n", (unsigned long long)split);
+       ext4_ext_show_leaf(inode, path);
+@@ -3381,6 +3384,9 @@ static struct ext4_ext_path *ext4_split_
+       ee_len = ext4_ext_get_actual_len(ex);
+       unwritten = ext4_ext_is_unwritten(ex);
++      /* Do not cache extents that are in the process of being modified. */
++      flags |= EXT4_EX_NOCACHE;
++
+       if (map->m_lblk + map->m_len < ee_block + ee_len) {
+               split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT;
+               flags1 = flags | EXT4_GET_BLOCKS_PRE_IO;
diff --git a/queue-6.18/ext4-don-t-zero-the-entire-extent-if-ext4_ext_data_partial_valid1.patch b/queue-6.18/ext4-don-t-zero-the-entire-extent-if-ext4_ext_data_partial_valid1.patch
new file mode 100644 (file)
index 0000000..49ad095
--- /dev/null
@@ -0,0 +1,85 @@
+From 1bf6974822d1dba86cf11b5f05498581cf3488a2 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Sat, 29 Nov 2025 18:32:34 +0800
+Subject: ext4: don't zero the entire extent if EXT4_EXT_DATA_PARTIAL_VALID1
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 1bf6974822d1dba86cf11b5f05498581cf3488a2 upstream.
+
+When allocating initialized blocks from a large unwritten extent, or
+when splitting an unwritten extent during end I/O and converting it to
+initialized, there is currently a potential issue of stale data if the
+extent needs to be split in the middle.
+
+       0  A      B  N
+       [UUUUUUUUUUUU]    U: unwritten extent
+       [--DDDDDDDD--]    D: valid data
+          |<-  ->| ----> this range needs to be initialized
+
+ext4_split_extent() first try to split this extent at B with
+EXT4_EXT_DATA_ENTIRE_VALID1 and EXT4_EXT_MAY_ZEROOUT flag set, but
+ext4_split_extent_at() failed to split this extent due to temporary lack
+of space. It zeroout B to N and mark the entire extent from 0 to N
+as written.
+
+       0  A      B  N
+       [WWWWWWWWWWWW]    W: written extent
+       [SSDDDDDDDDZZ]    Z: zeroed, S: stale data
+
+ext4_split_extent() then try to split this extent at A with
+EXT4_EXT_DATA_VALID2 flag set. This time, it split successfully and left
+a stale written extent from 0 to A.
+
+       0  A      B   N
+       [WW|WWWWWWWWWW]
+       [SS|DDDDDDDDZZ]
+
+Fix this by pass EXT4_EXT_DATA_PARTIAL_VALID1 to ext4_split_extent_at()
+when splitting at B, don't convert the entire extent to written and left
+it as unwritten after zeroing out B to N. The remaining work is just
+like the standard two-part split. ext4_split_extent() will pass the
+EXT4_EXT_DATA_VALID2 flag when it calls ext4_split_extent_at() for the
+second time, allowing it to properly handle the split. If the split is
+successful, it will keep extent from 0 to A as unwritten.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Message-ID: <20251129103247.686136-3-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |   13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3310,6 +3310,15 @@ static struct ext4_ext_path *ext4_split_
+               }
+               if (!err) {
++                      /*
++                       * The first half contains partially valid data, the
++                       * splitting of this extent has not been completed, fix
++                       * extent length and ext4_split_extent() split will the
++                       * first half again.
++                       */
++                      if (split_flag & EXT4_EXT_DATA_PARTIAL_VALID1)
++                              goto fix_extent_len;
++
+                       /* update the extent length and mark as initialized */
+                       ex->ee_len = cpu_to_le16(ee_len);
+                       ext4_ext_try_to_merge(handle, inode, path, ex);
+@@ -3379,7 +3388,9 @@ static struct ext4_ext_path *ext4_split_
+                       split_flag1 |= EXT4_EXT_MARK_UNWRIT1 |
+                                      EXT4_EXT_MARK_UNWRIT2;
+               if (split_flag & EXT4_EXT_DATA_VALID2)
+-                      split_flag1 |= EXT4_EXT_DATA_ENTIRE_VALID1;
++                      split_flag1 |= map->m_lblk > ee_block ?
++                                     EXT4_EXT_DATA_PARTIAL_VALID1 :
++                                     EXT4_EXT_DATA_ENTIRE_VALID1;
+               path = ext4_split_extent_at(handle, inode, path,
+                               map->m_lblk + map->m_len, split_flag1, flags1);
+               if (IS_ERR(path))
diff --git a/queue-6.18/ext4-drop-extent-cache-after-doing-partial_valid1-zeroout.patch b/queue-6.18/ext4-drop-extent-cache-after-doing-partial_valid1-zeroout.patch
new file mode 100644 (file)
index 0000000..bc62afe
--- /dev/null
@@ -0,0 +1,84 @@
+From 6d882ea3b0931b43530d44149b79fcd4ffc13030 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Sat, 29 Nov 2025 18:32:38 +0800
+Subject: ext4: drop extent cache after doing PARTIAL_VALID1 zeroout
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 6d882ea3b0931b43530d44149b79fcd4ffc13030 upstream.
+
+When splitting an unwritten extent in the middle and converting it to
+initialized in ext4_split_extent() with the EXT4_EXT_MAY_ZEROOUT and
+EXT4_EXT_DATA_VALID2 flags set, it could leave a stale unwritten extent.
+
+Assume we have an unwritten file and buffered write in the middle of it
+without dioread_nolock enabled, it will allocate blocks as written
+extent.
+
+       0  A      B  N
+       [UUUUUUUUUUUU] on-disk extent      U: unwritten extent
+       [UUUUUUUUUUUU] extent status tree
+       [--DDDDDDDD--]                     D: valid data
+          |<-  ->| ----> this range needs to be initialized
+
+ext4_split_extent() first try to split this extent at B with
+EXT4_EXT_DATA_PARTIAL_VALID1 and EXT4_EXT_MAY_ZEROOUT flag set, but
+ext4_split_extent_at() failed to split this extent due to temporary lack
+of space. It zeroout B to N and leave the entire extent as unwritten.
+
+       0  A      B  N
+       [UUUUUUUUUUUU] on-disk extent
+       [UUUUUUUUUUUU] extent status tree
+       [--DDDDDDDDZZ]                     Z: zeroed data
+
+ext4_split_extent() then try to split this extent at A with
+EXT4_EXT_DATA_VALID2 flag set. This time, it split successfully and
+leave an written extent from A to N.
+
+       0  A      B  N
+       [UUWWWWWWWWWW] on-disk extent      W: written extent
+       [UUUUUUUUUUUU] extent status tree
+       [--DDDDDDDDZZ]
+
+Finally ext4_map_create_blocks() only insert extent A to B to the extent
+status tree, and leave an stale unwritten extent in the status tree.
+
+       0  A      B  N
+       [UUWWWWWWWWWW] on-disk extent      W: written extent
+       [UUWWWWWWWWUU] extent status tree
+       [--DDDDDDDDZZ]
+
+Fix this issue by always cached extent status entry after zeroing out
+the second part.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Message-ID: <20251129103247.686136-7-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3319,8 +3319,16 @@ static struct ext4_ext_path *ext4_split_
+                        * extent length and ext4_split_extent() split will the
+                        * first half again.
+                        */
+-                      if (split_flag & EXT4_EXT_DATA_PARTIAL_VALID1)
++                      if (split_flag & EXT4_EXT_DATA_PARTIAL_VALID1) {
++                              /*
++                               * Drop extent cache to prevent stale unwritten
++                               * extents remaining after zeroing out.
++                               */
++                              ext4_es_remove_extent(inode,
++                                      le32_to_cpu(zero_ex.ee_block),
++                                      ext4_ext_get_actual_len(&zero_ex));
+                               goto fix_extent_len;
++                      }
+                       /* update the extent length and mark as initialized */
+                       ex->ee_len = cpu_to_le16(ee_len);
diff --git a/queue-6.18/ext4-drop-extent-cache-when-splitting-extent-fails.patch b/queue-6.18/ext4-drop-extent-cache-when-splitting-extent-fails.patch
new file mode 100644 (file)
index 0000000..9c856a7
--- /dev/null
@@ -0,0 +1,56 @@
+From 79b592e8f1b435796cbc2722190368e3e8ffd7a1 Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Sat, 29 Nov 2025 18:32:39 +0800
+Subject: ext4: drop extent cache when splitting extent fails
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 79b592e8f1b435796cbc2722190368e3e8ffd7a1 upstream.
+
+When the split extent fails, we might leave some extents still being
+processed and return an error directly, which will result in stale
+extent entries remaining in the extent status tree. So drop all of the
+remaining potentially stale extents if the splitting fails.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Message-ID: <20251129103247.686136-8-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_
+       err = PTR_ERR(path);
+       if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
+-              return path;
++              goto out_path;
+       /*
+        * Get a new path to try to zeroout or fix the extent length.
+@@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_
+       if (IS_ERR(path)) {
+               EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
+                                split, PTR_ERR(path));
+-              return path;
++              goto out_path;
+       }
+       depth = ext_depth(inode);
+       ex = path[depth].p_ext;
+@@ -3358,6 +3358,10 @@ out:
+               ext4_free_ext_path(path);
+               path = ERR_PTR(err);
+       }
++out_path:
++      if (IS_ERR(path))
++              /* Remove all remaining potentially stale extents. */
++              ext4_es_remove_extent(inode, ee_block, ee_len);
+       ext4_ext_show_leaf(inode, path);
+       return path;
+ }
diff --git a/queue-6.18/ext4-fix-dirtyclusters-double-decrement-on-fs-shutdown.patch b/queue-6.18/ext4-fix-dirtyclusters-double-decrement-on-fs-shutdown.patch
new file mode 100644 (file)
index 0000000..fc4f930
--- /dev/null
@@ -0,0 +1,116 @@
+From 94a8cea54cd935c54fa2fba70354757c0fc245e3 Mon Sep 17 00:00:00 2001
+From: Brian Foster <bfoster@redhat.com>
+Date: Tue, 13 Jan 2026 12:19:05 -0500
+Subject: ext4: fix dirtyclusters double decrement on fs shutdown
+
+From: Brian Foster <bfoster@redhat.com>
+
+commit 94a8cea54cd935c54fa2fba70354757c0fc245e3 upstream.
+
+fstests test generic/388 occasionally reproduces a warning in
+ext4_put_super() associated with the dirty clusters count:
+
+  WARNING: CPU: 7 PID: 76064 at fs/ext4/super.c:1324 ext4_put_super+0x48c/0x590 [ext4]
+
+Tracing the failure shows that the warning fires due to an
+s_dirtyclusters_counter value of -1. IOW, this appears to be a
+spurious decrement as opposed to some sort of leak. Further tracing
+of the dirty cluster count deltas and an LLM scan of the resulting
+output identified the cause as a double decrement in the error path
+between ext4_mb_mark_diskspace_used() and the caller
+ext4_mb_new_blocks().
+
+First, note that generic/388 is a shutdown vs. fsstress test and so
+produces a random set of operations and shutdown injections. In the
+problematic case, the shutdown triggers an error return from the
+ext4_handle_dirty_metadata() call(s) made from
+ext4_mb_mark_context(). The changed value is non-zero at this point,
+so ext4_mb_mark_diskspace_used() does not exit after the error
+bubbles up from ext4_mb_mark_context(). Instead, the former
+decrements both cluster counters and returns the error up to
+ext4_mb_new_blocks(). The latter falls into the !ar->len out path
+which decrements the dirty clusters counter a second time, creating
+the inconsistency.
+
+To avoid this problem and simplify ownership of the cluster
+reservation in this codepath, lift the counter reduction to a single
+place in the caller. This makes it more clear that
+ext4_mb_new_blocks() is responsible for acquiring cluster
+reservation (via ext4_claim_free_clusters()) in the !delalloc case
+as well as releasing it, regardless of whether it ends up consumed
+or returned due to failure.
+
+Fixes: 0087d9fb3f29 ("ext4: Fix s_dirty_blocks_counter if block allocation failed with nodelalloc")
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Link: https://patch.msgid.link/20260113171905.118284-1-bfoster@redhat.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc-test.c |    2 +-
+ fs/ext4/mballoc.c      |   21 +++++----------------
+ 2 files changed, 6 insertions(+), 17 deletions(-)
+
+--- a/fs/ext4/mballoc-test.c
++++ b/fs/ext4/mballoc-test.c
+@@ -567,7 +567,7 @@ test_mark_diskspace_used_range(struct ku
+       bitmap = mbt_ctx_bitmap(sb, TEST_GOAL_GROUP);
+       memset(bitmap, 0, sb->s_blocksize);
+-      ret = ext4_mb_mark_diskspace_used(ac, NULL, 0);
++      ret = ext4_mb_mark_diskspace_used(ac, NULL);
+       KUNIT_ASSERT_EQ(test, ret, 0);
+       max = EXT4_CLUSTERS_PER_GROUP(sb);
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4181,8 +4181,7 @@ out_err:
+  * Returns 0 if success or error code
+  */
+ static noinline_for_stack int
+-ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
+-                              handle_t *handle, unsigned int reserv_clstrs)
++ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, handle_t *handle)
+ {
+       struct ext4_group_desc *gdp;
+       struct ext4_sb_info *sbi;
+@@ -4237,13 +4236,6 @@ ext4_mb_mark_diskspace_used(struct ext4_
+       BUG_ON(changed != ac->ac_b_ex.fe_len);
+ #endif
+       percpu_counter_sub(&sbi->s_freeclusters_counter, ac->ac_b_ex.fe_len);
+-      /*
+-       * Now reduce the dirty block count also. Should not go negative
+-       */
+-      if (!(ac->ac_flags & EXT4_MB_DELALLOC_RESERVED))
+-              /* release all the reserved blocks if non delalloc */
+-              percpu_counter_sub(&sbi->s_dirtyclusters_counter,
+-                                 reserv_clstrs);
+       return err;
+ }
+@@ -6328,7 +6320,7 @@ repeat:
+                       ext4_mb_pa_put_free(ac);
+       }
+       if (likely(ac->ac_status == AC_STATUS_FOUND)) {
+-              *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
++              *errp = ext4_mb_mark_diskspace_used(ac, handle);
+               if (*errp) {
+                       ext4_discard_allocated_blocks(ac);
+                       goto errout;
+@@ -6359,12 +6351,9 @@ errout:
+ out:
+       if (inquota && ar->len < inquota)
+               dquot_free_block(ar->inode, EXT4_C2B(sbi, inquota - ar->len));
+-      if (!ar->len) {
+-              if ((ar->flags & EXT4_MB_DELALLOC_RESERVED) == 0)
+-                      /* release all the reserved blocks if non delalloc */
+-                      percpu_counter_sub(&sbi->s_dirtyclusters_counter,
+-                                              reserv_clstrs);
+-      }
++      /* release any reserved blocks */
++      if (reserv_clstrs)
++              percpu_counter_sub(&sbi->s_dirtyclusters_counter, reserv_clstrs);
+       trace_ext4_allocate_blocks(ar, (unsigned long long)block);
diff --git a/queue-6.18/ext4-fix-e4b-bitmap-inconsistency-reports.patch b/queue-6.18/ext4-fix-e4b-bitmap-inconsistency-reports.patch
new file mode 100644 (file)
index 0000000..8da5e59
--- /dev/null
@@ -0,0 +1,122 @@
+From bdc56a9c46b2a99c12313122b9352b619a2e719e Mon Sep 17 00:00:00 2001
+From: Yongjian Sun <sunyongjian1@huawei.com>
+Date: Tue, 6 Jan 2026 17:08:20 +0800
+Subject: ext4: fix e4b bitmap inconsistency reports
+
+From: Yongjian Sun <sunyongjian1@huawei.com>
+
+commit bdc56a9c46b2a99c12313122b9352b619a2e719e upstream.
+
+A bitmap inconsistency issue was observed during stress tests under
+mixed huge-page workloads. Ext4 reported multiple e4b bitmap check
+failures like:
+
+ext4_mb_complex_scan_group:2508: group 350, 8179 free clusters as
+per group info. But got 8192 blocks
+
+Analysis and experimentation confirmed that the issue is caused by a
+race condition between page migration and bitmap modification. Although
+this timing window is extremely narrow, it is still hit in practice:
+
+folio_lock                        ext4_mb_load_buddy
+__migrate_folio
+  check ref count
+  folio_mc_copy                     __filemap_get_folio
+                                      folio_try_get(folio)
+                                  ......
+                                  mb_mark_used
+                                  ext4_mb_unload_buddy
+  __folio_migrate_mapping
+    folio_ref_freeze
+folio_unlock
+
+The root cause of this issue is that the fast path of load_buddy only
+increments the folio's reference count, which is insufficient to prevent
+concurrent folio migration. We observed that the folio migration process
+acquires the folio lock. Therefore, we can determine whether to take the
+fast path in load_buddy by checking the lock status. If the folio is
+locked, we opt for the slow path (which acquires the lock) to close this
+concurrency window.
+
+Additionally, this change addresses the following issues:
+
+When the DOUBLE_CHECK macro is enabled to inspect bitmap-related
+issues, the following error may be triggered:
+
+corruption in group 324 at byte 784(6272): f in copy != ff on
+disk/prealloc
+
+Analysis reveals that this is a false positive. There is a specific race
+window where the bitmap and the group descriptor become momentarily
+inconsistent, leading to this error report:
+
+ext4_mb_load_buddy                   ext4_mb_load_buddy
+  __filemap_get_folio(create|lock)
+    folio_lock
+  ext4_mb_init_cache
+    folio_mark_uptodate
+                                     __filemap_get_folio(no lock)
+                                     ......
+                                     mb_mark_used
+                                       mb_mark_used_double
+  mb_cmp_bitmaps
+                                       mb_set_bits(e4b->bd_bitmap)
+  folio_unlock
+
+The original logic assumed that since mb_cmp_bitmaps is called when the
+bitmap is newly loaded from disk, the folio lock would be sufficient to
+prevent concurrent access. However, this overlooks a specific race
+condition: if another process attempts to load buddy and finds the folio
+is already in an uptodate state, it will immediately begin using it without
+holding folio lock.
+
+Signed-off-by: Yongjian Sun <sunyongjian1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://patch.msgid.link/20260106090820.836242-1-sunyongjian@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c |   21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -1712,16 +1712,17 @@ ext4_mb_load_buddy_gfp(struct super_bloc
+       /* Avoid locking the folio in the fast path ... */
+       folio = __filemap_get_folio(inode->i_mapping, pnum, FGP_ACCESSED, 0);
+-      if (IS_ERR(folio) || !folio_test_uptodate(folio)) {
++      if (IS_ERR(folio) || !folio_test_uptodate(folio) || folio_test_locked(folio)) {
++              /*
++               * folio_test_locked is employed to detect ongoing folio
++               * migrations, since concurrent migrations can lead to
++               * bitmap inconsistency. And if we are not uptodate that
++               * implies somebody just created the folio but is yet to
++               * initialize it. We can drop the folio reference and
++               * try to get the folio with lock in both cases to avoid
++               * concurrency.
++               */
+               if (!IS_ERR(folio))
+-                      /*
+-                       * drop the folio reference and try
+-                       * to get the folio with lock. If we
+-                       * are not uptodate that implies
+-                       * somebody just created the folio but
+-                       * is yet to initialize it. So
+-                       * wait for it to initialize.
+-                       */
+                       folio_put(folio);
+               folio = __filemap_get_folio(inode->i_mapping, pnum,
+                               FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);
+@@ -1763,7 +1764,7 @@ ext4_mb_load_buddy_gfp(struct super_bloc
+       poff = block % blocks_per_page;
+       folio = __filemap_get_folio(inode->i_mapping, pnum, FGP_ACCESSED, 0);
+-      if (IS_ERR(folio) || !folio_test_uptodate(folio)) {
++      if (IS_ERR(folio) || !folio_test_uptodate(folio) || folio_test_locked(folio)) {
+               if (!IS_ERR(folio))
+                       folio_put(folio);
+               folio = __filemap_get_folio(inode->i_mapping, pnum,
diff --git a/queue-6.18/ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch b/queue-6.18/ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch
new file mode 100644 (file)
index 0000000..26646d9
--- /dev/null
@@ -0,0 +1,40 @@
+From ca81109d4a8f192dc1cbad4a1ee25246363c2833 Mon Sep 17 00:00:00 2001
+From: Zilin Guan <zilin@seu.edu.cn>
+Date: Thu, 25 Dec 2025 08:48:00 +0000
+Subject: ext4: fix memory leak in ext4_ext_shift_extents()
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+commit ca81109d4a8f192dc1cbad4a1ee25246363c2833 upstream.
+
+In ext4_ext_shift_extents(), if the extent is NULL in the while loop, the
+function returns immediately without releasing the path obtained via
+ext4_find_extent(), leading to a memory leak.
+
+Fix this by jumping to the out label to ensure the path is properly
+released.
+
+Fixes: a18ed359bdddc ("ext4: always check ext4_ext_find_extent result")
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Link: https://patch.msgid.link/20251225084800.905701-1-zilin@seu.edu.cn
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5410,7 +5410,8 @@ again:
+               if (!extent) {
+                       EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
+                                        (unsigned long) *iterator);
+-                      return -EFSCORRUPTED;
++                      ret = -EFSCORRUPTED;
++                      goto out;
+               }
+               if (SHIFT == SHIFT_LEFT && *iterator >
+                   le32_to_cpu(extent->ee_block)) {
diff --git a/queue-6.18/ext4-subdivide-ext4_ext_data_valid1.patch b/queue-6.18/ext4-subdivide-ext4_ext_data_valid1.patch
new file mode 100644 (file)
index 0000000..5546734
--- /dev/null
@@ -0,0 +1,85 @@
+From 22784ca541c0f01c5ebad14e8228298dc0a390ed Mon Sep 17 00:00:00 2001
+From: Zhang Yi <yi.zhang@huawei.com>
+Date: Sat, 29 Nov 2025 18:32:33 +0800
+Subject: ext4: subdivide EXT4_EXT_DATA_VALID1
+
+From: Zhang Yi <yi.zhang@huawei.com>
+
+commit 22784ca541c0f01c5ebad14e8228298dc0a390ed upstream.
+
+When splitting an extent, if the EXT4_GET_BLOCKS_CONVERT flag is set and
+it is necessary to split the target extent in the middle,
+ext4_split_extent() first handles splitting the latter half of the
+extent and passes the EXT4_EXT_DATA_VALID1 flag. This flag implies that
+all blocks before the split point contain valid data; however, this
+assumption is incorrect.
+
+Therefore, subdivid EXT4_EXT_DATA_VALID1 into
+EXT4_EXT_DATA_ENTIRE_VALID1 and EXT4_EXT_DATA_PARTIAL_VALID1, which
+indicate that the first half of the extent is either entirely valid or
+only partially valid, respectively. These two flags cannot be set
+simultaneously.
+
+This patch does not use EXT4_EXT_DATA_PARTIAL_VALID1, it only replaces
+EXT4_EXT_DATA_VALID1 with EXT4_EXT_DATA_ENTIRE_VALID1 at the location
+where it is set, no logical changes.
+
+Signed-off-by: Zhang Yi <yi.zhang@huawei.com>
+Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Cc: stable@kernel.org
+Message-ID: <20251129103247.686136-2-yi.zhang@huaweicloud.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -43,8 +43,13 @@
+ #define EXT4_EXT_MARK_UNWRIT1 0x2  /* mark first half unwritten */
+ #define EXT4_EXT_MARK_UNWRIT2 0x4  /* mark second half unwritten */
+-#define EXT4_EXT_DATA_VALID1  0x8  /* first half contains valid data */
+-#define EXT4_EXT_DATA_VALID2  0x10 /* second half contains valid data */
++/* first half contains valid data */
++#define EXT4_EXT_DATA_ENTIRE_VALID1   0x8   /* has entirely valid data */
++#define EXT4_EXT_DATA_PARTIAL_VALID1  0x10  /* has partially valid data */
++#define EXT4_EXT_DATA_VALID1          (EXT4_EXT_DATA_ENTIRE_VALID1 | \
++                                       EXT4_EXT_DATA_PARTIAL_VALID1)
++
++#define EXT4_EXT_DATA_VALID2  0x20 /* second half contains valid data */
+ static __le32 ext4_extent_block_csum(struct inode *inode,
+                                    struct ext4_extent_header *eh)
+@@ -3190,8 +3195,9 @@ static struct ext4_ext_path *ext4_split_
+       unsigned int ee_len, depth;
+       int err = 0;
+-      BUG_ON((split_flag & (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)) ==
+-             (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2));
++      BUG_ON((split_flag & EXT4_EXT_DATA_VALID1) == EXT4_EXT_DATA_VALID1);
++      BUG_ON((split_flag & EXT4_EXT_DATA_VALID1) &&
++             (split_flag & EXT4_EXT_DATA_VALID2));
+       ext_debug(inode, "logical block %llu\n", (unsigned long long)split);
+@@ -3373,7 +3379,7 @@ static struct ext4_ext_path *ext4_split_
+                       split_flag1 |= EXT4_EXT_MARK_UNWRIT1 |
+                                      EXT4_EXT_MARK_UNWRIT2;
+               if (split_flag & EXT4_EXT_DATA_VALID2)
+-                      split_flag1 |= EXT4_EXT_DATA_VALID1;
++                      split_flag1 |= EXT4_EXT_DATA_ENTIRE_VALID1;
+               path = ext4_split_extent_at(handle, inode, path,
+                               map->m_lblk + map->m_len, split_flag1, flags1);
+               if (IS_ERR(path))
+@@ -3732,7 +3738,7 @@ static struct ext4_ext_path *ext4_split_
+       /* Convert to unwritten */
+       if (flags & EXT4_GET_BLOCKS_CONVERT_UNWRITTEN) {
+-              split_flag |= EXT4_EXT_DATA_VALID1;
++              split_flag |= EXT4_EXT_DATA_ENTIRE_VALID1;
+       /* Convert to initialized */
+       } else if (flags & EXT4_GET_BLOCKS_CONVERT) {
+               split_flag |= ee_block + ee_len <= eof_block ?
diff --git a/queue-6.18/ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch b/queue-6.18/ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch
new file mode 100644 (file)
index 0000000..45822cd
--- /dev/null
@@ -0,0 +1,43 @@
+From 3574c322b1d0eb32dbd76b469cb08f9a67641599 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 14 Jan 2026 19:28:19 +0100
+Subject: ext4: use optimized mballoc scanning regardless of inode format
+
+From: Jan Kara <jack@suse.cz>
+
+commit 3574c322b1d0eb32dbd76b469cb08f9a67641599 upstream.
+
+Currently we don't used mballoc optimized scanning (using max free
+extent order and avg free extent order group lists) for inodes with
+indirect block based format. This is confusing for users and I don't see
+a good reason for that. Even with indirect block based inode format we
+can spend big amount of time searching for free blocks for large
+filesystems with fragmented free space. To add to the confusion before
+commit 077d0c2c78df ("ext4: make mb_optimize_scan performance mount
+option work with extents") optimized scanning was applied *only* to
+indirect block based inodes so that commit appears as a performance
+regression to some users. Just use optimized scanning whenever it is
+enabled by mount options.
+
+Reviewed-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Cc: stable@kernel.org
+Link: https://patch.msgid.link/20260114182836.14120-4-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -1148,8 +1148,6 @@ static inline int should_optimize_scan(s
+               return 0;
+       if (ac->ac_criteria >= CR_GOAL_LEN_SLOW)
+               return 0;
+-      if (!ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS))
+-              return 0;
+       return 1;
+ }
diff --git a/queue-6.18/mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch b/queue-6.18/mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch
new file mode 100644 (file)
index 0000000..0479a0e
--- /dev/null
@@ -0,0 +1,98 @@
+From 30bfc2d6a1132a89a5f1c3b96c59cf3e4d076ea3 Mon Sep 17 00:00:00 2001
+From: Yao Zi <me@ziyao.cc>
+Date: Thu, 5 Feb 2026 15:56:44 +0000
+Subject: MIPS: Work around LLVM bug when gp is used as global register variable
+
+From: Yao Zi <me@ziyao.cc>
+
+commit 30bfc2d6a1132a89a5f1c3b96c59cf3e4d076ea3 upstream.
+
+On MIPS, __current_thread_info is defined as global register variable
+locating in $gp, and is simply assigned with new address during kernel
+relocation.
+
+This however is broken with LLVM, which always restores $gp if it finds
+$gp is clobbered in any form, including when intentionally through a
+global register variable. This is against GCC's documentation[1], which
+requires a callee-saved register used as global register variable not to
+be restored if it's clobbered.
+
+As a result, $gp will continue to point to the unrelocated kernel after
+the epilog of relocate_kernel(), leading to an early crash in init_idle,
+
+[    0.000000] CPU 0 Unable to handle kernel paging request at virtual address 0000000000000000, epc == ffffffff81afada8, ra == ffffffff81afad90
+[    0.000000] Oops[#1]:
+[    0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Tainted: G        W           6.19.0-rc5-00262-gd3eeb99bbc99-dirty #188 VOLUNTARY
+[    0.000000] Tainted: [W]=WARN
+[    0.000000] Hardware name: loongson,loongson64v-4core-virtio
+[    0.000000] $ 0   : 0000000000000000 0000000000000000 0000000000000001 0000000000000000
+[    0.000000] $ 4   : ffffffff80b80ec0 ffffffff80b53d48 0000000000000000 00000000000f4240
+[    0.000000] $ 8   : 0000000000000100 ffffffff81d82f80 ffffffff81d82f80 0000000000000001
+[    0.000000] $12   : 0000000000000000 ffffffff81776f58 00000000000005da 0000000000000002
+[    0.000000] $16   : ffffffff80b80e40 0000000000000000 ffffffff80b81614 9800000005dfbe80
+[    0.000000] $20   : 00000000540000e0 ffffffff81980000 0000000000000000 ffffffff80f81c80
+[    0.000000] $24   : 0000000000000a26 ffffffff8114fb90
+[    0.000000] $28   : ffffffff80b50000 ffffffff80b53d40 0000000000000000 ffffffff81afad90
+[    0.000000] Hi    : 0000000000000000
+[    0.000000] Lo    : 0000000000000000
+[    0.000000] epc   : ffffffff81afada8 init_idle+0x130/0x270
+[    0.000000] ra    : ffffffff81afad90 init_idle+0x118/0x270
+[    0.000000] Status: 540000e2        KX SX UX KERNEL EXL
+[    0.000000] Cause : 00000008 (ExcCode 02)
+[    0.000000] BadVA : 0000000000000000
+[    0.000000] PrId  : 00006305 (ICT Loongson-3)
+[    0.000000] Process swapper (pid: 0, threadinfo=(____ptrval____), task=(____ptrval____), tls=0000000000000000)
+[    0.000000] Stack : 9800000005dfbf00 ffffffff8178e950 0000000000000000 0000000000000000
+[    0.000000]         0000000000000000 ffffffff81970000 000000000000003f ffffffff810a6528
+[    0.000000]         0000000000000001 9800000005dfbe80 9800000005dfbf00 ffffffff81980000
+[    0.000000]         ffffffff810a6450 ffffffff81afb6c0 0000000000000000 ffffffff810a2258
+[    0.000000]         ffffffff81d82ec8 ffffffff8198d010 ffffffff81b67e80 ffffffff8197dd98
+[    0.000000]         ffffffff81d81c80 ffffffff81930000 0000000000000040 0000000000000000
+[    0.000000]         0000000000000000 0000000000000000 0000000000000000 0000000000000000
+[    0.000000]         0000000000000000 000000000000009e ffffffff9fc01000 0000000000000000
+[    0.000000]         0000000000000000 0000000000000000 0000000000000000 0000000000000000
+[    0.000000]         0000000000000000 ffffffff81ae86dc ffffffff81b3c741 0000000000000002
+[    0.000000]         ...
+[    0.000000] Call Trace:
+[    0.000000] [<ffffffff81afada8>] init_idle+0x130/0x270
+[    0.000000] [<ffffffff81afb6c0>] sched_init+0x5c8/0x6c0
+[    0.000000] [<ffffffff81ae86dc>] start_kernel+0x27c/0x7a8
+
+This bug has been reported to LLVM[2] and affects version from (at
+least) 18 to 21. Let's work around this by using inline assembly to
+assign $gp before a fix is widely available.
+
+Cc: stable@vger.kernel.org
+Link: https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Global-Register-Variables.html # [1]
+Link: https://github.com/llvm/llvm-project/issues/176546 # [2]
+Signed-off-by: Yao Zi <me@ziyao.cc>
+Acked-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/mips/kernel/relocate.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/mips/kernel/relocate.c
++++ b/arch/mips/kernel/relocate.c
+@@ -420,7 +420,20 @@ void *__init relocate_kernel(void)
+                       goto out;
+               /* The current thread is now within the relocated image */
++#ifndef CONFIG_CC_IS_CLANG
+               __current_thread_info = RELOCATED(&init_thread_union);
++#else
++              /*
++               * LLVM may wrongly restore $gp ($28) in epilog even if it's
++               * intentionally modified. Work around this by using inline
++               * assembly to assign $gp. $gp couldn't be listed as output or
++               * clobber, or LLVM will still restore its original value.
++               * See also LLVM upstream issue
++               * https://github.com/llvm/llvm-project/issues/176546
++               */
++              asm volatile("move $28, %0" : :
++                           "r" (RELOCATED(&init_thread_union)));
++#endif
+               /* Return the new kernel's entry point */
+               kernel_entry = RELOCATED(start_kernel);
index 11ed72b20f5c0a7c8ee9a54f7b2c8187586d6d09..08fd618c919824c8538d08fcdd0ec15fb556526c 100644 (file)
@@ -608,3 +608,28 @@ btrfs-fix-invalid-leaf-access-in-btrfs_quota_enable-.patch
 x86-hyperv-fix-error-pointer-dereference.patch
 asoc-rockchip-i2s-tdm-use-param-rate-if-not-provided.patch
 drm-amd-display-use-same-max-plane-scaling-limits-fo.patch
+usb-cdns3-fix-role-switching-during-resume.patch
+mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch
+ext4-subdivide-ext4_ext_data_valid1.patch
+ext4-don-t-zero-the-entire-extent-if-ext4_ext_data_partial_valid1.patch
+ext4-don-t-cache-extent-during-splitting-extent.patch
+ext4-drop-extent-cache-after-doing-partial_valid1-zeroout.patch
+ext4-drop-extent-cache-when-splitting-extent-fails.patch
+ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch
+ext4-fix-e4b-bitmap-inconsistency-reports.patch
+ext4-fix-dirtyclusters-double-decrement-on-fs-shutdown.patch
+ext4-always-allocate-blocks-only-from-groups-inode-can-use.patch
+ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch
+ata-pata_ftide010-fix-some-dma-timings.patch
+ata-libata-scsi-refactor-ata_scsi_translate.patch
+ata-libata-scsi-avoid-non-ncq-command-starvation.patch
+sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch
+sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch
+dt-bindings-phy-qcom-edp-add-missing-clock-for-x-elite.patch
+dt-bindings-media-qcom-qcs8300-camss-add-missing-power-supplies.patch
+asoc-dt-bindings-asahi-kasei-ak4458-set-unevaluatedproperties-false.patch
+asoc-dt-bindings-asahi-kasei-ak4458-fix-the-supply-names.patch
+asoc-dt-bindings-asahi-kasei-ak5558-fix-the-supply-names.patch
+alsa-hda-realtek-add-quirk-for-gigabyte-g5-kf5-2023.patch
+alsa-hda-conexant-fix-headphone-jack-handling-on-acer-swift-sf314.patch
+alsa-hda-realtek-add-quirk-for-samsung-galaxy-book3-pro-360-np965qfg.patch
diff --git a/queue-6.18/sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch b/queue-6.18/sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch
new file mode 100644 (file)
index 0000000..1758317
--- /dev/null
@@ -0,0 +1,222 @@
+From 3e6397b056335cc56ef0e9da36c95946a19f5118 Mon Sep 17 00:00:00 2001
+From: Chuck Lever <chuck.lever@oracle.com>
+Date: Fri, 26 Dec 2025 10:15:32 -0500
+Subject: SUNRPC: auth_gss: fix memory leaks in XDR decoding error paths
+
+From: Chuck Lever <chuck.lever@oracle.com>
+
+commit 3e6397b056335cc56ef0e9da36c95946a19f5118 upstream.
+
+The gssx_dec_ctx(), gssx_dec_status(), and gssx_dec_name()
+functions allocate memory via gssx_dec_buffer(), which calls
+kmemdup(). When a subsequent decode operation fails, these
+functions return immediately without freeing previously
+allocated buffers, causing memory leaks.
+
+The leak in gssx_dec_ctx() is particularly relevant because
+the caller (gssp_accept_sec_context_upcall) initializes several
+buffer length fields to non-zero values, resulting in memory
+allocation:
+
+    struct gssx_ctx rctxh = {
+        .exported_context_token.len = GSSX_max_output_handle_sz,
+        .mech.len = GSS_OID_MAX_LEN,
+        .src_name.display_name.len = GSSX_max_princ_sz,
+        .targ_name.display_name.len = GSSX_max_princ_sz
+    };
+
+If, for example, gssx_dec_name() succeeds for src_name but
+fails for targ_name, the memory allocated for
+exported_context_token, mech, and src_name.display_name
+remains unreferenced and cannot be reclaimed.
+
+Add error handling with goto-based cleanup to free any
+previously allocated buffers before returning an error.
+
+Reported-by: Xingjing Deng <micro6947@gmail.com>
+Closes: https://lore.kernel.org/linux-nfs/CAK+ZN9qttsFDu6h1FoqGadXjMx1QXqPMoYQ=6O9RY4SxVTvKng@mail.gmail.com/
+Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth")
+Cc: stable@vger.kernel.org
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sunrpc/auth_gss/gss_rpc_xdr.c |   82 +++++++++++++++++++++++++++++---------
+ 1 file changed, 64 insertions(+), 18 deletions(-)
+
+--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c
++++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c
+@@ -320,29 +320,47 @@ static int gssx_dec_status(struct xdr_st
+       /* status->minor_status */
+       p = xdr_inline_decode(xdr, 8);
+-      if (unlikely(p == NULL))
+-              return -ENOSPC;
++      if (unlikely(p == NULL)) {
++              err = -ENOSPC;
++              goto out_free_mech;
++      }
+       p = xdr_decode_hyper(p, &status->minor_status);
+       /* status->major_status_string */
+       err = gssx_dec_buffer(xdr, &status->major_status_string);
+       if (err)
+-              return err;
++              goto out_free_mech;
+       /* status->minor_status_string */
+       err = gssx_dec_buffer(xdr, &status->minor_status_string);
+       if (err)
+-              return err;
++              goto out_free_major_status_string;
+       /* status->server_ctx */
+       err = gssx_dec_buffer(xdr, &status->server_ctx);
+       if (err)
+-              return err;
++              goto out_free_minor_status_string;
+       /* we assume we have no options for now, so simply consume them */
+       /* status->options */
+       err = dummy_dec_opt_array(xdr, &status->options);
++      if (err)
++              goto out_free_server_ctx;
++      return 0;
++
++out_free_server_ctx:
++      kfree(status->server_ctx.data);
++      status->server_ctx.data = NULL;
++out_free_minor_status_string:
++      kfree(status->minor_status_string.data);
++      status->minor_status_string.data = NULL;
++out_free_major_status_string:
++      kfree(status->major_status_string.data);
++      status->major_status_string.data = NULL;
++out_free_mech:
++      kfree(status->mech.data);
++      status->mech.data = NULL;
+       return err;
+ }
+@@ -505,28 +523,35 @@ static int gssx_dec_name(struct xdr_stre
+       /* name->name_type */
+       err = gssx_dec_buffer(xdr, &dummy_netobj);
+       if (err)
+-              return err;
++              goto out_free_display_name;
+       /* name->exported_name */
+       err = gssx_dec_buffer(xdr, &dummy_netobj);
+       if (err)
+-              return err;
++              goto out_free_display_name;
+       /* name->exported_composite_name */
+       err = gssx_dec_buffer(xdr, &dummy_netobj);
+       if (err)
+-              return err;
++              goto out_free_display_name;
+       /* we assume we have no attributes for now, so simply consume them */
+       /* name->name_attributes */
+       err = dummy_dec_nameattr_array(xdr, &dummy_name_attr_array);
+       if (err)
+-              return err;
++              goto out_free_display_name;
+       /* we assume we have no options for now, so simply consume them */
+       /* name->extensions */
+       err = dummy_dec_opt_array(xdr, &dummy_option_array);
++      if (err)
++              goto out_free_display_name;
++      return 0;
++
++out_free_display_name:
++      kfree(name->display_name.data);
++      name->display_name.data = NULL;
+       return err;
+ }
+@@ -649,32 +674,34 @@ static int gssx_dec_ctx(struct xdr_strea
+       /* ctx->state */
+       err = gssx_dec_buffer(xdr, &ctx->state);
+       if (err)
+-              return err;
++              goto out_free_exported_context_token;
+       /* ctx->need_release */
+       err = gssx_dec_bool(xdr, &ctx->need_release);
+       if (err)
+-              return err;
++              goto out_free_state;
+       /* ctx->mech */
+       err = gssx_dec_buffer(xdr, &ctx->mech);
+       if (err)
+-              return err;
++              goto out_free_state;
+       /* ctx->src_name */
+       err = gssx_dec_name(xdr, &ctx->src_name);
+       if (err)
+-              return err;
++              goto out_free_mech;
+       /* ctx->targ_name */
+       err = gssx_dec_name(xdr, &ctx->targ_name);
+       if (err)
+-              return err;
++              goto out_free_src_name;
+       /* ctx->lifetime */
+       p = xdr_inline_decode(xdr, 8+8);
+-      if (unlikely(p == NULL))
+-              return -ENOSPC;
++      if (unlikely(p == NULL)) {
++              err = -ENOSPC;
++              goto out_free_targ_name;
++      }
+       p = xdr_decode_hyper(p, &ctx->lifetime);
+       /* ctx->ctx_flags */
+@@ -683,17 +710,36 @@ static int gssx_dec_ctx(struct xdr_strea
+       /* ctx->locally_initiated */
+       err = gssx_dec_bool(xdr, &ctx->locally_initiated);
+       if (err)
+-              return err;
++              goto out_free_targ_name;
+       /* ctx->open */
+       err = gssx_dec_bool(xdr, &ctx->open);
+       if (err)
+-              return err;
++              goto out_free_targ_name;
+       /* we assume we have no options for now, so simply consume them */
+       /* ctx->options */
+       err = dummy_dec_opt_array(xdr, &ctx->options);
++      if (err)
++              goto out_free_targ_name;
++
++      return 0;
++out_free_targ_name:
++      kfree(ctx->targ_name.display_name.data);
++      ctx->targ_name.display_name.data = NULL;
++out_free_src_name:
++      kfree(ctx->src_name.display_name.data);
++      ctx->src_name.display_name.data = NULL;
++out_free_mech:
++      kfree(ctx->mech.data);
++      ctx->mech.data = NULL;
++out_free_state:
++      kfree(ctx->state.data);
++      ctx->state.data = NULL;
++out_free_exported_context_token:
++      kfree(ctx->exported_context_token.data);
++      ctx->exported_context_token.data = NULL;
+       return err;
+ }
diff --git a/queue-6.18/sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch b/queue-6.18/sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch
new file mode 100644 (file)
index 0000000..090eab2
--- /dev/null
@@ -0,0 +1,51 @@
+From dd2fdc3504592d85e549c523b054898a036a6afe Mon Sep 17 00:00:00 2001
+From: Daniel Hodges <git@danielhodges.dev>
+Date: Fri, 6 Feb 2026 15:41:46 -0500
+Subject: SUNRPC: fix gss_auth kref leak in gss_alloc_msg error path
+
+From: Daniel Hodges <git@danielhodges.dev>
+
+commit dd2fdc3504592d85e549c523b054898a036a6afe upstream.
+
+Commit 5940d1cf9f42 ("SUNRPC: Rebalance a kref in auth_gss.c") added
+a kref_get(&gss_auth->kref) call to balance the gss_put_auth() done
+in gss_release_msg(), but forgot to add a corresponding kref_put()
+on the error path when kstrdup_const() fails.
+
+If service_name is non-NULL and kstrdup_const() fails, the function
+jumps to err_put_pipe_version which calls put_pipe_version() and
+kfree(gss_msg), but never releases the gss_auth reference. This leads
+to a kref leak where the gss_auth structure is never freed.
+
+Add a forward declaration for gss_free_callback() and call kref_put()
+in the err_put_pipe_version error path to properly release the
+reference taken earlier.
+
+Fixes: 5940d1cf9f42 ("SUNRPC: Rebalance a kref in auth_gss.c")
+Cc: stable@vger.kernel.org
+Signed-off-by: Daniel Hodges <git@danielhodges.dev>
+Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sunrpc/auth_gss/auth_gss.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -39,6 +39,8 @@ static const struct rpc_authops authgss_
+ static const struct rpc_credops gss_credops;
+ static const struct rpc_credops gss_nullops;
++static void gss_free_callback(struct kref *kref);
++
+ #define GSS_RETRY_EXPIRED 5
+ static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
+@@ -551,6 +553,7 @@ gss_alloc_msg(struct gss_auth *gss_auth,
+       }
+       return gss_msg;
+ err_put_pipe_version:
++      kref_put(&gss_auth->kref, gss_free_callback);
+       put_pipe_version(gss_auth->net);
+ err_free_msg:
+       kfree(gss_msg);
diff --git a/queue-6.18/usb-cdns3-fix-role-switching-during-resume.patch b/queue-6.18/usb-cdns3-fix-role-switching-during-resume.patch
new file mode 100644 (file)
index 0000000..a7a53e1
--- /dev/null
@@ -0,0 +1,87 @@
+From 87e4b043b98a1d269be0b812f383881abee0ca45 Mon Sep 17 00:00:00 2001
+From: "Thomas Richard (TI)" <thomas.richard@bootlin.com>
+Date: Fri, 30 Jan 2026 11:05:45 +0100
+Subject: usb: cdns3: fix role switching during resume
+
+From: Thomas Richard (TI) <thomas.richard@bootlin.com>
+
+commit 87e4b043b98a1d269be0b812f383881abee0ca45 upstream.
+
+If the role change while we are suspended, the cdns3 driver switches to the
+new mode during resume. However, switching to host mode in this context
+causes a NULL pointer dereference.
+
+The host role's start() operation registers a xhci-hcd device, but its
+probe is deferred while we are in the resume path. The host role's resume()
+operation assumes the xhci-hcd device is already probed, which is not the
+case, leading to the dereference. Since the start() operation of the new
+role is already called, the resume operation can be skipped.
+
+So skip the resume operation for the new role if a role switch occurs
+during resume. Once the resume sequence is complete, the xhci-hcd device
+can be probed in case of host mode.
+
+Unable to handle kernel NULL pointer dereference at virtual address 0000000000000208
+Mem abort info:
+...
+Data abort info:
+...
+[0000000000000208] pgd=0000000000000000, p4d=0000000000000000
+Internal error: Oops: 0000000096000004 [#1]  SMP
+Modules linked in:
+CPU: 0 UID: 0 PID: 146 Comm: sh Not tainted
+6.19.0-rc7-00013-g6e64f4aabfae-dirty #135 PREEMPT
+Hardware name: Texas Instruments J7200 EVM (DT)
+pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : usb_hcd_is_primary_hcd+0x0/0x1c
+lr : cdns_host_resume+0x24/0x5c
+...
+Call trace:
+ usb_hcd_is_primary_hcd+0x0/0x1c (P)
+ cdns_resume+0x6c/0xbc
+ cdns3_controller_resume.isra.0+0xe8/0x17c
+ cdns3_plat_resume+0x18/0x24
+ platform_pm_resume+0x2c/0x68
+ dpm_run_callback+0x90/0x248
+ device_resume+0x100/0x24c
+ dpm_resume+0x190/0x2ec
+ dpm_resume_end+0x18/0x34
+ suspend_devices_and_enter+0x2b0/0xa44
+ pm_suspend+0x16c/0x5fc
+ state_store+0x80/0xec
+ kobj_attr_store+0x18/0x2c
+ sysfs_kf_write+0x7c/0x94
+ kernfs_fop_write_iter+0x130/0x1dc
+ vfs_write+0x240/0x370
+ ksys_write+0x70/0x108
+ __arm64_sys_write+0x1c/0x28
+ invoke_syscall+0x48/0x10c
+ el0_svc_common.constprop.0+0x40/0xe0
+ do_el0_svc+0x1c/0x28
+ el0_svc+0x34/0x108
+ el0t_64_sync_handler+0xa0/0xe4
+ el0t_64_sync+0x198/0x19c
+Code: 52800003 f9407ca5 d63f00a0 17ffffe4 (f9410401)
+---[ end trace 0000000000000000 ]---
+
+Cc: stable <stable@kernel.org>
+Fixes: 2cf2581cd229 ("usb: cdns3: add power lost support for system resume")
+Signed-off-by: Thomas Richard (TI) <thomas.richard@bootlin.com>
+Acked-by: Peter Chen <peter.chen@kernel.org>
+Link: https://patch.msgid.link/20260130-usb-cdns3-fix-role-switching-during-resume-v1-1-44c456852b52@bootlin.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/cdns3/core.c
++++ b/drivers/usb/cdns3/core.c
+@@ -551,7 +551,7 @@ int cdns_resume(struct cdns *cdns)
+               }
+       }
+-      if (cdns->roles[cdns->role]->resume)
++      if (!role_changed && cdns->roles[cdns->role]->resume)
+               cdns->roles[cdns->role]->resume(cdns, power_lost);
+       return 0;