diff options
-rw-r--r-- | fs/ceph/mds_client.c | 48 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 12 |
2 files changed, 51 insertions, 9 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 8dbfca01c7ea..5b767cf1f780 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -902,6 +902,27 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq) | |||
902 | return msg; | 902 | return msg; |
903 | } | 903 | } |
904 | 904 | ||
905 | static void encode_supported_features(void **p, void *end) | ||
906 | { | ||
907 | static const unsigned char bits[] = CEPHFS_FEATURES_CLIENT_SUPPORTED; | ||
908 | static const size_t count = ARRAY_SIZE(bits); | ||
909 | |||
910 | if (count > 0) { | ||
911 | size_t i; | ||
912 | size_t size = ((size_t)bits[count - 1] + 64) / 64 * 8; | ||
913 | |||
914 | BUG_ON(*p + 4 + size > end); | ||
915 | ceph_encode_32(p, size); | ||
916 | memset(*p, 0, size); | ||
917 | for (i = 0; i < count; i++) | ||
918 | ((unsigned char*)(*p))[i / 8] |= 1 << (bits[i] % 8); | ||
919 | *p += size; | ||
920 | } else { | ||
921 | BUG_ON(*p + 4 > end); | ||
922 | ceph_encode_32(p, 0); | ||
923 | } | ||
924 | } | ||
925 | |||
905 | /* | 926 | /* |
906 | * session message, specialization for CEPH_SESSION_REQUEST_OPEN | 927 | * session message, specialization for CEPH_SESSION_REQUEST_OPEN |
907 | * to include additional client metadata fields. | 928 | * to include additional client metadata fields. |
@@ -911,11 +932,11 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 | |||
911 | struct ceph_msg *msg; | 932 | struct ceph_msg *msg; |
912 | struct ceph_mds_session_head *h; | 933 | struct ceph_mds_session_head *h; |
913 | int i = -1; | 934 | int i = -1; |
914 | int metadata_bytes = 0; | 935 | int extra_bytes = 0; |
915 | int metadata_key_count = 0; | 936 | int metadata_key_count = 0; |
916 | struct ceph_options *opt = mdsc->fsc->client->options; | 937 | struct ceph_options *opt = mdsc->fsc->client->options; |
917 | struct ceph_mount_options *fsopt = mdsc->fsc->mount_options; | 938 | struct ceph_mount_options *fsopt = mdsc->fsc->mount_options; |
918 | void *p; | 939 | void *p, *end; |
919 | 940 | ||
920 | const char* metadata[][2] = { | 941 | const char* metadata[][2] = { |
921 | {"hostname", mdsc->nodename}, | 942 | {"hostname", mdsc->nodename}, |
@@ -926,21 +947,26 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 | |||
926 | }; | 947 | }; |
927 | 948 | ||
928 | /* Calculate serialized length of metadata */ | 949 | /* Calculate serialized length of metadata */ |
929 | metadata_bytes = 4; /* map length */ | 950 | extra_bytes = 4; /* map length */ |
930 | for (i = 0; metadata[i][0]; ++i) { | 951 | for (i = 0; metadata[i][0]; ++i) { |
931 | metadata_bytes += 8 + strlen(metadata[i][0]) + | 952 | extra_bytes += 8 + strlen(metadata[i][0]) + |
932 | strlen(metadata[i][1]); | 953 | strlen(metadata[i][1]); |
933 | metadata_key_count++; | 954 | metadata_key_count++; |
934 | } | 955 | } |
956 | /* supported feature */ | ||
957 | extra_bytes += 4 + 8; | ||
935 | 958 | ||
936 | /* Allocate the message */ | 959 | /* Allocate the message */ |
937 | msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + metadata_bytes, | 960 | msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes, |
938 | GFP_NOFS, false); | 961 | GFP_NOFS, false); |
939 | if (!msg) { | 962 | if (!msg) { |
940 | pr_err("create_session_msg ENOMEM creating msg\n"); | 963 | pr_err("create_session_msg ENOMEM creating msg\n"); |
941 | return NULL; | 964 | return NULL; |
942 | } | 965 | } |
943 | h = msg->front.iov_base; | 966 | p = msg->front.iov_base; |
967 | end = p + msg->front.iov_len; | ||
968 | |||
969 | h = p; | ||
944 | h->op = cpu_to_le32(CEPH_SESSION_REQUEST_OPEN); | 970 | h->op = cpu_to_le32(CEPH_SESSION_REQUEST_OPEN); |
945 | h->seq = cpu_to_le64(seq); | 971 | h->seq = cpu_to_le64(seq); |
946 | 972 | ||
@@ -950,11 +976,11 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 | |||
950 | * | 976 | * |
951 | * ClientSession messages with metadata are v2 | 977 | * ClientSession messages with metadata are v2 |
952 | */ | 978 | */ |
953 | msg->hdr.version = cpu_to_le16(2); | 979 | msg->hdr.version = cpu_to_le16(3); |
954 | msg->hdr.compat_version = cpu_to_le16(1); | 980 | msg->hdr.compat_version = cpu_to_le16(1); |
955 | 981 | ||
956 | /* The write pointer, following the session_head structure */ | 982 | /* The write pointer, following the session_head structure */ |
957 | p = msg->front.iov_base + sizeof(*h); | 983 | p += sizeof(*h); |
958 | 984 | ||
959 | /* Number of entries in the map */ | 985 | /* Number of entries in the map */ |
960 | ceph_encode_32(&p, metadata_key_count); | 986 | ceph_encode_32(&p, metadata_key_count); |
@@ -972,6 +998,10 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6 | |||
972 | p += val_len; | 998 | p += val_len; |
973 | } | 999 | } |
974 | 1000 | ||
1001 | encode_supported_features(&p, end); | ||
1002 | msg->front.iov_len = p - msg->front.iov_base; | ||
1003 | msg->hdr.front_len = cpu_to_le32(msg->front.iov_len); | ||
1004 | |||
975 | return msg; | 1005 | return msg; |
976 | } | 1006 | } |
977 | 1007 | ||
@@ -2749,7 +2779,7 @@ static void handle_session(struct ceph_mds_session *session, | |||
2749 | int wake = 0; | 2779 | int wake = 0; |
2750 | 2780 | ||
2751 | /* decode */ | 2781 | /* decode */ |
2752 | if (msg->front.iov_len != sizeof(*h)) | 2782 | if (msg->front.iov_len < sizeof(*h)) |
2753 | goto bad; | 2783 | goto bad; |
2754 | op = le32_to_cpu(h->op); | 2784 | op = le32_to_cpu(h->op); |
2755 | seq = le64_to_cpu(h->seq); | 2785 | seq = le64_to_cpu(h->seq); |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 80a7523e1523..32fcce0d4d3c 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -16,6 +16,18 @@ | |||
16 | #include <linux/ceph/mdsmap.h> | 16 | #include <linux/ceph/mdsmap.h> |
17 | #include <linux/ceph/auth.h> | 17 | #include <linux/ceph/auth.h> |
18 | 18 | ||
19 | /* The first 8 bits are reserved for old ceph releases */ | ||
20 | #define CEPHFS_FEATURE_MIMIC 8 | ||
21 | |||
22 | #define CEPHFS_FEATURES_ALL { \ | ||
23 | 0, 1, 2, 3, 4, 5, 6, 7, \ | ||
24 | CEPHFS_FEATURE_MIMIC, \ | ||
25 | } | ||
26 | |||
27 | #define CEPHFS_FEATURES_CLIENT_SUPPORTED CEPHFS_FEATURES_ALL | ||
28 | #define CEPHFS_FEATURES_CLIENT_REQUIRED {} | ||
29 | |||
30 | |||
19 | /* | 31 | /* |
20 | * Some lock dependencies: | 32 | * Some lock dependencies: |
21 | * | 33 | * |