ceph: CEPH_FEATURE_MDSENC support
authorYan, Zheng <zyan@redhat.com>
Thu, 31 Mar 2016 07:53:01 +0000 (15:53 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Wed, 25 May 2016 23:15:31 +0000 (01:15 +0200)
Signed-off-by: Yan, Zheng <zyan@redhat.com>
fs/ceph/mdsmap.c
fs/ceph/super.c

index 261531e..8c3591a 100644 (file)
@@ -54,16 +54,21 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
        const void *start = *p;
        int i, j, n;
        int err = -EINVAL;
-       u16 version;
+       u8 mdsmap_v, mdsmap_cv;
 
        m = kzalloc(sizeof(*m), GFP_NOFS);
        if (m == NULL)
                return ERR_PTR(-ENOMEM);
 
-       ceph_decode_16_safe(p, end, version, bad);
-       if (version > 3) {
-               pr_warn("got mdsmap version %d > 3, failing", version);
-               goto bad;
+       ceph_decode_need(p, end, 1 + 1, bad);
+       mdsmap_v = ceph_decode_8(p);
+       mdsmap_cv = ceph_decode_8(p);
+       if (mdsmap_v >= 4) {
+              u32 mdsmap_len;
+              ceph_decode_32_safe(p, end, mdsmap_len, bad);
+              if (end < *p + mdsmap_len)
+                      goto bad;
+              end = *p + mdsmap_len;
        }
 
        ceph_decode_need(p, end, 8*sizeof(u32) + sizeof(u64), bad);
@@ -87,16 +92,29 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                u32 namelen;
                s32 mds, inc, state;
                u64 state_seq;
-               u8 infoversion;
+               u8 info_v;
+               void *info_end = NULL;
                struct ceph_entity_addr addr;
                u32 num_export_targets;
                void *pexport_targets = NULL;
                struct ceph_timespec laggy_since;
                struct ceph_mds_info *info;
 
-               ceph_decode_need(p, end, sizeof(u64)*2 + 1 + sizeof(u32), bad);
+               ceph_decode_need(p, end, sizeof(u64) + 1, bad);
                global_id = ceph_decode_64(p);
-               infoversion = ceph_decode_8(p);
+               info_v= ceph_decode_8(p);
+               if (info_v >= 4) {
+                       u32 info_len;
+                       u8 info_cv;
+                       ceph_decode_need(p, end, 1 + sizeof(u32), bad);
+                       info_cv = ceph_decode_8(p);
+                       info_len = ceph_decode_32(p);
+                       info_end = *p + info_len;
+                       if (info_end > end)
+                               goto bad;
+               }
+
+               ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
                *p += sizeof(u64);
                namelen = ceph_decode_32(p);  /* skip mds name */
                *p += namelen;
@@ -115,7 +133,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                *p += sizeof(u32);
                ceph_decode_32_safe(p, end, namelen, bad);
                *p += namelen;
-               if (infoversion >= 2) {
+               if (info_v >= 2) {
                        ceph_decode_32_safe(p, end, num_export_targets, bad);
                        pexport_targets = *p;
                        *p += num_export_targets * sizeof(u32);
@@ -123,6 +141,12 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                        num_export_targets = 0;
                }
 
+               if (info_end && *p != info_end) {
+                       if (*p > info_end)
+                               goto bad;
+                       *p = info_end;
+               }
+
                dout("mdsmap_decode %d/%d %lld mds%d.%d %s %s\n",
                     i+1, n, global_id, mds, inc,
                     ceph_pr_addr(&addr.in_addr),
@@ -163,6 +187,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
        m->m_cas_pg_pool = ceph_decode_64(p);
 
        /* ok, we don't care about the rest. */
+       *p = end;
        dout("mdsmap_decode success epoch %u\n", m->m_epoch);
        return m;
 
index 452770d..d714ab2 100644 (file)
@@ -519,9 +519,8 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
 {
        struct ceph_fs_client *fsc;
        const u64 supported_features =
-               CEPH_FEATURE_FLOCK |
-               CEPH_FEATURE_DIRLAYOUTHASH |
-               CEPH_FEATURE_MDS_INLINE_DATA;
+               CEPH_FEATURE_FLOCK | CEPH_FEATURE_DIRLAYOUTHASH |
+               CEPH_FEATURE_MDSENC | CEPH_FEATURE_MDS_INLINE_DATA;
        const u64 required_features = 0;
        int page_count;
        size_t size;