Commit 9ba1e224 authored by Xiubo Li's avatar Xiubo Li Committed by Ilya Dryomov

ceph: allocate the correct amount of extra bytes for the session features

The total bytes may potentially be larger than 8.
Signed-off-by: default avatarXiubo Li <xiubli@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
parent 5b3248c6
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/bits.h>
#include "super.h" #include "super.h"
#include "mds_client.h" #include "mds_client.h"
...@@ -1057,20 +1058,21 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq) ...@@ -1057,20 +1058,21 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq)
return msg; 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 void encode_supported_features(void **p, void *end)
{ {
static const unsigned char bits[] = CEPHFS_FEATURES_CLIENT_SUPPORTED; static const size_t count = ARRAY_SIZE(feature_bits);
static const size_t count = ARRAY_SIZE(bits);
if (count > 0) { if (count > 0) {
size_t i; 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); BUG_ON(*p + 4 + size > end);
ceph_encode_32(p, size); ceph_encode_32(p, size);
memset(*p, 0, size); memset(*p, 0, size);
for (i = 0; i < count; i++) 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; *p += size;
} else { } else {
BUG_ON(*p + 4 > end); BUG_ON(*p + 4 > end);
...@@ -1091,6 +1093,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 ...@@ -1091,6 +1093,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
int metadata_key_count = 0; int metadata_key_count = 0;
struct ceph_options *opt = mdsc->fsc->client->options; struct ceph_options *opt = mdsc->fsc->client->options;
struct ceph_mount_options *fsopt = mdsc->fsc->mount_options; struct ceph_mount_options *fsopt = mdsc->fsc->mount_options;
size_t size, count;
void *p, *end; void *p, *end;
const char* metadata[][2] = { const char* metadata[][2] = {
...@@ -1108,8 +1111,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 ...@@ -1108,8 +1111,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
strlen(metadata[i][1]); strlen(metadata[i][1]);
metadata_key_count++; metadata_key_count++;
} }
/* supported feature */ /* 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 */ /* Allocate the message */
msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes, 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 ...@@ -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 * Serialize client metadata into waiting buffer space, using
* the format that userspace expects for map<string, string> * 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.version = cpu_to_le16(3);
msg->hdr.compat_version = cpu_to_le16(1); msg->hdr.compat_version = cpu_to_le16(1);
......
...@@ -17,22 +17,31 @@ ...@@ -17,22 +17,31 @@
#include <linux/ceph/auth.h> #include <linux/ceph/auth.h>
/* The first 8 bits are reserved for old ceph releases */ /* The first 8 bits are reserved for old ceph releases */
#define CEPHFS_FEATURE_MIMIC 8 enum ceph_feature_type {
#define CEPHFS_FEATURE_REPLY_ENCODING 9 CEPHFS_FEATURE_MIMIC = 8,
#define CEPHFS_FEATURE_RECLAIM_CLIENT 10 CEPHFS_FEATURE_REPLY_ENCODING,
#define CEPHFS_FEATURE_LAZY_CAP_WANTED 11 CEPHFS_FEATURE_RECLAIM_CLIENT,
#define CEPHFS_FEATURE_MULTI_RECONNECT 12 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, \ 0, 1, 2, 3, 4, 5, 6, 7, \
CEPHFS_FEATURE_MIMIC, \ CEPHFS_FEATURE_MIMIC, \
CEPHFS_FEATURE_REPLY_ENCODING, \ CEPHFS_FEATURE_REPLY_ENCODING, \
CEPHFS_FEATURE_LAZY_CAP_WANTED, \ CEPHFS_FEATURE_LAZY_CAP_WANTED, \
CEPHFS_FEATURE_MULTI_RECONNECT, \ CEPHFS_FEATURE_MULTI_RECONNECT, \
\
CEPHFS_FEATURE_MAX, \
} }
#define CEPHFS_FEATURES_CLIENT_REQUIRED {} #define CEPHFS_FEATURES_CLIENT_REQUIRED {}
/* /*
* Some lock dependencies: * Some lock dependencies:
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment