Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ceph: send client metadata to MDS

Implement version 2 of CEPH_MSG_CLIENT_SESSION syntax,
which includes additional client metadata to allow
the MDS to report on clients by user-sensible names
like hostname.

Signed-off-by: John Spray <john.spray@redhat.com>
Reviewed-by: Yan, Zheng <zyan@redhat.com>

authored by

John Spray and committed by
Sage Weil
dbd0c8bf a4483e8a

+70 -1
+70 -1
fs/ceph/mds_client.c
··· 7 7 #include <linux/sched.h> 8 8 #include <linux/debugfs.h> 9 9 #include <linux/seq_file.h> 10 + #include <linux/utsname.h> 10 11 11 12 #include "super.h" 12 13 #include "mds_client.h" ··· 813 812 h = msg->front.iov_base; 814 813 h->op = cpu_to_le32(op); 815 814 h->seq = cpu_to_le64(seq); 815 + 816 + return msg; 817 + } 818 + 819 + /* 820 + * session message, specialization for CEPH_SESSION_REQUEST_OPEN 821 + * to include additional client metadata fields. 822 + */ 823 + static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u64 seq) 824 + { 825 + struct ceph_msg *msg; 826 + struct ceph_mds_session_head *h; 827 + int i = -1; 828 + int metadata_bytes = 0; 829 + int metadata_key_count = 0; 830 + struct ceph_options *opt = mdsc->fsc->client->options; 831 + void *p; 832 + 833 + const char* metadata[3][2] = { 834 + {"hostname", utsname()->nodename}, 835 + {"entity_id", opt->name ? opt->name : ""}, 836 + {NULL, NULL} 837 + }; 838 + 839 + /* Calculate serialized length of metadata */ 840 + metadata_bytes = 4; /* map length */ 841 + for (i = 0; metadata[i][0] != NULL; ++i) { 842 + metadata_bytes += 8 + strlen(metadata[i][0]) + 843 + strlen(metadata[i][1]); 844 + metadata_key_count++; 845 + } 846 + 847 + /* Allocate the message */ 848 + msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + metadata_bytes, 849 + GFP_NOFS, false); 850 + if (!msg) { 851 + pr_err("create_session_msg ENOMEM creating msg\n"); 852 + return NULL; 853 + } 854 + h = msg->front.iov_base; 855 + h->op = cpu_to_le32(CEPH_SESSION_REQUEST_OPEN); 856 + h->seq = cpu_to_le64(seq); 857 + 858 + /* 859 + * Serialize client metadata into waiting buffer space, using 860 + * the format that userspace expects for map<string, string> 861 + */ 862 + msg->hdr.version = 2; /* ClientSession messages with metadata are v2 */ 863 + 864 + /* The write pointer, following the session_head structure */ 865 + p = msg->front.iov_base + sizeof(*h); 866 + 867 + /* Number of entries in the map */ 868 + ceph_encode_32(&p, metadata_key_count); 869 + 870 + /* Two length-prefixed strings for each entry in the map */ 871 + for (i = 0; metadata[i][0] != NULL; ++i) { 872 + size_t const key_len = strlen(metadata[i][0]); 873 + size_t const val_len = strlen(metadata[i][1]); 874 + 875 + ceph_encode_32(&p, key_len); 876 + memcpy(p, metadata[i][0], key_len); 877 + p += key_len; 878 + ceph_encode_32(&p, val_len); 879 + memcpy(p, metadata[i][1], val_len); 880 + p += val_len; 881 + } 882 + 816 883 return msg; 817 884 } 818 885 ··· 904 835 session->s_renew_requested = jiffies; 905 836 906 837 /* send connect message */ 907 - msg = create_session_msg(CEPH_SESSION_REQUEST_OPEN, session->s_seq); 838 + msg = create_session_open_msg(mdsc, session->s_seq); 908 839 if (!msg) 909 840 return -ENOMEM; 910 841 ceph_con_send(&session->s_con, msg);