Skip to content

Commit

Permalink
ceph: allocate the correct amount of extra bytes for the session feat…
Browse files Browse the repository at this point in the history
…ures

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>
  • Loading branch information
lxbsz authored and idryomov committed Jan 27, 2020
1 parent 5b3248c commit 9ba1e22
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
20 changes: 14 additions & 6 deletions fs/ceph/mds_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand All @@ -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] = {
Expand All @@ -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,
Expand All @@ -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);
Expand Down
23 changes: 16 additions & 7 deletions fs/ceph/mds_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,31 @@
#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:
*
Expand Down

0 comments on commit 9ba1e22

Please sign in to comment.