]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Sat, 23 Sep 2023 12:16:15 +0000 (08:16 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 23 Sep 2023 12:16:15 +0000 (08:16 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
16 files changed:
queue-5.10/ata-ahci-drop-pointless-vprintk-calls-and-convert-th.patch [new file with mode: 0644]
queue-5.10/ata-libahci-clear-pending-interrupt-status.patch [new file with mode: 0644]
queue-5.10/ext4-add-new-helper-interface-ext4_try_to_trim_range.patch [new file with mode: 0644]
queue-5.10/ext4-change-s_last_trim_minblks-type-to-unsigned-lon.patch [new file with mode: 0644]
queue-5.10/ext4-do-not-let-fstrim-block-system-suspend.patch [new file with mode: 0644]
queue-5.10/ext4-mark-group-as-trimmed-only-if-it-was-fully-scan.patch [new file with mode: 0644]
queue-5.10/ext4-move-setting-of-trimmed-bit-into-ext4_try_to_tr.patch [new file with mode: 0644]
queue-5.10/ext4-remove-the-group-parameter-of-ext4_trim_extent.patch [new file with mode: 0644]
queue-5.10/ext4-replace-the-traditional-ternary-conditional-ope.patch [new file with mode: 0644]
queue-5.10/ext4-scope-ret-locally-in-ext4_try_to_trim_range.patch [new file with mode: 0644]
queue-5.10/nfs-pnfs-report-einval-errors-from-connect-to-the-se.patch [new file with mode: 0644]
queue-5.10/nfs-use-the-correct-commit-info-in-nfs_join_page_gro.patch [new file with mode: 0644]
queue-5.10/series [new file with mode: 0644]
queue-5.10/sunrpc-mark-the-cred-for-revalidation-if-the-server-.patch [new file with mode: 0644]
queue-5.10/tracing-have-event-inject-files-inc-the-trace-array-.patch [new file with mode: 0644]
queue-5.10/tracing-increase-trace-array-ref-count-on-enable-and.patch [new file with mode: 0644]

diff --git a/queue-5.10/ata-ahci-drop-pointless-vprintk-calls-and-convert-th.patch b/queue-5.10/ata-ahci-drop-pointless-vprintk-calls-and-convert-th.patch
new file mode 100644 (file)
index 0000000..96821b9
--- /dev/null
@@ -0,0 +1,155 @@
+From eadb1c5c1c49c4ac6f9333730a5c566529e57510 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 21 Dec 2021 08:20:47 +0100
+Subject: ata: ahci: Drop pointless VPRINTK() calls and convert the remaining
+ ones
+
+From: Hannes Reinecke <hare@suse.de>
+
+[ Upstream commit 93c7711494f47f9c829321e2a8711671b02f6e4c ]
+
+Drop pointless VPRINTK() calls for entering and existing interrupt
+routines and convert the remaining calls to dev_dbg().
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Stable-dep-of: 737dd811a3db ("ata: libahci: clear pending interrupt status")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/ahci.c       |  4 +---
+ drivers/ata/ahci_xgene.c |  4 ----
+ drivers/ata/libahci.c    | 18 ++++--------------
+ 3 files changed, 5 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index bf949f7da483f..d831a80c25f04 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -703,7 +703,7 @@ static void ahci_pci_init_controller(struct ata_host *host)
+               /* clear port IRQ */
+               tmp = readl(port_mmio + PORT_IRQ_STAT);
+-              VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
++              dev_dbg(&pdev->dev, "PORT_IRQ_STAT 0x%x\n", tmp);
+               if (tmp)
+                       writel(tmp, port_mmio + PORT_IRQ_STAT);
+       }
+@@ -1495,7 +1495,6 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
+       u32 irq_stat, irq_masked;
+       unsigned int handled = 1;
+-      VPRINTK("ENTER\n");
+       hpriv = host->private_data;
+       mmio = hpriv->mmio;
+       irq_stat = readl(mmio + HOST_IRQ_STAT);
+@@ -1512,7 +1511,6 @@ static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
+               irq_stat = readl(mmio + HOST_IRQ_STAT);
+               spin_unlock(&host->lock);
+       } while (irq_stat);
+-      VPRINTK("EXIT\n");
+       return IRQ_RETVAL(handled);
+ }
+diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
+index 16246c843365e..e0f0577ac191c 100644
+--- a/drivers/ata/ahci_xgene.c
++++ b/drivers/ata/ahci_xgene.c
+@@ -588,8 +588,6 @@ static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance)
+       void __iomem *mmio;
+       u32 irq_stat, irq_masked;
+-      VPRINTK("ENTER\n");
+-
+       hpriv = host->private_data;
+       mmio = hpriv->mmio;
+@@ -612,8 +610,6 @@ static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance)
+       spin_unlock(&host->lock);
+-      VPRINTK("EXIT\n");
+-
+       return IRQ_RETVAL(rc);
+ }
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index fec2e9754aed2..08c4b641691b1 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -1215,12 +1215,12 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
+       /* clear SError */
+       tmp = readl(port_mmio + PORT_SCR_ERR);
+-      VPRINTK("PORT_SCR_ERR 0x%x\n", tmp);
++      dev_dbg(dev, "PORT_SCR_ERR 0x%x\n", tmp);
+       writel(tmp, port_mmio + PORT_SCR_ERR);
+       /* clear port IRQ */
+       tmp = readl(port_mmio + PORT_IRQ_STAT);
+-      VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
++      dev_dbg(dev, "PORT_IRQ_STAT 0x%x\n", tmp);
+       if (tmp)
+               writel(tmp, port_mmio + PORT_IRQ_STAT);
+@@ -1251,10 +1251,10 @@ void ahci_init_controller(struct ata_host *host)
+       }
+       tmp = readl(mmio + HOST_CTL);
+-      VPRINTK("HOST_CTL 0x%x\n", tmp);
++      dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp);
+       writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL);
+       tmp = readl(mmio + HOST_CTL);
+-      VPRINTK("HOST_CTL 0x%x\n", tmp);
++      dev_dbg(host->dev, "HOST_CTL 0x%x\n", tmp);
+ }
+ EXPORT_SYMBOL_GPL(ahci_init_controller);
+@@ -1905,8 +1905,6 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance)
+       void __iomem *port_mmio = ahci_port_base(ap);
+       u32 status;
+-      VPRINTK("ENTER\n");
+-
+       status = readl(port_mmio + PORT_IRQ_STAT);
+       writel(status, port_mmio + PORT_IRQ_STAT);
+@@ -1914,8 +1912,6 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance)
+       ahci_handle_port_interrupt(ap, port_mmio, status);
+       spin_unlock(ap->lock);
+-      VPRINTK("EXIT\n");
+-
+       return IRQ_HANDLED;
+ }
+@@ -1932,9 +1928,7 @@ u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
+               ap = host->ports[i];
+               if (ap) {
+                       ahci_port_intr(ap);
+-                      VPRINTK("port %u\n", i);
+               } else {
+-                      VPRINTK("port %u (no irq)\n", i);
+                       if (ata_ratelimit())
+                               dev_warn(host->dev,
+                                        "interrupt on disabled port %u\n", i);
+@@ -1955,8 +1949,6 @@ static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance)
+       void __iomem *mmio;
+       u32 irq_stat, irq_masked;
+-      VPRINTK("ENTER\n");
+-
+       hpriv = host->private_data;
+       mmio = hpriv->mmio;
+@@ -1984,8 +1976,6 @@ static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance)
+       spin_unlock(&host->lock);
+-      VPRINTK("EXIT\n");
+-
+       return IRQ_RETVAL(rc);
+ }
+-- 
+2.40.1
+
diff --git a/queue-5.10/ata-libahci-clear-pending-interrupt-status.patch b/queue-5.10/ata-libahci-clear-pending-interrupt-status.patch
new file mode 100644 (file)
index 0000000..cf949d5
--- /dev/null
@@ -0,0 +1,101 @@
+From 163f4a44885a3fdd1b55ae6e628d72d2930182eb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Sep 2023 16:17:10 +0800
+Subject: ata: libahci: clear pending interrupt status
+
+From: Szuying Chen <chensiying21@gmail.com>
+
+[ Upstream commit 737dd811a3dbfd7edd4ad2ba5152e93d99074f83 ]
+
+When a CRC error occurs, the HBA asserts an interrupt to indicate an
+interface fatal error (PxIS.IFS). The ISR clears PxIE and PxIS, then
+does error recovery. If the adapter receives another SDB FIS
+with an error (PxIS.TFES) from the device before the start of the EH
+recovery process, the interrupt signaling the new SDB cannot be
+serviced as PxIE was cleared already. This in turn results in the HBA
+inability to issue any command during the error recovery process after
+setting PxCMD.ST to 1 because PxIS.TFES is still set.
+
+According to AHCI 1.3.1 specifications section 6.2.2, fatal errors
+notified by setting PxIS.HBFS, PxIS.HBDS, PxIS.IFS or PxIS.TFES will
+cause the HBA to enter the ERR:Fatal state. In this state, the HBA
+shall not issue any new commands.
+
+To avoid this situation, introduce the function
+ahci_port_clear_pending_irq() to clear pending interrupts before
+executing a COMRESET. This follows the AHCI 1.3.1 - section 6.2.2.2
+specification.
+
+Signed-off-by: Szuying Chen <Chloe_Chen@asmedia.com.tw>
+Fixes: e0bfd149973d ("[PATCH] ahci: stop engine during hard reset")
+Cc: stable@vger.kernel.org
+Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/libahci.c | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index 08c4b641691b1..e188850f65ff2 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -1199,6 +1199,26 @@ static ssize_t ahci_activity_show(struct ata_device *dev, char *buf)
+       return sprintf(buf, "%d\n", emp->blink_policy);
+ }
++static void ahci_port_clear_pending_irq(struct ata_port *ap)
++{
++      struct ahci_host_priv *hpriv = ap->host->private_data;
++      void __iomem *port_mmio = ahci_port_base(ap);
++      u32 tmp;
++
++      /* clear SError */
++      tmp = readl(port_mmio + PORT_SCR_ERR);
++      dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp);
++      writel(tmp, port_mmio + PORT_SCR_ERR);
++
++      /* clear port IRQ */
++      tmp = readl(port_mmio + PORT_IRQ_STAT);
++      dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp);
++      if (tmp)
++              writel(tmp, port_mmio + PORT_IRQ_STAT);
++
++      writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT);
++}
++
+ static void ahci_port_init(struct device *dev, struct ata_port *ap,
+                          int port_no, void __iomem *mmio,
+                          void __iomem *port_mmio)
+@@ -1213,18 +1233,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
+       if (rc)
+               dev_warn(dev, "%s (%d)\n", emsg, rc);
+-      /* clear SError */
+-      tmp = readl(port_mmio + PORT_SCR_ERR);
+-      dev_dbg(dev, "PORT_SCR_ERR 0x%x\n", tmp);
+-      writel(tmp, port_mmio + PORT_SCR_ERR);
+-
+-      /* clear port IRQ */
+-      tmp = readl(port_mmio + PORT_IRQ_STAT);
+-      dev_dbg(dev, "PORT_IRQ_STAT 0x%x\n", tmp);
+-      if (tmp)
+-              writel(tmp, port_mmio + PORT_IRQ_STAT);
+-
+-      writel(1 << port_no, mmio + HOST_IRQ_STAT);
++      ahci_port_clear_pending_irq(ap);
+       /* mark esata ports */
+       tmp = readl(port_mmio + PORT_CMD);
+@@ -1554,6 +1563,8 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
+       tf.command = ATA_BUSY;
+       ata_tf_to_fis(&tf, 0, 0, d2h_fis);
++      ahci_port_clear_pending_irq(ap);
++
+       rc = sata_link_hardreset(link, timing, deadline, online,
+                                ahci_check_ready);
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-add-new-helper-interface-ext4_try_to_trim_range.patch b/queue-5.10/ext4-add-new-helper-interface-ext4_try_to_trim_range.patch
new file mode 100644 (file)
index 0000000..6ac564b
--- /dev/null
@@ -0,0 +1,165 @@
+From 94c43c58c9f68224449300d1526f1c07a416021c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Jul 2021 15:41:21 +0800
+Subject: ext4: add new helper interface ext4_try_to_trim_range()
+
+From: Wang Jianchao <wangjianchao@kuaishou.com>
+
+[ Upstream commit 6920b3913235f517728bb69abe9b39047a987113 ]
+
+There is no functional change in this patch but just split the
+codes, which serachs free block and does trim, into a new function
+ext4_try_to_trim_range. This is preparing for the following async
+backgroup discard.
+
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Signed-off-by: Wang Jianchao <wangjianchao@kuaishou.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20210724074124.25731-3-jianchao.wan9@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 45e4ab320c9b ("ext4: move setting of trimmed bit into ext4_try_to_trim_range()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 102 ++++++++++++++++++++++++++--------------------
+ 1 file changed, 57 insertions(+), 45 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 342225c1cf332..54c718d471978 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -5894,6 +5894,54 @@ __acquires(bitlock)
+       return ret;
+ }
++static int ext4_try_to_trim_range(struct super_block *sb,
++              struct ext4_buddy *e4b, ext4_grpblk_t start,
++              ext4_grpblk_t max, ext4_grpblk_t minblocks)
++{
++      ext4_grpblk_t next, count, free_count;
++      void *bitmap;
++      int ret = 0;
++
++      bitmap = e4b->bd_bitmap;
++      start = (e4b->bd_info->bb_first_free > start) ?
++              e4b->bd_info->bb_first_free : start;
++      count = 0;
++      free_count = 0;
++
++      while (start <= max) {
++              start = mb_find_next_zero_bit(bitmap, max + 1, start);
++              if (start > max)
++                      break;
++              next = mb_find_next_bit(bitmap, max + 1, start);
++
++              if ((next - start) >= minblocks) {
++                      ret = ext4_trim_extent(sb, start, next - start, e4b);
++                      if (ret && ret != -EOPNOTSUPP)
++                              break;
++                      ret = 0;
++                      count += next - start;
++              }
++              free_count += next - start;
++              start = next + 1;
++
++              if (fatal_signal_pending(current)) {
++                      count = -ERESTARTSYS;
++                      break;
++              }
++
++              if (need_resched()) {
++                      ext4_unlock_group(sb, e4b->bd_group);
++                      cond_resched();
++                      ext4_lock_group(sb, e4b->bd_group);
++              }
++
++              if ((e4b->bd_info->bb_free - free_count) < minblocks)
++                      break;
++      }
++
++      return count;
++}
++
+ /**
+  * ext4_trim_all_free -- function to trim all free space in alloc. group
+  * @sb:                       super block for file system
+@@ -5917,10 +5965,8 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+                  ext4_grpblk_t start, ext4_grpblk_t max,
+                  ext4_grpblk_t minblocks)
+ {
+-      void *bitmap;
+-      ext4_grpblk_t next, count = 0, free_count = 0;
+       struct ext4_buddy e4b;
+-      int ret = 0;
++      int ret;
+       trace_ext4_trim_all_free(sb, group, start, max);
+@@ -5930,57 +5976,23 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+                            ret, group);
+               return ret;
+       }
+-      bitmap = e4b.bd_bitmap;
+       ext4_lock_group(sb, group);
+-      if (EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) &&
+-          minblocks >= atomic_read(&EXT4_SB(sb)->s_last_trim_minblks))
+-              goto out;
+-
+-      start = (e4b.bd_info->bb_first_free > start) ?
+-              e4b.bd_info->bb_first_free : start;
+-      while (start <= max) {
+-              start = mb_find_next_zero_bit(bitmap, max + 1, start);
+-              if (start > max)
+-                      break;
+-              next = mb_find_next_bit(bitmap, max + 1, start);
+-
+-              if ((next - start) >= minblocks) {
+-                      ret = ext4_trim_extent(sb, start, next - start, &e4b);
+-                      if (ret && ret != -EOPNOTSUPP)
+-                              break;
+-                      ret = 0;
+-                      count += next - start;
+-              }
+-              free_count += next - start;
+-              start = next + 1;
+-
+-              if (fatal_signal_pending(current)) {
+-                      count = -ERESTARTSYS;
+-                      break;
+-              }
+-
+-              if (need_resched()) {
+-                      ext4_unlock_group(sb, group);
+-                      cond_resched();
+-                      ext4_lock_group(sb, group);
+-              }
+-
+-              if ((e4b.bd_info->bb_free - free_count) < minblocks)
+-                      break;
++      if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
++          minblocks < atomic_read(&EXT4_SB(sb)->s_last_trim_minblks)) {
++              ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
++              if (ret >= 0)
++                      EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
++      } else {
++              ret = 0;
+       }
+-      if (!ret) {
+-              ret = count;
+-              EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
+-      }
+-out:
+       ext4_unlock_group(sb, group);
+       ext4_mb_unload_buddy(&e4b);
+       ext4_debug("trimmed %d blocks in the group %d\n",
+-              count, group);
++              ret, group);
+       return ret;
+ }
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-change-s_last_trim_minblks-type-to-unsigned-lon.patch b/queue-5.10/ext4-change-s_last_trim_minblks-type-to-unsigned-lon.patch
new file mode 100644 (file)
index 0000000..3f49a3d
--- /dev/null
@@ -0,0 +1,64 @@
+From 145f12a5aaf9f0516b0aa6cfa3d4348078c4194a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Nov 2021 15:51:21 +0100
+Subject: ext4: change s_last_trim_minblks type to unsigned long
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+[ Upstream commit 2327fb2e23416cfb2795ccca2f77d4d65925be99 ]
+
+There is no good reason for the s_last_trim_minblks to be atomic. There is
+no data integrity needed and there is no real danger in setting and
+reading it in a racy manner. Change it to be unsigned long, the same type
+as s_clusters_per_group which is the maximum that's allowed.
+
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Suggested-by: Andreas Dilger <adilger@dilger.ca>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Link: https://lore.kernel.org/r/20211103145122.17338-1-lczerner@redhat.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 45e4ab320c9b ("ext4: move setting of trimmed bit into ext4_try_to_trim_range()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h    | 2 +-
+ fs/ext4/mballoc.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index c3e9cb5037631..fec021e6bb600 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1580,7 +1580,7 @@ struct ext4_sb_info {
+       struct task_struct *s_mmp_tsk;
+       /* record the last minlen when FITRIM is called. */
+-      atomic_t s_last_trim_minblks;
++      unsigned long s_last_trim_minblks;
+       /* Reference to checksum algorithm driver via cryptoapi */
+       struct crypto_shash *s_chksum_driver;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index e0428cec6ff60..7bc17eb5ea74a 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -5979,7 +5979,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+       ext4_lock_group(sb, group);
+       if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
+-          minblocks < atomic_read(&EXT4_SB(sb)->s_last_trim_minblks)) {
++          minblocks < EXT4_SB(sb)->s_last_trim_minblks) {
+               ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
+               if (ret >= 0)
+                       EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
+@@ -6090,7 +6090,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+       }
+       if (!ret)
+-              atomic_set(&EXT4_SB(sb)->s_last_trim_minblks, minlen);
++              EXT4_SB(sb)->s_last_trim_minblks = minlen;
+ out:
+       range->len = EXT4_C2B(EXT4_SB(sb), trimmed) << sb->s_blocksize_bits;
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-do-not-let-fstrim-block-system-suspend.patch b/queue-5.10/ext4-do-not-let-fstrim-block-system-suspend.patch
new file mode 100644 (file)
index 0000000..68454b9
--- /dev/null
@@ -0,0 +1,76 @@
+From 78a05a2f1a017e2f0f239661f2b84aa9a1835901 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 17:04:55 +0200
+Subject: ext4: do not let fstrim block system suspend
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 5229a658f6453362fbb9da6bf96872ef25a7097e ]
+
+Len Brown has reported that system suspend sometimes fail due to
+inability to freeze a task working in ext4_trim_fs() for one minute.
+Trimming a large filesystem on a disk that slowly processes discard
+requests can indeed take a long time. Since discard is just an advisory
+call, it is perfectly fine to interrupt it at any time and the return
+number of discarded blocks until that moment. Do that when we detect the
+task is being frozen.
+
+Cc: stable@kernel.org
+Reported-by: Len Brown <lenb@kernel.org>
+Suggested-by: Dave Chinner <david@fromorbit.com>
+References: https://bugzilla.kernel.org/show_bug.cgi?id=216322
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230913150504.9054-2-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 2907bf57744a8..b35d59d41c896 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -16,6 +16,7 @@
+ #include <linux/slab.h>
+ #include <linux/nospec.h>
+ #include <linux/backing-dev.h>
++#include <linux/freezer.h>
+ #include <trace/events/ext4.h>
+ /*
+@@ -5904,6 +5905,11 @@ static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb,
+                                       EXT4_CLUSTER_BITS(sb);
+ }
++static bool ext4_trim_interrupted(void)
++{
++      return fatal_signal_pending(current) || freezing(current);
++}
++
+ static int ext4_try_to_trim_range(struct super_block *sb,
+               struct ext4_buddy *e4b, ext4_grpblk_t start,
+               ext4_grpblk_t max, ext4_grpblk_t minblocks)
+@@ -5935,8 +5941,8 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+               free_count += next - start;
+               start = next + 1;
+-              if (fatal_signal_pending(current))
+-                      return -ERESTARTSYS;
++              if (ext4_trim_interrupted())
++                      return count;
+               if (need_resched()) {
+                       ext4_unlock_group(sb, e4b->bd_group);
+@@ -6063,6 +6069,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+       end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
+       for (group = first_group; group <= last_group; group++) {
++              if (ext4_trim_interrupted())
++                      break;
+               grp = ext4_get_group_info(sb, group);
+               if (!grp)
+                       continue;
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-mark-group-as-trimmed-only-if-it-was-fully-scan.patch b/queue-5.10/ext4-mark-group-as-trimmed-only-if-it-was-fully-scan.patch
new file mode 100644 (file)
index 0000000..b83b249
--- /dev/null
@@ -0,0 +1,107 @@
+From 61e3e2926388fd4caa217c6782d9a1f8f963d3c6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 Apr 2022 20:03:15 +0300
+Subject: ext4: mark group as trimmed only if it was fully scanned
+
+From: Dmitry Monakhov <dmtrmonakhov@yandex-team.ru>
+
+[ Upstream commit d63c00ea435a5352f486c259665a4ced60399421 ]
+
+Otherwise nonaligned fstrim calls will works inconveniently for iterative
+scanners, for example:
+
+// trim [0,16MB] for group-1, but mark full group as trimmed
+fstrim  -o $((1024*1024*128)) -l $((1024*1024*16)) ./m
+// handle [16MB,16MB] for group-1, do nothing because group already has the flag.
+fstrim  -o $((1024*1024*144)) -l $((1024*1024*16)) ./m
+
+[ Update function documentation for ext4_trim_all_free -- TYT ]
+
+Signed-off-by: Dmitry Monakhov <dmtrmonakhov@yandex-team.ru>
+Link: https://lore.kernel.org/r/1650214995-860245-1-git-send-email-dmtrmonakhov@yandex-team.ru
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Stable-dep-of: 45e4ab320c9b ("ext4: move setting of trimmed bit into ext4_try_to_trim_range()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 7bc17eb5ea74a..5c650e28dcb6b 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -5948,6 +5948,7 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+  * @start:            first group block to examine
+  * @max:              last group block to examine
+  * @minblocks:                minimum extent block count
++ * @set_trimmed:      set the trimmed flag if at least one block is trimmed
+  *
+  * ext4_trim_all_free walks through group's buddy bitmap searching for free
+  * extents. When the free block is found, ext4_trim_extent is called to TRIM
+@@ -5962,7 +5963,7 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+ static ext4_grpblk_t
+ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+                  ext4_grpblk_t start, ext4_grpblk_t max,
+-                 ext4_grpblk_t minblocks)
++                 ext4_grpblk_t minblocks, bool set_trimmed)
+ {
+       struct ext4_buddy e4b;
+       int ret;
+@@ -5981,7 +5982,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+       if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
+           minblocks < EXT4_SB(sb)->s_last_trim_minblks) {
+               ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
+-              if (ret >= 0)
++              if (ret >= 0 && set_trimmed)
+                       EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
+       } else {
+               ret = 0;
+@@ -6018,6 +6019,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+       ext4_fsblk_t first_data_blk =
+                       le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
+       ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es);
++      bool whole_group, eof = false;
+       int ret = 0;
+       start = range->start >> sb->s_blocksize_bits;
+@@ -6036,8 +6038,10 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+               if (minlen > EXT4_CLUSTERS_PER_GROUP(sb))
+                       goto out;
+       }
+-      if (end >= max_blks)
++      if (end >= max_blks - 1) {
+               end = max_blks - 1;
++              eof = true;
++      }
+       if (end <= first_data_blk)
+               goto out;
+       if (start < first_data_blk)
+@@ -6051,6 +6055,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+       /* end now represents the last cluster to discard in this group */
+       end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
++      whole_group = true;
+       for (group = first_group; group <= last_group; group++) {
+               grp = ext4_get_group_info(sb, group);
+@@ -6069,12 +6074,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+                * change it for the last group, note that last_cluster is
+                * already computed earlier by ext4_get_group_no_and_offset()
+                */
+-              if (group == last_group)
++              if (group == last_group) {
+                       end = last_cluster;
+-
++                      whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1;
++              }
+               if (grp->bb_free >= minlen) {
+                       cnt = ext4_trim_all_free(sb, group, first_cluster,
+-                                              end, minlen);
++                                               end, minlen, whole_group);
+                       if (cnt < 0) {
+                               ret = cnt;
+                               break;
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-move-setting-of-trimmed-bit-into-ext4_try_to_tr.patch b/queue-5.10/ext4-move-setting-of-trimmed-bit-into-ext4_try_to_tr.patch
new file mode 100644 (file)
index 0000000..d470675
--- /dev/null
@@ -0,0 +1,168 @@
+From d3789f9dc4d047ed1ef52fb4590c1faad8530f0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Sep 2023 17:04:54 +0200
+Subject: ext4: move setting of trimmed bit into ext4_try_to_trim_range()
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 45e4ab320c9b5fa67b1fc3b6a9b381cfcc0c8488 ]
+
+Currently we set the group's trimmed bit in ext4_trim_all_free() based
+on return value of ext4_try_to_trim_range(). However when we will want
+to abort trimming because of suspend attempt, we want to return success
+from ext4_try_to_trim_range() but not set the trimmed bit. Instead
+implementing awkward propagation of this information, just move setting
+of trimmed bit into ext4_try_to_trim_range() when the whole group is
+trimmed.
+
+Cc: stable@kernel.org
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20230913150504.9054-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 46 +++++++++++++++++++++++++---------------------
+ 1 file changed, 25 insertions(+), 21 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index c06f304f38edf..2907bf57744a8 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -5894,14 +5894,27 @@ __acquires(bitlock)
+       return ret;
+ }
++static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb,
++                                         ext4_group_t grp)
++{
++      if (grp < ext4_get_groups_count(sb))
++              return EXT4_CLUSTERS_PER_GROUP(sb) - 1;
++      return (ext4_blocks_count(EXT4_SB(sb)->s_es) -
++              ext4_group_first_block_no(sb, grp) - 1) >>
++                                      EXT4_CLUSTER_BITS(sb);
++}
++
+ static int ext4_try_to_trim_range(struct super_block *sb,
+               struct ext4_buddy *e4b, ext4_grpblk_t start,
+               ext4_grpblk_t max, ext4_grpblk_t minblocks)
+ {
+       ext4_grpblk_t next, count, free_count;
++      bool set_trimmed = false;
+       void *bitmap;
+       bitmap = e4b->bd_bitmap;
++      if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group))
++              set_trimmed = true;
+       start = max(e4b->bd_info->bb_first_free, start);
+       count = 0;
+       free_count = 0;
+@@ -5916,16 +5929,14 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+                       int ret = ext4_trim_extent(sb, start, next - start, e4b);
+                       if (ret && ret != -EOPNOTSUPP)
+-                              break;
++                              return count;
+                       count += next - start;
+               }
+               free_count += next - start;
+               start = next + 1;
+-              if (fatal_signal_pending(current)) {
+-                      count = -ERESTARTSYS;
+-                      break;
+-              }
++              if (fatal_signal_pending(current))
++                      return -ERESTARTSYS;
+               if (need_resched()) {
+                       ext4_unlock_group(sb, e4b->bd_group);
+@@ -5937,6 +5948,9 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+                       break;
+       }
++      if (set_trimmed)
++              EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info);
++
+       return count;
+ }
+@@ -5947,7 +5961,6 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+  * @start:            first group block to examine
+  * @max:              last group block to examine
+  * @minblocks:                minimum extent block count
+- * @set_trimmed:      set the trimmed flag if at least one block is trimmed
+  *
+  * ext4_trim_all_free walks through group's buddy bitmap searching for free
+  * extents. When the free block is found, ext4_trim_extent is called to TRIM
+@@ -5962,7 +5975,7 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+ static ext4_grpblk_t
+ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+                  ext4_grpblk_t start, ext4_grpblk_t max,
+-                 ext4_grpblk_t minblocks, bool set_trimmed)
++                 ext4_grpblk_t minblocks)
+ {
+       struct ext4_buddy e4b;
+       int ret;
+@@ -5979,13 +5992,10 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+       ext4_lock_group(sb, group);
+       if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
+-          minblocks < EXT4_SB(sb)->s_last_trim_minblks) {
++          minblocks < EXT4_SB(sb)->s_last_trim_minblks)
+               ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
+-              if (ret >= 0 && set_trimmed)
+-                      EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
+-      } else {
++      else
+               ret = 0;
+-      }
+       ext4_unlock_group(sb, group);
+       ext4_mb_unload_buddy(&e4b);
+@@ -6018,7 +6028,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+       ext4_fsblk_t first_data_blk =
+                       le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
+       ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es);
+-      bool whole_group, eof = false;
+       int ret = 0;
+       start = range->start >> sb->s_blocksize_bits;
+@@ -6037,10 +6046,8 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+               if (minlen > EXT4_CLUSTERS_PER_GROUP(sb))
+                       goto out;
+       }
+-      if (end >= max_blks - 1) {
++      if (end >= max_blks - 1)
+               end = max_blks - 1;
+-              eof = true;
+-      }
+       if (end <= first_data_blk)
+               goto out;
+       if (start < first_data_blk)
+@@ -6054,7 +6061,6 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+       /* end now represents the last cluster to discard in this group */
+       end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
+-      whole_group = true;
+       for (group = first_group; group <= last_group; group++) {
+               grp = ext4_get_group_info(sb, group);
+@@ -6073,13 +6079,11 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
+                * change it for the last group, note that last_cluster is
+                * already computed earlier by ext4_get_group_no_and_offset()
+                */
+-              if (group == last_group) {
++              if (group == last_group)
+                       end = last_cluster;
+-                      whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1;
+-              }
+               if (grp->bb_free >= minlen) {
+                       cnt = ext4_trim_all_free(sb, group, first_cluster,
+-                                               end, minlen, whole_group);
++                                               end, minlen);
+                       if (cnt < 0) {
+                               ret = cnt;
+                               break;
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-remove-the-group-parameter-of-ext4_trim_extent.patch b/queue-5.10/ext4-remove-the-group-parameter-of-ext4_trim_extent.patch
new file mode 100644 (file)
index 0000000..ad49ac5
--- /dev/null
@@ -0,0 +1,63 @@
+From 2925db3a0ce15fe1e06c486a9c60138438ac4815 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 24 Jul 2021 15:41:20 +0800
+Subject: ext4: remove the 'group' parameter of ext4_trim_extent
+
+From: Wang Jianchao <wangjianchao@kuaishou.com>
+
+[ Upstream commit bd2eea8d0a6b6a9aca22f20bf74f73b71d8808af ]
+
+Get rid of the 'group' parameter of ext4_trim_extent as we can get
+it from the 'e4b'.
+
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Signed-off-by: Wang Jianchao <wangjianchao@kuaishou.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20210724074124.25731-2-jianchao.wan9@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 45e4ab320c9b ("ext4: move setting of trimmed bit into ext4_try_to_trim_range()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 2f6ed59d81f02..342225c1cf332 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -5859,19 +5859,19 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
+  * @sb:               super block for the file system
+  * @start:    starting block of the free extent in the alloc. group
+  * @count:    number of blocks to TRIM
+- * @group:    alloc. group we are working with
+  * @e4b:      ext4 buddy for the group
+  *
+  * Trim "count" blocks starting at "start" in the "group". To assure that no
+  * one will allocate those blocks, mark it as used in buddy bitmap. This must
+  * be called with under the group lock.
+  */
+-static int ext4_trim_extent(struct super_block *sb, int start, int count,
+-                           ext4_group_t group, struct ext4_buddy *e4b)
++static int ext4_trim_extent(struct super_block *sb,
++              int start, int count, struct ext4_buddy *e4b)
+ __releases(bitlock)
+ __acquires(bitlock)
+ {
+       struct ext4_free_extent ex;
++      ext4_group_t group = e4b->bd_group;
+       int ret = 0;
+       trace_ext4_trim_extent(sb, group, start, count);
+@@ -5947,8 +5947,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
+               next = mb_find_next_bit(bitmap, max + 1, start);
+               if ((next - start) >= minblocks) {
+-                      ret = ext4_trim_extent(sb, start,
+-                                             next - start, group, &e4b);
++                      ret = ext4_trim_extent(sb, start, next - start, &e4b);
+                       if (ret && ret != -EOPNOTSUPP)
+                               break;
+                       ret = 0;
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-replace-the-traditional-ternary-conditional-ope.patch b/queue-5.10/ext4-replace-the-traditional-ternary-conditional-ope.patch
new file mode 100644 (file)
index 0000000..c374183
--- /dev/null
@@ -0,0 +1,49 @@
+From 1e9986d62b40addae9c5c6c38d20eefdd7ed207f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Aug 2023 22:32:00 +0800
+Subject: ext4: replace the traditional ternary conditional operator with with
+ max()/min()
+
+From: Kemeng Shi <shikemeng@huaweicloud.com>
+
+[ Upstream commit de8bf0e5ee7482585450357c6d4eddec8efc5cb7 ]
+
+Replace the traditional ternary conditional operator with with max()/min()
+
+Signed-off-by: Kemeng Shi <shikemeng@huaweicloud.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20230801143204.2284343-7-shikemeng@huaweicloud.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 45e4ab320c9b ("ext4: move setting of trimmed bit into ext4_try_to_trim_range()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 5c650e28dcb6b..c06f304f38edf 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -5902,8 +5902,7 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+       void *bitmap;
+       bitmap = e4b->bd_bitmap;
+-      start = (e4b->bd_info->bb_first_free > start) ?
+-              e4b->bd_info->bb_first_free : start;
++      start = max(e4b->bd_info->bb_first_free, start);
+       count = 0;
+       free_count = 0;
+@@ -6125,8 +6124,7 @@ ext4_mballoc_query_range(
+       ext4_lock_group(sb, group);
+-      start = (e4b.bd_info->bb_first_free > start) ?
+-              e4b.bd_info->bb_first_free : start;
++      start = max(e4b.bd_info->bb_first_free, start);
+       if (end >= EXT4_CLUSTERS_PER_GROUP(sb))
+               end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
+-- 
+2.40.1
+
diff --git a/queue-5.10/ext4-scope-ret-locally-in-ext4_try_to_trim_range.patch b/queue-5.10/ext4-scope-ret-locally-in-ext4_try_to_trim_range.patch
new file mode 100644 (file)
index 0000000..edb4e1f
--- /dev/null
@@ -0,0 +1,55 @@
+From 08e162b3e7ff1feb4e137dc807ce60d36bb3a8e6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 20 Aug 2021 14:08:53 +0200
+Subject: ext4: scope ret locally in ext4_try_to_trim_range()
+
+From: Lukas Bulwahn <lukas.bulwahn@gmail.com>
+
+[ Upstream commit afcc4e32f606dbfb47aa7309172c89174b86e74c ]
+
+As commit 6920b3913235 ("ext4: add new helper interface
+ext4_try_to_trim_range()") moves some code into the separate function
+ext4_try_to_trim_range(), the use of the variable ret within that
+function is more limited and can be adjusted as well.
+
+Scope the use of the variable ret locally and drop dead assignments.
+
+No functional change.
+
+Signed-off-by: Lukas Bulwahn <lukas.bulwahn@gmail.com>
+Link: https://lore.kernel.org/r/20210820120853.23134-1-lukas.bulwahn@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Stable-dep-of: 45e4ab320c9b ("ext4: move setting of trimmed bit into ext4_try_to_trim_range()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 54c718d471978..e0428cec6ff60 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -5900,7 +5900,6 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+ {
+       ext4_grpblk_t next, count, free_count;
+       void *bitmap;
+-      int ret = 0;
+       bitmap = e4b->bd_bitmap;
+       start = (e4b->bd_info->bb_first_free > start) ?
+@@ -5915,10 +5914,10 @@ static int ext4_try_to_trim_range(struct super_block *sb,
+               next = mb_find_next_bit(bitmap, max + 1, start);
+               if ((next - start) >= minblocks) {
+-                      ret = ext4_trim_extent(sb, start, next - start, e4b);
++                      int ret = ext4_trim_extent(sb, start, next - start, e4b);
++
+                       if (ret && ret != -EOPNOTSUPP)
+                               break;
+-                      ret = 0;
+                       count += next - start;
+               }
+               free_count += next - start;
+-- 
+2.40.1
+
diff --git a/queue-5.10/nfs-pnfs-report-einval-errors-from-connect-to-the-se.patch b/queue-5.10/nfs-pnfs-report-einval-errors-from-connect-to-the-se.patch
new file mode 100644 (file)
index 0000000..8694697
--- /dev/null
@@ -0,0 +1,36 @@
+From 9986ccc886bd9b57c17c535b1f552faa529a94ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 12:43:58 -0400
+Subject: NFS/pNFS: Report EINVAL errors from connect() to the server
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit dd7d7ee3ba2a70d12d02defb478790cf57d5b87b ]
+
+With IPv6, connect() can occasionally return EINVAL if a route is
+unavailable. If this happens during I/O to a data server, we want to
+report it using LAYOUTERROR as an inability to connect.
+
+Fixes: dd52128afdde ("NFSv4.1/pnfs Ensure flexfiles reports all connection related errors")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/flexfilelayout/flexfilelayout.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
+index a8a02081942d2..e4f2820ba5a59 100644
+--- a/fs/nfs/flexfilelayout/flexfilelayout.c
++++ b/fs/nfs/flexfilelayout/flexfilelayout.c
+@@ -1240,6 +1240,7 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
+               case -EPFNOSUPPORT:
+               case -EPROTONOSUPPORT:
+               case -EOPNOTSUPP:
++              case -EINVAL:
+               case -ECONNREFUSED:
+               case -ECONNRESET:
+               case -EHOSTDOWN:
+-- 
+2.40.1
+
diff --git a/queue-5.10/nfs-use-the-correct-commit-info-in-nfs_join_page_gro.patch b/queue-5.10/nfs-use-the-correct-commit-info-in-nfs_join_page_gro.patch
new file mode 100644 (file)
index 0000000..3e656f3
--- /dev/null
@@ -0,0 +1,150 @@
+From b7284cdf6553048006df6e81c8dd44b6efcf2b03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 12:34:40 -0400
+Subject: NFS: Use the correct commit info in nfs_join_page_group()
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit b193a78ddb5ee7dba074d3f28dc050069ba083c0 ]
+
+Ensure that nfs_clear_request_commit() updates the correct counters when
+it removes them from the commit list.
+
+Fixes: ed5d588fe47f ("NFS: Try to join page groups before an O_DIRECT retransmission")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/direct.c          |  8 +++++---
+ fs/nfs/write.c           | 23 ++++++++++++-----------
+ include/linux/nfs_page.h |  4 +++-
+ 3 files changed, 20 insertions(+), 15 deletions(-)
+
+diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
+index 018af6ec97b40..5d86ffa72ceab 100644
+--- a/fs/nfs/direct.c
++++ b/fs/nfs/direct.c
+@@ -525,7 +525,9 @@ static void nfs_direct_add_page_head(struct list_head *list,
+       kref_get(&head->wb_kref);
+ }
+-static void nfs_direct_join_group(struct list_head *list, struct inode *inode)
++static void nfs_direct_join_group(struct list_head *list,
++                                struct nfs_commit_info *cinfo,
++                                struct inode *inode)
+ {
+       struct nfs_page *req, *subreq;
+@@ -547,7 +549,7 @@ static void nfs_direct_join_group(struct list_head *list, struct inode *inode)
+                               nfs_release_request(subreq);
+                       }
+               } while ((subreq = subreq->wb_this_page) != req);
+-              nfs_join_page_group(req, inode);
++              nfs_join_page_group(req, cinfo, inode);
+       }
+ }
+@@ -573,7 +575,7 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
+       nfs_init_cinfo_from_dreq(&cinfo, dreq);
+       nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo);
+-      nfs_direct_join_group(&reqs, dreq->inode);
++      nfs_direct_join_group(&reqs, &cinfo, dreq->inode);
+       dreq->count = 0;
+       dreq->max_count = 0;
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index dc08a0c02f095..d3cd099ffb6e1 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -58,7 +58,8 @@ static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
+ static const struct nfs_commit_completion_ops nfs_commit_completion_ops;
+ static const struct nfs_rw_ops nfs_rw_write_ops;
+ static void nfs_inode_remove_request(struct nfs_page *req);
+-static void nfs_clear_request_commit(struct nfs_page *req);
++static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
++                                   struct nfs_page *req);
+ static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
+                                     struct inode *inode);
+ static struct nfs_page *
+@@ -500,8 +501,8 @@ nfs_destroy_unlinked_subrequests(struct nfs_page *destroy_list,
+  * the (former) group.  All subrequests are removed from any write or commit
+  * lists, unlinked from the group and destroyed.
+  */
+-void
+-nfs_join_page_group(struct nfs_page *head, struct inode *inode)
++void nfs_join_page_group(struct nfs_page *head, struct nfs_commit_info *cinfo,
++                       struct inode *inode)
+ {
+       struct nfs_page *subreq;
+       struct nfs_page *destroy_list = NULL;
+@@ -531,7 +532,7 @@ nfs_join_page_group(struct nfs_page *head, struct inode *inode)
+        * Commit list removal accounting is done after locks are dropped */
+       subreq = head;
+       do {
+-              nfs_clear_request_commit(subreq);
++              nfs_clear_request_commit(cinfo, subreq);
+               subreq = subreq->wb_this_page;
+       } while (subreq != head);
+@@ -565,8 +566,10 @@ nfs_lock_and_join_requests(struct page *page)
+ {
+       struct inode *inode = page_file_mapping(page)->host;
+       struct nfs_page *head;
++      struct nfs_commit_info cinfo;
+       int ret;
++      nfs_init_cinfo_from_inode(&cinfo, inode);
+       /*
+        * A reference is taken only on the head request which acts as a
+        * reference to the whole page group - the group will not be destroyed
+@@ -583,7 +586,7 @@ nfs_lock_and_join_requests(struct page *page)
+               return ERR_PTR(ret);
+       }
+-      nfs_join_page_group(head, inode);
++      nfs_join_page_group(head, &cinfo, inode);
+       return head;
+ }
+@@ -944,18 +947,16 @@ nfs_clear_page_commit(struct page *page)
+ }
+ /* Called holding the request lock on @req */
+-static void
+-nfs_clear_request_commit(struct nfs_page *req)
++static void nfs_clear_request_commit(struct nfs_commit_info *cinfo,
++                                   struct nfs_page *req)
+ {
+       if (test_bit(PG_CLEAN, &req->wb_flags)) {
+               struct nfs_open_context *ctx = nfs_req_openctx(req);
+               struct inode *inode = d_inode(ctx->dentry);
+-              struct nfs_commit_info cinfo;
+-              nfs_init_cinfo_from_inode(&cinfo, inode);
+               mutex_lock(&NFS_I(inode)->commit_mutex);
+-              if (!pnfs_clear_request_commit(req, &cinfo)) {
+-                      nfs_request_remove_commit_list(req, &cinfo);
++              if (!pnfs_clear_request_commit(req, cinfo)) {
++                      nfs_request_remove_commit_list(req, cinfo);
+               }
+               mutex_unlock(&NFS_I(inode)->commit_mutex);
+               nfs_clear_page_commit(req->wb_page);
+diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
+index f0373a6cb5fb6..40aa09a21f75d 100644
+--- a/include/linux/nfs_page.h
++++ b/include/linux/nfs_page.h
+@@ -145,7 +145,9 @@ extern     void nfs_unlock_request(struct nfs_page *req);
+ extern        void nfs_unlock_and_release_request(struct nfs_page *);
+ extern        struct nfs_page *nfs_page_group_lock_head(struct nfs_page *req);
+ extern        int nfs_page_group_lock_subrequests(struct nfs_page *head);
+-extern        void nfs_join_page_group(struct nfs_page *head, struct inode *inode);
++extern void nfs_join_page_group(struct nfs_page *head,
++                              struct nfs_commit_info *cinfo,
++                              struct inode *inode);
+ extern int nfs_page_group_lock(struct nfs_page *);
+ extern void nfs_page_group_unlock(struct nfs_page *);
+ extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
+-- 
+2.40.1
+
diff --git a/queue-5.10/series b/queue-5.10/series
new file mode 100644 (file)
index 0000000..e5f1b48
--- /dev/null
@@ -0,0 +1,15 @@
+nfs-use-the-correct-commit-info-in-nfs_join_page_gro.patch
+nfs-pnfs-report-einval-errors-from-connect-to-the-se.patch
+sunrpc-mark-the-cred-for-revalidation-if-the-server-.patch
+tracing-increase-trace-array-ref-count-on-enable-and.patch
+ata-ahci-drop-pointless-vprintk-calls-and-convert-th.patch
+ata-libahci-clear-pending-interrupt-status.patch
+ext4-remove-the-group-parameter-of-ext4_trim_extent.patch
+ext4-add-new-helper-interface-ext4_try_to_trim_range.patch
+ext4-scope-ret-locally-in-ext4_try_to_trim_range.patch
+ext4-change-s_last_trim_minblks-type-to-unsigned-lon.patch
+ext4-mark-group-as-trimmed-only-if-it-was-fully-scan.patch
+ext4-replace-the-traditional-ternary-conditional-ope.patch
+ext4-move-setting-of-trimmed-bit-into-ext4_try_to_tr.patch
+ext4-do-not-let-fstrim-block-system-suspend.patch
+tracing-have-event-inject-files-inc-the-trace-array-.patch
diff --git a/queue-5.10/sunrpc-mark-the-cred-for-revalidation-if-the-server-.patch b/queue-5.10/sunrpc-mark-the-cred-for-revalidation-if-the-server-.patch
new file mode 100644 (file)
index 0000000..323deaa
--- /dev/null
@@ -0,0 +1,35 @@
+From 62cd62584c9970f37e8ce1da8c1d6be44acbf3dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Sep 2023 12:50:09 -0400
+Subject: SUNRPC: Mark the cred for revalidation if the server rejects it
+
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+
+[ Upstream commit 611fa42dfa9d2f3918ac5f4dd5705dfad81b323d ]
+
+If the server rejects the credential as being stale, or bad, then we
+should mark it for revalidation before retransmitting.
+
+Fixes: 7f5667a5f8c4 ("SUNRPC: Clean up rpc_verify_header()")
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sunrpc/clnt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index e1ce0f261f0be..e9a3fca4aedc0 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -2630,6 +2630,7 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr)
+       case rpc_autherr_rejectedverf:
+       case rpcsec_gsserr_credproblem:
+       case rpcsec_gsserr_ctxproblem:
++              rpcauth_invalcred(task);
+               if (!task->tk_cred_retry)
+                       break;
+               task->tk_cred_retry--;
+-- 
+2.40.1
+
diff --git a/queue-5.10/tracing-have-event-inject-files-inc-the-trace-array-.patch b/queue-5.10/tracing-have-event-inject-files-inc-the-trace-array-.patch
new file mode 100644 (file)
index 0000000..29df5da
--- /dev/null
@@ -0,0 +1,49 @@
+From 7465b1c3fcef0cadf01cc5fe19969a6e8a664013 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 22:47:16 -0400
+Subject: tracing: Have event inject files inc the trace array ref count
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit e5c624f027ac74f97e97c8f36c69228ac9f1102d ]
+
+The event inject files add events for a specific trace array. For an
+instance, if the file is opened and the instance is deleted, reading or
+writing to the file will cause a use after free.
+
+Up the ref count of the trace_array when a event inject file is opened.
+
+Link: https://lkml.kernel.org/r/20230907024804.292337868@goodmis.org
+Link: https://lore.kernel.org/all/1cb3aee2-19af-c472-e265-05176fe9bd84@huawei.com/
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Zheng Yejian <zhengyejian1@huawei.com>
+Fixes: 6c3edaf9fd6a ("tracing: Introduce trace event injection")
+Tested-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace_events_inject.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/trace/trace_events_inject.c b/kernel/trace/trace_events_inject.c
+index 22bcf7c51d1ee..149c7dc6a4473 100644
+--- a/kernel/trace/trace_events_inject.c
++++ b/kernel/trace/trace_events_inject.c
+@@ -323,7 +323,8 @@ event_inject_read(struct file *file, char __user *buf, size_t size,
+ }
+ const struct file_operations event_inject_fops = {
+-      .open = tracing_open_generic,
++      .open = tracing_open_file_tr,
+       .read = event_inject_read,
+       .write = event_inject_write,
++      .release = tracing_release_file_tr,
+ };
+-- 
+2.40.1
+
diff --git a/queue-5.10/tracing-increase-trace-array-ref-count-on-enable-and.patch b/queue-5.10/tracing-increase-trace-array-ref-count-on-enable-and.patch
new file mode 100644 (file)
index 0000000..25fedf0
--- /dev/null
@@ -0,0 +1,115 @@
+From ec4a6f70ce42d49a866c37aa9e4fbb49d6d9f1df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Sep 2023 22:47:12 -0400
+Subject: tracing: Increase trace array ref count on enable and filter files
+
+From: Steven Rostedt (Google) <rostedt@goodmis.org>
+
+[ Upstream commit f5ca233e2e66dc1c249bf07eefa37e34a6c9346a ]
+
+When the trace event enable and filter files are opened, increment the
+trace array ref counter, otherwise they can be accessed when the trace
+array is being deleted. The ref counter keeps the trace array from being
+deleted while those files are opened.
+
+Link: https://lkml.kernel.org/r/20230907024803.456187066@goodmis.org
+Link: https://lore.kernel.org/all/1cb3aee2-19af-c472-e265-05176fe9bd84@huawei.com/
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Fixes: 8530dec63e7b4 ("tracing: Add tracing_check_open_get_tr()")
+Tested-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org>
+Reported-by: Zheng Yejian <zhengyejian1@huawei.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/trace.c        | 27 +++++++++++++++++++++++++++
+ kernel/trace/trace.h        |  2 ++
+ kernel/trace/trace_events.c |  6 ++++--
+ 3 files changed, 33 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
+index 7a64c0cd8819d..196eec0423ff2 100644
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -4559,6 +4559,33 @@ int tracing_open_generic_tr(struct inode *inode, struct file *filp)
+       return 0;
+ }
++/*
++ * The private pointer of the inode is the trace_event_file.
++ * Update the tr ref count associated to it.
++ */
++int tracing_open_file_tr(struct inode *inode, struct file *filp)
++{
++      struct trace_event_file *file = inode->i_private;
++      int ret;
++
++      ret = tracing_check_open_get_tr(file->tr);
++      if (ret)
++              return ret;
++
++      filp->private_data = inode->i_private;
++
++      return 0;
++}
++
++int tracing_release_file_tr(struct inode *inode, struct file *filp)
++{
++      struct trace_event_file *file = inode->i_private;
++
++      trace_array_put(file->tr);
++
++      return 0;
++}
++
+ static int tracing_release(struct inode *inode, struct file *file)
+ {
+       struct trace_array *tr = inode->i_private;
+diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
+index dfde855dafda7..7fa00b83dfa4b 100644
+--- a/kernel/trace/trace.h
++++ b/kernel/trace/trace.h
+@@ -730,6 +730,8 @@ void tracing_reset_all_online_cpus(void);
+ void tracing_reset_all_online_cpus_unlocked(void);
+ int tracing_open_generic(struct inode *inode, struct file *filp);
+ int tracing_open_generic_tr(struct inode *inode, struct file *filp);
++int tracing_open_file_tr(struct inode *inode, struct file *filp);
++int tracing_release_file_tr(struct inode *inode, struct file *filp);
+ bool tracing_is_disabled(void);
+ bool tracer_tracing_is_on(struct trace_array *tr);
+ void tracer_tracing_on(struct trace_array *tr);
+diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
+index a46d34d840f69..321cfda1b3338 100644
+--- a/kernel/trace/trace_events.c
++++ b/kernel/trace/trace_events.c
+@@ -1855,9 +1855,10 @@ static const struct file_operations ftrace_set_event_notrace_pid_fops = {
+ };
+ static const struct file_operations ftrace_enable_fops = {
+-      .open = tracing_open_generic,
++      .open = tracing_open_file_tr,
+       .read = event_enable_read,
+       .write = event_enable_write,
++      .release = tracing_release_file_tr,
+       .llseek = default_llseek,
+ };
+@@ -1874,9 +1875,10 @@ static const struct file_operations ftrace_event_id_fops = {
+ };
+ static const struct file_operations ftrace_event_filter_fops = {
+-      .open = tracing_open_generic,
++      .open = tracing_open_file_tr,
+       .read = event_filter_read,
+       .write = event_filter_write,
++      .release = tracing_release_file_tr,
+       .llseek = default_llseek,
+ };
+-- 
+2.40.1
+