]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Mon, 21 Apr 2025 11:19:45 +0000 (07:19 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 21 Apr 2025 11:19:45 +0000 (07:19 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.1/nfs-add-missing-selections-of-config_crc32.patch [new file with mode: 0644]
queue-6.1/nfs-move-nfs_fhandle_hash-to-common-include-file.patch [new file with mode: 0644]
queue-6.1/nfsd-decrease-sc_count-directly-if-fail-to-queue-dl_.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/nfs-add-missing-selections-of-config_crc32.patch b/queue-6.1/nfs-add-missing-selections-of-config_crc32.patch
new file mode 100644 (file)
index 0000000..e964866
--- /dev/null
@@ -0,0 +1,179 @@
+From 6cbe99b0c33fa23d66d8f07de6aea128fde6a15f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 15:02:21 -0700
+Subject: nfs: add missing selections of CONFIG_CRC32
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit cd35b6cb46649750b7dbd0df0e2d767415d8917b ]
+
+nfs.ko, nfsd.ko, and lockd.ko all use crc32_le(), which is available
+only when CONFIG_CRC32 is enabled.  But the only NFS kconfig option that
+selected CONFIG_CRC32 was CONFIG_NFS_DEBUG, which is client-specific and
+did not actually guard the use of crc32_le() even on the client.
+
+The code worked around this bug by only actually calling crc32_le() when
+CONFIG_CRC32 is built-in, instead hard-coding '0' in other cases.  This
+avoided randconfig build errors, and in real kernels the fallback code
+was unlikely to be reached since CONFIG_CRC32 is 'default y'.  But, this
+really needs to just be done properly, especially now that I'm planning
+to update CONFIG_CRC32 to not be 'default y'.
+
+Therefore, make CONFIG_NFS_FS, CONFIG_NFSD, and CONFIG_LOCKD select
+CONFIG_CRC32.  Then remove the fallback code that becomes unnecessary,
+as well as the selection of CONFIG_CRC32 from CONFIG_NFS_DEBUG.
+
+Fixes: 1264a2f053a3 ("NFS: refactor code for calculating the crc32 hash of a filehandle")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Acked-by: Anna Schumaker <anna.schumaker@oracle.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/Kconfig           | 1 +
+ fs/nfs/Kconfig       | 2 +-
+ fs/nfs/internal.h    | 7 -------
+ fs/nfs/nfs4session.h | 4 ----
+ fs/nfsd/Kconfig      | 1 +
+ fs/nfsd/nfsfh.h      | 7 -------
+ include/linux/nfs.h  | 7 -------
+ 7 files changed, 3 insertions(+), 26 deletions(-)
+
+diff --git a/fs/Kconfig b/fs/Kconfig
+index 703a1cea0fc09..7104e3eb38eb4 100644
+--- a/fs/Kconfig
++++ b/fs/Kconfig
+@@ -347,6 +347,7 @@ config GRACE_PERIOD
+ config LOCKD
+       tristate
+       depends on FILE_LOCKING
++      select CRC32
+       select GRACE_PERIOD
+ config LOCKD_V4
+diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
+index 14a72224b6571..899e25e9b4eb5 100644
+--- a/fs/nfs/Kconfig
++++ b/fs/nfs/Kconfig
+@@ -2,6 +2,7 @@
+ config NFS_FS
+       tristate "NFS client support"
+       depends on INET && FILE_LOCKING && MULTIUSER
++      select CRC32
+       select LOCKD
+       select SUNRPC
+       select NFS_ACL_SUPPORT if NFS_V3_ACL
+@@ -194,7 +195,6 @@ config NFS_USE_KERNEL_DNS
+ config NFS_DEBUG
+       bool
+       depends on NFS_FS && SUNRPC_DEBUG
+-      select CRC32
+       default y
+ config NFS_DISABLE_UDP_SUPPORT
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index d511d66bd8a3a..ece517ebcca0b 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -826,18 +826,11 @@ u64 nfs_timespec_to_change_attr(const struct timespec64 *ts)
+       return ((u64)ts->tv_sec << 30) + ts->tv_nsec;
+ }
+-#ifdef CONFIG_CRC32
+ static inline u32 nfs_stateid_hash(const nfs4_stateid *stateid)
+ {
+       return ~crc32_le(0xFFFFFFFF, &stateid->other[0],
+                               NFS4_STATEID_OTHER_SIZE);
+ }
+-#else
+-static inline u32 nfs_stateid_hash(nfs4_stateid *stateid)
+-{
+-      return 0;
+-}
+-#endif
+ static inline bool nfs_error_is_fatal(int err)
+ {
+diff --git a/fs/nfs/nfs4session.h b/fs/nfs/nfs4session.h
+index 351616c61df54..f9c291e2165cd 100644
+--- a/fs/nfs/nfs4session.h
++++ b/fs/nfs/nfs4session.h
+@@ -148,16 +148,12 @@ static inline void nfs4_copy_sessionid(struct nfs4_sessionid *dst,
+       memcpy(dst->data, src->data, NFS4_MAX_SESSIONID_LEN);
+ }
+-#ifdef CONFIG_CRC32
+ /*
+  * nfs_session_id_hash - calculate the crc32 hash for the session id
+  * @session - pointer to session
+  */
+ #define nfs_session_id_hash(sess_id) \
+       (~crc32_le(0xFFFFFFFF, &(sess_id)->data[0], sizeof((sess_id)->data)))
+-#else
+-#define nfs_session_id_hash(session) (0)
+-#endif
+ #else /* defined(CONFIG_NFS_V4_1) */
+ static inline int nfs4_init_session(struct nfs_client *clp)
+diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
+index 7c441f2bd4440..4f704f868d9c9 100644
+--- a/fs/nfsd/Kconfig
++++ b/fs/nfsd/Kconfig
+@@ -4,6 +4,7 @@ config NFSD
+       depends on INET
+       depends on FILE_LOCKING
+       depends on FSNOTIFY
++      select CRC32
+       select LOCKD
+       select SUNRPC
+       select EXPORTFS
+diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h
+index 513e028b0bbee..40aee06ebd952 100644
+--- a/fs/nfsd/nfsfh.h
++++ b/fs/nfsd/nfsfh.h
+@@ -263,7 +263,6 @@ static inline bool fh_fsid_match(const struct knfsd_fh *fh1,
+       return true;
+ }
+-#ifdef CONFIG_CRC32
+ /**
+  * knfsd_fh_hash - calculate the crc32 hash for the filehandle
+  * @fh - pointer to filehandle
+@@ -275,12 +274,6 @@ static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh)
+ {
+       return ~crc32_le(0xFFFFFFFF, fh->fh_raw, fh->fh_size);
+ }
+-#else
+-static inline u32 knfsd_fh_hash(const struct knfsd_fh *fh)
+-{
+-      return 0;
+-}
+-#endif
+ /**
+  * fh_clear_pre_post_attrs - Reset pre/post attributes
+diff --git a/include/linux/nfs.h b/include/linux/nfs.h
+index ceb70a926b95e..095a95c1fae82 100644
+--- a/include/linux/nfs.h
++++ b/include/linux/nfs.h
+@@ -46,7 +46,6 @@ enum nfs3_stable_how {
+       NFS_INVALID_STABLE_HOW = -1
+ };
+-#ifdef CONFIG_CRC32
+ /**
+  * nfs_fhandle_hash - calculate the crc32 hash for the filehandle
+  * @fh - pointer to filehandle
+@@ -58,10 +57,4 @@ static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
+ {
+       return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
+ }
+-#else /* CONFIG_CRC32 */
+-static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
+-{
+-      return 0;
+-}
+-#endif /* CONFIG_CRC32 */
+ #endif /* _LINUX_NFS_H */
+-- 
+2.39.5
+
diff --git a/queue-6.1/nfs-move-nfs_fhandle_hash-to-common-include-file.patch b/queue-6.1/nfs-move-nfs_fhandle_hash-to-common-include-file.patch
new file mode 100644 (file)
index 0000000..03bfb23
--- /dev/null
@@ -0,0 +1,92 @@
+From 46181bd821cc20fac9d83d95e2f706893557e896 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Mar 2023 07:16:02 -0500
+Subject: nfs: move nfs_fhandle_hash to common include file
+
+From: Jeff Layton <jlayton@kernel.org>
+
+[ Upstream commit e59fb6749ed833deee5b3cfd7e89925296d41f49 ]
+
+lockd needs to be able to hash filehandles for tracepoints. Move the
+nfs_fhandle_hash() helper to a common nfs include file.
+
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Stable-dep-of: cd35b6cb4664 ("nfs: add missing selections of CONFIG_CRC32")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfs/internal.h   | 15 ---------------
+ include/linux/nfs.h | 20 ++++++++++++++++++++
+ 2 files changed, 20 insertions(+), 15 deletions(-)
+
+diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
+index 7fa23a6368e0b..d511d66bd8a3a 100644
+--- a/fs/nfs/internal.h
++++ b/fs/nfs/internal.h
+@@ -827,27 +827,12 @@ u64 nfs_timespec_to_change_attr(const struct timespec64 *ts)
+ }
+ #ifdef CONFIG_CRC32
+-/**
+- * nfs_fhandle_hash - calculate the crc32 hash for the filehandle
+- * @fh - pointer to filehandle
+- *
+- * returns a crc32 hash for the filehandle that is compatible with
+- * the one displayed by "wireshark".
+- */
+-static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
+-{
+-      return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
+-}
+ static inline u32 nfs_stateid_hash(const nfs4_stateid *stateid)
+ {
+       return ~crc32_le(0xFFFFFFFF, &stateid->other[0],
+                               NFS4_STATEID_OTHER_SIZE);
+ }
+ #else
+-static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
+-{
+-      return 0;
+-}
+ static inline u32 nfs_stateid_hash(nfs4_stateid *stateid)
+ {
+       return 0;
+diff --git a/include/linux/nfs.h b/include/linux/nfs.h
+index b06375e88e589..ceb70a926b95e 100644
+--- a/include/linux/nfs.h
++++ b/include/linux/nfs.h
+@@ -10,6 +10,7 @@
+ #include <linux/sunrpc/msg_prot.h>
+ #include <linux/string.h>
++#include <linux/crc32.h>
+ #include <uapi/linux/nfs.h>
+ /*
+@@ -44,4 +45,23 @@ enum nfs3_stable_how {
+       /* used by direct.c to mark verf as invalid */
+       NFS_INVALID_STABLE_HOW = -1
+ };
++
++#ifdef CONFIG_CRC32
++/**
++ * nfs_fhandle_hash - calculate the crc32 hash for the filehandle
++ * @fh - pointer to filehandle
++ *
++ * returns a crc32 hash for the filehandle that is compatible with
++ * the one displayed by "wireshark".
++ */
++static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
++{
++      return ~crc32_le(0xFFFFFFFF, &fh->data[0], fh->size);
++}
++#else /* CONFIG_CRC32 */
++static inline u32 nfs_fhandle_hash(const struct nfs_fh *fh)
++{
++      return 0;
++}
++#endif /* CONFIG_CRC32 */
+ #endif /* _LINUX_NFS_H */
+-- 
+2.39.5
+
diff --git a/queue-6.1/nfsd-decrease-sc_count-directly-if-fail-to-queue-dl_.patch b/queue-6.1/nfsd-decrease-sc_count-directly-if-fail-to-queue-dl_.patch
new file mode 100644 (file)
index 0000000..040c0d7
--- /dev/null
@@ -0,0 +1,75 @@
+From 13baebc23a89b7ef227b4d8f6a1a5ee36e390342 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Apr 2025 09:57:08 +0800
+Subject: nfsd: decrease sc_count directly if fail to queue dl_recall
+
+From: Li Lingfeng <lilingfeng3@huawei.com>
+
+[ Upstream commit a1d14d931bf700c1025db8c46d6731aa5cf440f9 ]
+
+A deadlock warning occurred when invoking nfs4_put_stid following a failed
+dl_recall queue operation:
+            T1                            T2
+                                nfs4_laundromat
+                                 nfs4_get_client_reaplist
+                                  nfs4_anylock_blockers
+__break_lease
+ spin_lock // ctx->flc_lock
+                                   spin_lock // clp->cl_lock
+                                   nfs4_lockowner_has_blockers
+                                    locks_owner_has_blockers
+                                     spin_lock // flctx->flc_lock
+ nfsd_break_deleg_cb
+  nfsd_break_one_deleg
+   nfs4_put_stid
+    refcount_dec_and_lock
+     spin_lock // clp->cl_lock
+
+When a file is opened, an nfs4_delegation is allocated with sc_count
+initialized to 1, and the file_lease holds a reference to the delegation.
+The file_lease is then associated with the file through kernel_setlease.
+
+The disassociation is performed in nfsd4_delegreturn via the following
+call chain:
+nfsd4_delegreturn --> destroy_delegation --> destroy_unhashed_deleg -->
+nfs4_unlock_deleg_lease --> kernel_setlease --> generic_delete_lease
+The corresponding sc_count reference will be released after this
+disassociation.
+
+Since nfsd_break_one_deleg executes while holding the flc_lock, the
+disassociation process becomes blocked when attempting to acquire flc_lock
+in generic_delete_lease. This means:
+1) sc_count in nfsd_break_one_deleg will not be decremented to 0;
+2) The nfs4_put_stid called by nfsd_break_one_deleg will not attempt to
+acquire cl_lock;
+3) Consequently, no deadlock condition is created.
+
+Given that sc_count in nfsd_break_one_deleg remains non-zero, we can
+safely perform refcount_dec on sc_count directly. This approach
+effectively avoids triggering deadlock warnings.
+
+Fixes: 230ca758453c ("nfsd: put dl_stid if fail to queue dl_recall")
+Signed-off-by: Li Lingfeng <lilingfeng3@huawei.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 628d20574a919..bdee95d714d0e 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -4941,7 +4941,7 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
+       queued = nfsd4_run_cb(&dp->dl_recall);
+       WARN_ON_ONCE(!queued);
+       if (!queued)
+-              nfs4_put_stid(&dp->dl_stid);
++              refcount_dec(&dp->dl_stid.sc_count);
+ }
+ /* Called from break_lease() with flc_lock held. */
+-- 
+2.39.5
+
index f43bede492512af6ae08f6a53ecd011c29c1973e..f325997268795162a668bd3b6193dd003ceef1bd 100644 (file)
@@ -197,3 +197,6 @@ riscv-properly-export-reserved-regions-in-proc-iomem.patch
 riscv-kgdb-do-not-inline-arch_kgdb_breakpoint.patch
 riscv-kgdb-remove-.option-norvc-.option-rvc-for-kgdb.patch
 cpufreq-sched-fix-the-usage-of-cpufreq_need_update_l.patch
+nfs-move-nfs_fhandle_hash-to-common-include-file.patch
+nfs-add-missing-selections-of-config_crc32.patch
+nfsd-decrease-sc_count-directly-if-fail-to-queue-dl_.patch