ceph: allocate the correct amount of extra bytes for the session features
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>
This commit is contained in:
parent
5b3248c677
commit
9ba1e22453
2 changed files with 30 additions and 13 deletions
|
@ -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)
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
* 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 @@
|
||||||
#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,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This will always have the highest feature bit value
|
||||||
|
* as the last element of the array.
|
||||||
|
*/
|
||||||
#define CEPHFS_FEATURES_CLIENT_SUPPORTED { \
|
#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:
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue