]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Jul 2022 15:24:53 +0000 (17:24 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Jul 2022 15:24:53 +0000 (17:24 +0200)
added patches:
xfs-fix-maxlevels-comparisons-in-the-btree-staging-code.patch
xfs-fix-perag-reference-leak-on-iteration-race-with-growfs.patch
xfs-fold-perag-loop-iteration-logic-into-helper-function.patch
xfs-prevent-a-warn_once-in-xfs_ioc_attr_list.patch
xfs-rename-the-next_agno-perag-iteration-variable.patch
xfs-terminate-perag-iteration-reliably-on-agcount.patch

queue-5.15/series
queue-5.15/xfs-fix-maxlevels-comparisons-in-the-btree-staging-code.patch [new file with mode: 0644]
queue-5.15/xfs-fix-perag-reference-leak-on-iteration-race-with-growfs.patch [new file with mode: 0644]
queue-5.15/xfs-fold-perag-loop-iteration-logic-into-helper-function.patch [new file with mode: 0644]
queue-5.15/xfs-prevent-a-warn_once-in-xfs_ioc_attr_list.patch [new file with mode: 0644]
queue-5.15/xfs-rename-the-next_agno-perag-iteration-variable.patch [new file with mode: 0644]
queue-5.15/xfs-terminate-perag-iteration-reliably-on-agcount.patch [new file with mode: 0644]

index 1b2923ec67775968853d3bb8da5b448f611e43b8..3cbe2485bf4a5d8b839b3c5f4167f81e93d47f61 100644 (file)
@@ -18,3 +18,9 @@ revert-mt76-mt7921e-fix-possible-probe-failure-after-reboot.patch
 mt76-mt7921-use-physical-addr-to-unify-register-access.patch
 mt76-mt7921e-fix-possible-probe-failure-after-reboot.patch
 mt76-mt7921-fix-the-error-handling-path-of-mt7921_pci_probe.patch
+xfs-fix-maxlevels-comparisons-in-the-btree-staging-code.patch
+xfs-fold-perag-loop-iteration-logic-into-helper-function.patch
+xfs-rename-the-next_agno-perag-iteration-variable.patch
+xfs-terminate-perag-iteration-reliably-on-agcount.patch
+xfs-fix-perag-reference-leak-on-iteration-race-with-growfs.patch
+xfs-prevent-a-warn_once-in-xfs_ioc_attr_list.patch
diff --git a/queue-5.15/xfs-fix-maxlevels-comparisons-in-the-btree-staging-code.patch b/queue-5.15/xfs-fix-maxlevels-comparisons-in-the-btree-staging-code.patch
new file mode 100644 (file)
index 0000000..1070107
--- /dev/null
@@ -0,0 +1,49 @@
+From foo@baz Sat Jul 23 05:23:15 PM CEST 2022
+From: Leah Rumancik <leah.rumancik@gmail.com>
+Date: Thu, 21 Jul 2022 14:36:05 -0700
+Subject: xfs: fix maxlevels comparisons in the btree staging code
+To: stable@vger.kernel.org, linux-xfs@vger.kernel.org
+Cc: amir73il@gmail.com, "Darrick J. Wong" <djwong@kernel.org>, Chandan Babu R <chandan.babu@oracle.com>, Christoph Hellwig <hch@lst.de>, Leah Rumancik <leah.rumancik@gmail.com>
+Message-ID: <20220721213610.2794134-2-leah.rumancik@gmail.com>
+
+From: "Darrick J. Wong" <djwong@kernel.org>
+
+[ Upstream commit 78e8ec83a404d63dcc86b251f42e4ee8aff27465 ]
+
+The btree geometry computation function has an off-by-one error in that
+it does not allow maximally tall btrees (nlevels == XFS_BTREE_MAXLEVELS).
+This can result in repairs failing unnecessarily on very fragmented
+filesystems.  Subsequent patches to remove MAXLEVELS usage in favor of
+the per-btree type computations will make this a much more likely
+occurrence.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_btree_staging.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_btree_staging.c
++++ b/fs/xfs/libxfs/xfs_btree_staging.c
+@@ -662,7 +662,7 @@ xfs_btree_bload_compute_geometry(
+       xfs_btree_bload_ensure_slack(cur, &bbl->node_slack, 1);
+       bbl->nr_records = nr_this_level = nr_records;
+-      for (cur->bc_nlevels = 1; cur->bc_nlevels < XFS_BTREE_MAXLEVELS;) {
++      for (cur->bc_nlevels = 1; cur->bc_nlevels <= XFS_BTREE_MAXLEVELS;) {
+               uint64_t        level_blocks;
+               uint64_t        dontcare64;
+               unsigned int    level = cur->bc_nlevels - 1;
+@@ -724,7 +724,7 @@ xfs_btree_bload_compute_geometry(
+               nr_this_level = level_blocks;
+       }
+-      if (cur->bc_nlevels == XFS_BTREE_MAXLEVELS)
++      if (cur->bc_nlevels > XFS_BTREE_MAXLEVELS)
+               return -EOVERFLOW;
+       bbl->btree_height = cur->bc_nlevels;
diff --git a/queue-5.15/xfs-fix-perag-reference-leak-on-iteration-race-with-growfs.patch b/queue-5.15/xfs-fix-perag-reference-leak-on-iteration-race-with-growfs.patch
new file mode 100644 (file)
index 0000000..4b51740
--- /dev/null
@@ -0,0 +1,90 @@
+From foo@baz Sat Jul 23 05:23:15 PM CEST 2022
+From: Leah Rumancik <leah.rumancik@gmail.com>
+Date: Thu, 21 Jul 2022 14:36:09 -0700
+Subject: xfs: fix perag reference leak on iteration race with growfs
+To: stable@vger.kernel.org, linux-xfs@vger.kernel.org
+Cc: amir73il@gmail.com, Brian Foster <bfoster@redhat.com>, Dave Chinner <dchinner@redhat.com>, "Darrick J . Wong" <djwong@kernel.org>, Leah Rumancik <leah.rumancik@gmail.com>
+Message-ID: <20220721213610.2794134-6-leah.rumancik@gmail.com>
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ Upstream commit 892a666fafa19ab04b5e948f6c92f98f1dafb489 ]
+
+The for_each_perag*() set of macros are hacky in that some (i.e.
+those based on sb_agcount) rely on the assumption that perag
+iteration terminates naturally with a NULL perag at the specified
+end_agno. Others allow for the final AG to have a valid perag and
+require the calling function to clean up any potential leftover
+xfs_perag reference on termination of the loop.
+
+Aside from providing a subtly inconsistent interface, the former
+variant is racy with growfs because growfs can create discoverable
+post-eofs perags before the final superblock update that completes
+the grow operation and increases sb_agcount. This leads to the
+following assert failure (reproduced by xfs/104) in the perag free
+path during unmount:
+
+ XFS: Assertion failed: atomic_read(&pag->pag_ref) == 0, file: fs/xfs/libxfs/xfs_ag.c, line: 195
+
+This occurs because one of the many for_each_perag() loops in the
+code that is expected to terminate with a NULL pag (and thus has no
+post-loop xfs_perag_put() check) raced with a growfs and found a
+non-NULL post-EOFS perag, but terminated naturally based on the
+end_agno check without releasing the post-EOFS perag.
+
+Rework the iteration logic to lift the agno check from the main for
+loop conditional to the iteration helper function. The for loop now
+purely terminates on a NULL pag and xfs_perag_next() avoids taking a
+reference to any perag beyond end_agno in the first place.
+
+Fixes: f250eedcf762 ("xfs: make for_each_perag... a first class citizen")
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_ag.h |   16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_ag.h
++++ b/fs/xfs/libxfs/xfs_ag.h
+@@ -116,30 +116,26 @@ void xfs_perag_put(struct xfs_perag *pag
+ /*
+  * Perag iteration APIs
+- *
+- * XXX: for_each_perag_range() usage really needs an iterator to clean up when
+- * we terminate at end_agno because we may have taken a reference to the perag
+- * beyond end_agno. Right now callers have to be careful to catch and clean that
+- * up themselves. This is not necessary for the callers of for_each_perag() and
+- * for_each_perag_from() because they terminate at sb_agcount where there are
+- * no perag structures in tree beyond end_agno.
+  */
+ static inline struct xfs_perag *
+ xfs_perag_next(
+       struct xfs_perag        *pag,
+-      xfs_agnumber_t          *agno)
++      xfs_agnumber_t          *agno,
++      xfs_agnumber_t          end_agno)
+ {
+       struct xfs_mount        *mp = pag->pag_mount;
+       *agno = pag->pag_agno + 1;
+       xfs_perag_put(pag);
++      if (*agno > end_agno)
++              return NULL;
+       return xfs_perag_get(mp, *agno);
+ }
+ #define for_each_perag_range(mp, agno, end_agno, pag) \
+       for ((pag) = xfs_perag_get((mp), (agno)); \
+-              (pag) != NULL && (agno) <= (end_agno); \
+-              (pag) = xfs_perag_next((pag), &(agno)))
++              (pag) != NULL; \
++              (pag) = xfs_perag_next((pag), &(agno), (end_agno)))
+ #define for_each_perag_from(mp, agno, pag) \
+       for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag))
diff --git a/queue-5.15/xfs-fold-perag-loop-iteration-logic-into-helper-function.patch b/queue-5.15/xfs-fold-perag-loop-iteration-logic-into-helper-function.patch
new file mode 100644 (file)
index 0000000..2cc5369
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Sat Jul 23 05:23:15 PM CEST 2022
+From: Leah Rumancik <leah.rumancik@gmail.com>
+Date: Thu, 21 Jul 2022 14:36:06 -0700
+Subject: xfs: fold perag loop iteration logic into helper function
+To: stable@vger.kernel.org, linux-xfs@vger.kernel.org
+Cc: amir73il@gmail.com, Brian Foster <bfoster@redhat.com>, Dave Chinner <dchinner@redhat.com>, "Darrick J . Wong" <djwong@kernel.org>, Leah Rumancik <leah.rumancik@gmail.com>
+Message-ID: <20220721213610.2794134-3-leah.rumancik@gmail.com>
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ Upstream commit bf2307b195135ed9c95eebb38920d8bd41843092 ]
+
+Fold the loop iteration logic into a helper in preparation for
+further fixups. No functional change in this patch.
+
+[backport: dependency for f1788b5e5ee25bedf00bb4d25f82b93820d61189]
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_ag.h |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_ag.h
++++ b/fs/xfs/libxfs/xfs_ag.h
+@@ -124,12 +124,22 @@ void xfs_perag_put(struct xfs_perag *pag
+  * for_each_perag_from() because they terminate at sb_agcount where there are
+  * no perag structures in tree beyond end_agno.
+  */
++static inline struct xfs_perag *
++xfs_perag_next(
++      struct xfs_perag        *pag,
++      xfs_agnumber_t          *next_agno)
++{
++      struct xfs_mount        *mp = pag->pag_mount;
++
++      *next_agno = pag->pag_agno + 1;
++      xfs_perag_put(pag);
++      return xfs_perag_get(mp, *next_agno);
++}
++
+ #define for_each_perag_range(mp, next_agno, end_agno, pag) \
+       for ((pag) = xfs_perag_get((mp), (next_agno)); \
+               (pag) != NULL && (next_agno) <= (end_agno); \
+-              (next_agno) = (pag)->pag_agno + 1, \
+-              xfs_perag_put(pag), \
+-              (pag) = xfs_perag_get((mp), (next_agno)))
++              (pag) = xfs_perag_next((pag), &(next_agno)))
+ #define for_each_perag_from(mp, next_agno, pag) \
+       for_each_perag_range((mp), (next_agno), (mp)->m_sb.sb_agcount, (pag))
diff --git a/queue-5.15/xfs-prevent-a-warn_once-in-xfs_ioc_attr_list.patch b/queue-5.15/xfs-prevent-a-warn_once-in-xfs_ioc_attr_list.patch
new file mode 100644 (file)
index 0000000..36c6693
--- /dev/null
@@ -0,0 +1,59 @@
+From foo@baz Sat Jul 23 05:23:15 PM CEST 2022
+From: Leah Rumancik <leah.rumancik@gmail.com>
+Date: Thu, 21 Jul 2022 14:36:10 -0700
+Subject: xfs: prevent a WARN_ONCE() in xfs_ioc_attr_list()
+To: stable@vger.kernel.org, linux-xfs@vger.kernel.org
+Cc: amir73il@gmail.com, Dan Carpenter <dan.carpenter@oracle.com>, "Darrick J . Wong" <djwong@kernel.org>, Leah Rumancik <leah.rumancik@gmail.com>
+Message-ID: <20220721213610.2794134-7-leah.rumancik@gmail.com>
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit 6ed6356b07714e0198be3bc3ecccc8b40a212de4 ]
+
+The "bufsize" comes from the root user.  If "bufsize" is negative then,
+because of type promotion, neither of the validation checks at the start
+of the function are able to catch it:
+
+       if (bufsize < sizeof(struct xfs_attrlist) ||
+           bufsize > XFS_XATTR_LIST_MAX)
+               return -EINVAL;
+
+This means "bufsize" will trigger (WARN_ON_ONCE(size > INT_MAX)) in
+kvmalloc_node().  Fix this by changing the type from int to size_t.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_ioctl.c |    2 +-
+ fs/xfs/xfs_ioctl.h |    5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/fs/xfs/xfs_ioctl.c
++++ b/fs/xfs/xfs_ioctl.c
+@@ -372,7 +372,7 @@ int
+ xfs_ioc_attr_list(
+       struct xfs_inode                *dp,
+       void __user                     *ubuf,
+-      int                             bufsize,
++      size_t                          bufsize,
+       int                             flags,
+       struct xfs_attrlist_cursor __user *ucursor)
+ {
+--- a/fs/xfs/xfs_ioctl.h
++++ b/fs/xfs/xfs_ioctl.h
+@@ -38,8 +38,9 @@ xfs_readlink_by_handle(
+ int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
+               uint32_t opcode, void __user *uname, void __user *value,
+               uint32_t *len, uint32_t flags);
+-int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf, int bufsize,
+-      int flags, struct xfs_attrlist_cursor __user *ucursor);
++int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf,
++                    size_t bufsize, int flags,
++                    struct xfs_attrlist_cursor __user *ucursor);
+ extern struct dentry *
+ xfs_handle_to_dentry(
diff --git a/queue-5.15/xfs-rename-the-next_agno-perag-iteration-variable.patch b/queue-5.15/xfs-rename-the-next_agno-perag-iteration-variable.patch
new file mode 100644 (file)
index 0000000..9bc7b60
--- /dev/null
@@ -0,0 +1,62 @@
+From foo@baz Sat Jul 23 05:23:15 PM CEST 2022
+From: Leah Rumancik <leah.rumancik@gmail.com>
+Date: Thu, 21 Jul 2022 14:36:07 -0700
+Subject: xfs: rename the next_agno perag iteration variable
+To: stable@vger.kernel.org, linux-xfs@vger.kernel.org
+Cc: amir73il@gmail.com, Brian Foster <bfoster@redhat.com>, Dave Chinner <dchinner@redhat.com>, "Darrick J . Wong" <djwong@kernel.org>, Leah Rumancik <leah.rumancik@gmail.com>
+Message-ID: <20220721213610.2794134-4-leah.rumancik@gmail.com>
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ Upstream commit f1788b5e5ee25bedf00bb4d25f82b93820d61189 ]
+
+Rename the next_agno variable to be consistent across the several
+iteration macros and shorten line length.
+
+[backport: dependency for 8ed004eb9d07a5d6114db3e97a166707c186262d]
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_ag.h |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_ag.h
++++ b/fs/xfs/libxfs/xfs_ag.h
+@@ -127,22 +127,22 @@ void xfs_perag_put(struct xfs_perag *pag
+ static inline struct xfs_perag *
+ xfs_perag_next(
+       struct xfs_perag        *pag,
+-      xfs_agnumber_t          *next_agno)
++      xfs_agnumber_t          *agno)
+ {
+       struct xfs_mount        *mp = pag->pag_mount;
+-      *next_agno = pag->pag_agno + 1;
++      *agno = pag->pag_agno + 1;
+       xfs_perag_put(pag);
+-      return xfs_perag_get(mp, *next_agno);
++      return xfs_perag_get(mp, *agno);
+ }
+-#define for_each_perag_range(mp, next_agno, end_agno, pag) \
+-      for ((pag) = xfs_perag_get((mp), (next_agno)); \
+-              (pag) != NULL && (next_agno) <= (end_agno); \
+-              (pag) = xfs_perag_next((pag), &(next_agno)))
++#define for_each_perag_range(mp, agno, end_agno, pag) \
++      for ((pag) = xfs_perag_get((mp), (agno)); \
++              (pag) != NULL && (agno) <= (end_agno); \
++              (pag) = xfs_perag_next((pag), &(agno)))
+-#define for_each_perag_from(mp, next_agno, pag) \
+-      for_each_perag_range((mp), (next_agno), (mp)->m_sb.sb_agcount, (pag))
++#define for_each_perag_from(mp, agno, pag) \
++      for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount, (pag))
+ #define for_each_perag(mp, agno, pag) \
diff --git a/queue-5.15/xfs-terminate-perag-iteration-reliably-on-agcount.patch b/queue-5.15/xfs-terminate-perag-iteration-reliably-on-agcount.patch
new file mode 100644 (file)
index 0000000..86d3426
--- /dev/null
@@ -0,0 +1,49 @@
+From foo@baz Sat Jul 23 05:23:15 PM CEST 2022
+From: Leah Rumancik <leah.rumancik@gmail.com>
+Date: Thu, 21 Jul 2022 14:36:08 -0700
+Subject: xfs: terminate perag iteration reliably on agcount
+To: stable@vger.kernel.org, linux-xfs@vger.kernel.org
+Cc: amir73il@gmail.com, Brian Foster <bfoster@redhat.com>, Dave Chinner <dchinner@redhat.com>, "Darrick J . Wong" <djwong@kernel.org>, Leah Rumancik <leah.rumancik@gmail.com>
+Message-ID: <20220721213610.2794134-5-leah.rumancik@gmail.com>
+
+From: Brian Foster <bfoster@redhat.com>
+
+[ Upstream commit 8ed004eb9d07a5d6114db3e97a166707c186262d ]
+
+The for_each_perag_from() iteration macro relies on sb_agcount to
+process every perag currently within EOFS from a given starting
+point. It's perfectly valid to have perag structures beyond
+sb_agcount, however, such as if a growfs is in progress. If a perag
+loop happens to race with growfs in this manner, it will actually
+attempt to process the post-EOFS perag where ->pag_agno ==
+sb_agcount. This is reproduced by xfs/104 and manifests as the
+following assert failure in superblock write verifier context:
+
+ XFS: Assertion failed: agno < mp->m_sb.sb_agcount, file: fs/xfs/libxfs/xfs_types.c, line: 22
+
+Update the corresponding macro to only process perags that are
+within the current sb_agcount.
+
+Fixes: 58d43a7e3263 ("xfs: pass perags around in fsmap data dev functions")
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_ag.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/xfs/libxfs/xfs_ag.h
++++ b/fs/xfs/libxfs/xfs_ag.h
+@@ -142,7 +142,7 @@ xfs_perag_next(
+               (pag) = xfs_perag_next((pag), &(agno)))
+ #define for_each_perag_from(mp, agno, pag) \
+-      for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount, (pag))
++      for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag))
+ #define for_each_perag(mp, agno, pag) \