--- /dev/null
+From 98b0204ef9ae00f351b501d399f4d47b55328847 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Feb 2024 13:14:32 +0800
+Subject: ceph: switch to corrected encoding of max_xattr_size in mdsmap
+
+From: Xiubo Li <xiubli@redhat.com>
+
+[ Upstream commit 51d31149a88b5c5a8d2d33f06df93f6187a25b4c ]
+
+The addition of bal_rank_mask with encoding version 17 was merged
+into ceph.git in Oct 2022 and made it into v18.2.0 release normally.
+A few months later, the much delayed addition of max_xattr_size got
+merged, also with encoding version 17, placed before bal_rank_mask
+in the encoding -- but it didn't make v18.2.0 release.
+
+The way this ended up being resolved on the MDS side is that
+bal_rank_mask will continue to be encoded in version 17 while
+max_xattr_size is now encoded in version 18. This does mean that
+older kernels will misdecode version 17, but this is also true for
+v18.2.0 and v18.2.1 clients in userspace.
+
+The best we can do is backport this adjustment -- see ceph.git
+commit 78abfeaff27fee343fb664db633de5b221699a73 for details.
+
+[ idryomov: changelog ]
+
+Cc: stable@vger.kernel.org
+Link: https://tracker.ceph.com/issues/64440
+Fixes: d93231a6bc8a ("ceph: prevent a client from exceeding the MDS maximum xattr size")
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Patrick Donnelly <pdonnell@ibm.com>
+Reviewed-by: Venky Shankar <vshankar@redhat.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ceph/mdsmap.c | 7 ++++---
+ include/linux/ceph/mdsmap.h | 6 +++++-
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c
+index 3fbabc98e1f70..4a089d70ebd07 100644
+--- a/fs/ceph/mdsmap.c
++++ b/fs/ceph/mdsmap.c
+@@ -379,10 +379,11 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end, bool msgr2)
+ ceph_decode_skip_8(p, end, bad_ext);
+ /* required_client_features */
+ ceph_decode_skip_set(p, end, 64, bad_ext);
++ /* bal_rank_mask */
++ ceph_decode_skip_string(p, end, bad_ext);
++ }
++ if (mdsmap_ev >= 18) {
+ ceph_decode_64_safe(p, end, m->m_max_xattr_size, bad_ext);
+- } else {
+- /* This forces the usage of the (sync) SETXATTR Op */
+- m->m_max_xattr_size = 0;
+ }
+ bad_ext:
+ dout("mdsmap_decode m_enabled: %d, m_damaged: %d, m_num_laggy: %d\n",
+diff --git a/include/linux/ceph/mdsmap.h b/include/linux/ceph/mdsmap.h
+index 4c3e0648dc277..fcc95bff72a57 100644
+--- a/include/linux/ceph/mdsmap.h
++++ b/include/linux/ceph/mdsmap.h
+@@ -25,7 +25,11 @@ struct ceph_mdsmap {
+ u32 m_session_timeout; /* seconds */
+ u32 m_session_autoclose; /* seconds */
+ u64 m_max_file_size;
+- u64 m_max_xattr_size; /* maximum size for xattrs blob */
++ /*
++ * maximum size for xattrs blob.
++ * Zeroed by default to force the usage of the (sync) SETXATTR Op.
++ */
++ u64 m_max_xattr_size;
+ u32 m_max_mds; /* expected up:active mds number */
+ u32 m_num_active_mds; /* actual up:active mds number */
+ u32 possible_max_rank; /* possible max rank index */
+--
+2.43.0
+