On Thu, 2020-07-16 at 10:05 -0400, xiubli@xxxxxxxxxx wrote: > From: Xiubo Li <xiubli@xxxxxxxxxx> > > Will send the metric flags to MDS, currently it supports the cap, > read latency, write latency and metadata latency. > > URL: https://tracker.ceph.com/issues/43435 > Signed-off-by: Xiubo Li <xiubli@xxxxxxxxxx> > --- > fs/ceph/mds_client.c | 60 ++++++++++++++++++++++++++++++++++++++++++-- > fs/ceph/metric.h | 13 ++++++++++ > 2 files changed, 71 insertions(+), 2 deletions(-) > > diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c > index cf4c2ba2311f..929778625ea5 100644 > --- a/fs/ceph/mds_client.c > +++ b/fs/ceph/mds_client.c > @@ -1194,6 +1194,48 @@ static int encode_supported_features(void **p, void *end) > return 0; > } > > +static const unsigned char metric_bits[] = CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED; > +#define METRIC_BYTES(cnt) (DIV_ROUND_UP((size_t)metric_bits[cnt - 1] + 1, 64) * 8) > +static int encode_metric_spec(void **p, void *end) > +{ > + static const size_t count = ARRAY_SIZE(metric_bits); > + > + /* header */ > + if (WARN_ON_ONCE(*p + 2 > end)) > + return -ERANGE; > + > + ceph_encode_8(p, 1); /* version */ > + ceph_encode_8(p, 1); /* compat */ > + > + if (count > 0) { > + size_t i; > + size_t size = METRIC_BYTES(count); > + > + if (WARN_ON_ONCE(*p + 4 + 4 + size > end)) > + return -ERANGE; > + > + /* metric spec info length */ > + ceph_encode_32(p, 4 + size); > + > + /* metric spec */ > + ceph_encode_32(p, size); > + memset(*p, 0, size); > + for (i = 0; i < count; i++) > + ((unsigned char *)(*p))[i / 8] |= BIT(metric_bits[i] % 8); > + *p += size; > + } else { > + if (WARN_ON_ONCE(*p + 4 + 4 > end)) > + return -ERANGE; > + > + /* metric spec info length */ > + ceph_encode_32(p, 4); > + /* metric spec */ > + ceph_encode_32(p, 0); > + } > + > + return 0; > +} > + > /* > * session message, specialization for CEPH_SESSION_REQUEST_OPEN > * to include additional client metadata fields. > @@ -1234,6 +1276,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 > size = FEATURE_BYTES(count); > extra_bytes += 4 + size; > > + /* metric spec */ > + size = 0; > + count = ARRAY_SIZE(metric_bits); > + if (count > 0) > + size = METRIC_BYTES(count); > + extra_bytes += 2 + 4 + 4 + size; > + > /* Allocate the message */ > msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes, > GFP_NOFS, false); > @@ -1252,9 +1301,9 @@ 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 v3 > + * ClientSession messages with metadata are v4 > */ > - msg->hdr.version = cpu_to_le16(3); > + msg->hdr.version = cpu_to_le16(4); > msg->hdr.compat_version = cpu_to_le16(1); > > /* The write pointer, following the session_head structure */ > @@ -1283,6 +1332,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 > return ERR_PTR(ret); > } > > + ret = encode_metric_spec(&p, end); > + if (ret) { > + pr_err("encode_metric_spec failed!\n"); > + ceph_msg_put(msg); > + return ERR_PTR(ret); > + } > + > msg->front.iov_len = p - msg->front.iov_base; > msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); > > diff --git a/fs/ceph/metric.h b/fs/ceph/metric.h > index fe5d07d2e63a..1d0959d669d7 100644 > --- a/fs/ceph/metric.h > +++ b/fs/ceph/metric.h > @@ -18,6 +18,19 @@ enum ceph_metric_type { > CLIENT_METRIC_TYPE_MAX = CLIENT_METRIC_TYPE_DENTRY_LEASE, > }; > > +/* > + * This will always have the highest metric bit value > + * as the last element of the array. > + */ > +#define CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED { \ > + CLIENT_METRIC_TYPE_CAP_INFO, \ > + CLIENT_METRIC_TYPE_READ_LATENCY, \ > + CLIENT_METRIC_TYPE_WRITE_LATENCY, \ > + CLIENT_METRIC_TYPE_METADATA_LATENCY, \ > + \ > + CLIENT_METRIC_TYPE_MAX, \ Not a huge problem now, but shouldn't this last line be? CLIENT_METRIC_TYPE_MAX = CLIENT_METRIC_TYPE_METADATA_LATENCY, > +} > + > /* metric caps header */ > struct ceph_metric_cap { > __le32 type; /* ceph metric type */ -- Jeff Layton <jlayton@xxxxxxxxxx>