Message ID | 20200108101731.26652-1-xiubli@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] ceph: allocate the accurate extra bytes for the session features | expand |
The testing output: # ./bin/cephfs-journal-tool --rank=1:0 event get --type=SESSION json Wrote output to JSON file 'dump' # cat dump [ { "client instance": "client.4275 v1:192.168.195.165:0/461391971", "open": "true", "client map version": 1, "inos": "[]", "inotable version": 0, "client_metadata": { "client_features": { "feature_bits": "0000000000001bff" }, "entity_id": "", "hostname": "fedora1", "kernel_version": "5.5.0-rc2+", "root": "/" } }, [...] On 2020/1/8 18:17, xiubli@redhat.com wrote: > From: Xiubo Li <xiubli@redhat.com> > > The totally bytes maybe potentially larger than 8. > > Signed-off-by: Xiubo Li <xiubli@redhat.com> > --- > fs/ceph/mds_client.c | 20 ++++++++++++++------ > fs/ceph/mds_client.h | 23 ++++++++++++++++------- > 2 files changed, 30 insertions(+), 13 deletions(-) > > diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c > index 94cce2ab92c4..d379f489ab63 100644 > --- a/fs/ceph/mds_client.c > +++ b/fs/ceph/mds_client.c > @@ -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" > @@ -1053,20 +1054,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); > @@ -1087,6 +1089,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] = { > @@ -1104,8 +1107,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, > @@ -1125,7 +1133,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); > diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h > index c021df5f50ce..c950f8f88f58 100644 > --- a/fs/ceph/mds_client.h > +++ b/fs/ceph/mds_client.h > @@ -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: > *
On Wed, 2020-01-08 at 05:17 -0500, xiubli@redhat.com wrote: > From: Xiubo Li <xiubli@redhat.com> > > The totally bytes maybe potentially larger than 8. > > Signed-off-by: Xiubo Li <xiubli@redhat.com> > --- > fs/ceph/mds_client.c | 20 ++++++++++++++------ > fs/ceph/mds_client.h | 23 ++++++++++++++++------- > 2 files changed, 30 insertions(+), 13 deletions(-) > > diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c > index 94cce2ab92c4..d379f489ab63 100644 > --- a/fs/ceph/mds_client.c > +++ b/fs/ceph/mds_client.c > @@ -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" > @@ -1053,20 +1054,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); > @@ -1087,6 +1089,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] = { > @@ -1104,8 +1107,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, > @@ -1125,7 +1133,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); > diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h > index c021df5f50ce..c950f8f88f58 100644 > --- a/fs/ceph/mds_client.h > +++ b/fs/ceph/mds_client.h > @@ -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: > * Merged (with small changelog rephrasing). Thanks!
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 94cce2ab92c4..d379f489ab63 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -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" @@ -1053,20 +1054,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); @@ -1087,6 +1089,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] = { @@ -1104,8 +1107,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, @@ -1125,7 +1133,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); diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index c021df5f50ce..c950f8f88f58 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -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: *