]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ceph: allocate the correct amount of extra bytes for the session features
authorXiubo Li <xiubli@redhat.com>
Wed, 8 Jan 2020 10:17:31 +0000 (05:17 -0500)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 27 Jan 2020 15:53:40 +0000 (16:53 +0100)
The total bytes may potentially be larger than 8.

Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/mds_client.c
fs/ceph/mds_client.h

index f7c9a56514f9c2ab87c5d7f2ced49e5b9d296da7..c839664f86c649cb6b2e49f7a2478304ca5ce7cd 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
+#include <linux/bits.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -1057,20 +1058,21 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq)
        return msg;
 }
 
+static const unsigned char feature_bits[] = CEPHFS_FEATURES_CLIENT_SUPPORTED;
+#define FEATURE_BYTES(c) (DIV_ROUND_UP((size_t)feature_bits[c - 1] + 1, 64) * 8)
 static void encode_supported_features(void **p, void *end)
 {
-       static const unsigned char bits[] = CEPHFS_FEATURES_CLIENT_SUPPORTED;
-       static const size_t count = ARRAY_SIZE(bits);
+       static const size_t count = ARRAY_SIZE(feature_bits);
 
        if (count > 0) {
                size_t i;
-               size_t size = ((size_t)bits[count - 1] + 64) / 64 * 8;
+               size_t size = FEATURE_BYTES(count);
 
                BUG_ON(*p + 4 + size > end);
                ceph_encode_32(p, size);
                memset(*p, 0, size);
                for (i = 0; i < count; i++)
-                       ((unsigned char*)(*p))[i / 8] |= 1 << (bits[i] % 8);
+                       ((unsigned char*)(*p))[i / 8] |= BIT(feature_bits[i] % 8);
                *p += size;
        } else {
                BUG_ON(*p + 4 > end);
@@ -1091,6 +1093,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
        int metadata_key_count = 0;
        struct ceph_options *opt = mdsc->fsc->client->options;
        struct ceph_mount_options *fsopt = mdsc->fsc->mount_options;
+       size_t size, count;
        void *p, *end;
 
        const char* metadata[][2] = {
@@ -1108,8 +1111,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
                        strlen(metadata[i][1]);
                metadata_key_count++;
        }
+
        /* supported feature */
-       extra_bytes += 4 + 8;
+       size = 0;
+       count = ARRAY_SIZE(feature_bits);
+       if (count > 0)
+               size = FEATURE_BYTES(count);
+       extra_bytes += 4 + size;
 
        /* Allocate the message */
        msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes,
@@ -1129,7 +1137,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
         * Serialize client metadata into waiting buffer space, using
         * the format that userspace expects for map<string, string>
         *
-        * ClientSession messages with metadata are v2
+        * ClientSession messages with metadata are v3
         */
        msg->hdr.version = cpu_to_le16(3);
        msg->hdr.compat_version = cpu_to_le16(1);
index c021df5f50cef0f7e82e34f583e197e85b59da4f..c950f8f88f587624d06647fca20fae18b4ef0006 100644 (file)
 #include <linux/ceph/auth.h>
 
 /* The first 8 bits are reserved for old ceph releases */
-#define CEPHFS_FEATURE_MIMIC           8
-#define CEPHFS_FEATURE_REPLY_ENCODING  9
-#define CEPHFS_FEATURE_RECLAIM_CLIENT  10
-#define CEPHFS_FEATURE_LAZY_CAP_WANTED 11
-#define CEPHFS_FEATURE_MULTI_RECONNECT  12
+enum ceph_feature_type {
+       CEPHFS_FEATURE_MIMIC = 8,
+       CEPHFS_FEATURE_REPLY_ENCODING,
+       CEPHFS_FEATURE_RECLAIM_CLIENT,
+       CEPHFS_FEATURE_LAZY_CAP_WANTED,
+       CEPHFS_FEATURE_MULTI_RECONNECT,
+
+       CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_MULTI_RECONNECT,
+};
 
-#define CEPHFS_FEATURES_CLIENT_SUPPORTED {     \
+/*
+ * This will always have the highest feature bit value
+ * as the last element of the array.
+ */
+#define CEPHFS_FEATURES_CLIENT_SUPPORTED {     \
        0, 1, 2, 3, 4, 5, 6, 7,                 \
        CEPHFS_FEATURE_MIMIC,                   \
        CEPHFS_FEATURE_REPLY_ENCODING,          \
        CEPHFS_FEATURE_LAZY_CAP_WANTED,         \
        CEPHFS_FEATURE_MULTI_RECONNECT,         \
+                                               \
+       CEPHFS_FEATURE_MAX,                     \
 }
 #define CEPHFS_FEATURES_CLIENT_REQUIRED {}
 
-
 /*
  * Some lock dependencies:
  *