ceph: update support for PGID64, PGPOOL3, OSDENC protocol features
[deliverable/linux.git] / net / ceph / osdmap.c
index 81118db5bd11955659aff7e9527ca75f7e0e6539..911919320d2e1a7bf561e52648ba0c6ee0c7a8d0 100644 (file)
@@ -45,13 +45,8 @@ static int calc_bits_of(unsigned int t)
  */
 static void calc_pg_masks(struct ceph_pg_pool_info *pi)
 {
-       pi->pg_num_mask = (1 << calc_bits_of(le32_to_cpu(pi->v.pg_num)-1)) - 1;
-       pi->pgp_num_mask =
-               (1 << calc_bits_of(le32_to_cpu(pi->v.pgp_num)-1)) - 1;
-       pi->lpg_num_mask =
-               (1 << calc_bits_of(le32_to_cpu(pi->v.lpg_num)-1)) - 1;
-       pi->lpgp_num_mask =
-               (1 << calc_bits_of(le32_to_cpu(pi->v.lpgp_num)-1)) - 1;
+       pi->pg_num_mask = (1 << calc_bits_of(pi->pg_num-1)) - 1;
+       pi->pgp_num_mask = (1 << calc_bits_of(pi->pgp_num-1)) - 1;
 }
 
 /*
@@ -452,7 +447,7 @@ static int __insert_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *new)
        return 0;
 }
 
-static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id)
+static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, u64 id)
 {
        struct ceph_pg_pool_info *pi;
        struct rb_node *n = root->rb_node;
@@ -508,24 +503,57 @@ static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
 
 static int __decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi)
 {
-       unsigned int n, m;
+       u8 ev, cv;
+       unsigned len, num;
+       void *pool_end;
+
+       ceph_decode_need(p, end, 2 + 4, bad);
+       ev = ceph_decode_8(p);  /* encoding version */
+       cv = ceph_decode_8(p); /* compat version */
+       if (ev < 5) {
+               pr_warning("got v %d < 5 cv %d of ceph_pg_pool\n", ev, cv);
+               return -EINVAL;
+       }
+       if (cv > 7) {
+               pr_warning("got v %d cv %d > 7 of ceph_pg_pool\n", ev, cv);
+               return -EINVAL;
+       }
+       len = ceph_decode_32(p);
+       ceph_decode_need(p, end, len, bad);
+       pool_end = *p + len;
 
-       ceph_decode_copy(p, &pi->v, sizeof(pi->v));
-       calc_pg_masks(pi);
+       pi->type = ceph_decode_8(p);
+       pi->size = ceph_decode_8(p);
+       pi->crush_ruleset = ceph_decode_8(p);
+       pi->object_hash = ceph_decode_8(p);
 
-       /* num_snaps * snap_info_t */
-       n = le32_to_cpu(pi->v.num_snaps);
-       while (n--) {
-               ceph_decode_need(p, end, sizeof(u64) + 1 + sizeof(u64) +
-                                sizeof(struct ceph_timespec), bad);
-               *p += sizeof(u64) +       /* key */
-                       1 + sizeof(u64) + /* u8, snapid */
-                       sizeof(struct ceph_timespec);
-               m = ceph_decode_32(p);    /* snap name */
-               *p += m;
+       pi->pg_num = ceph_decode_32(p);
+       pi->pgp_num = ceph_decode_32(p);
+
+       *p += 4 + 4;  /* skip lpg* */
+       *p += 4;      /* skip last_change */
+       *p += 8 + 4;  /* skip snap_seq, snap_epoch */
+
+       /* skip snaps */
+       num = ceph_decode_32(p);
+       while (num--) {
+               *p += 8;  /* snapid key */
+               *p += 1 + 1; /* versions */
+               len = ceph_decode_32(p);
+               *p += len;
        }
 
-       *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2;
+       /* skip removed snaps */
+       num = ceph_decode_32(p);
+       *p += num * (8 + 8);
+
+       *p += 8;  /* skip auid */
+       pi->flags = ceph_decode_64(p);
+
+       /* ignore the rest */
+
+       *p = pool_end;
+       calc_pg_masks(pi);
        return 0;
 
 bad:
@@ -535,14 +563,15 @@ bad:
 static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
 {
        struct ceph_pg_pool_info *pi;
-       u32 num, len, pool;
+       u32 num, len;
+       u64 pool;
 
        ceph_decode_32_safe(p, end, num, bad);
        dout(" %d pool names\n", num);
        while (num--) {
-               ceph_decode_32_safe(p, end, pool, bad);
+               ceph_decode_64_safe(p, end, pool, bad);
                ceph_decode_32_safe(p, end, len, bad);
-               dout("  pool %d len %d\n", pool, len);
+               dout("  pool %llu len %d\n", pool, len);
                ceph_decode_need(p, end, len, bad);
                pi = __lookup_pg_pool(&map->pg_pools, pool);
                if (pi) {
@@ -633,7 +662,6 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
        struct ceph_osdmap *map;
        u16 version;
        u32 len, max, i;
-       u8 ev;
        int err = -EINVAL;
        void *start = *p;
        struct ceph_pg_pool_info *pi;
@@ -646,9 +674,12 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
        map->pg_temp = RB_ROOT;
 
        ceph_decode_16_safe(p, end, version, bad);
-       if (version > CEPH_OSDMAP_VERSION) {
-               pr_warning("got unknown v %d > %d of osdmap\n", version,
-                          CEPH_OSDMAP_VERSION);
+       if (version > 6) {
+               pr_warning("got unknown v %d > 6 of osdmap\n", version);
+               goto bad;
+       }
+       if (version < 6) {
+               pr_warning("got old v %d < 6 of osdmap\n", version);
                goto bad;
        }
 
@@ -660,20 +691,12 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
 
        ceph_decode_32_safe(p, end, max, bad);
        while (max--) {
-               ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
+               ceph_decode_need(p, end, 8 + 2, bad);
                err = -ENOMEM;
                pi = kzalloc(sizeof(*pi), GFP_NOFS);
                if (!pi)
                        goto bad;
-               pi->id = ceph_decode_32(p);
-               err = -EINVAL;
-               ev = ceph_decode_8(p); /* encoding version */
-               if (ev > CEPH_PG_POOL_VERSION) {
-                       pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
-                                  ev, CEPH_PG_POOL_VERSION);
-                       kfree(pi);
-                       goto bad;
-               }
+               pi->id = ceph_decode_64(p);
                err = __decode_pool(p, end, pi);
                if (err < 0) {
                        kfree(pi);
@@ -682,12 +705,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
                __insert_pg_pool(&map->pg_pools, pi);
        }
 
-       if (version >= 5) {
-               err = __decode_pool_names(p, end, map);
-               if (err < 0) {
-                       dout("fail to decode pool names");
-                       goto bad;
-               }
+       err = __decode_pool_names(p, end, map);
+       if (err < 0) {
+               dout("fail to decode pool names");
+               goto bad;
        }
 
        ceph_decode_32_safe(p, end, map->pool_max, bad);
@@ -788,16 +809,17 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        struct ceph_fsid fsid;
        u32 epoch = 0;
        struct ceph_timespec modified;
-       u32 len, pool;
-       __s32 new_pool_max, new_flags, max;
+       s32 len;
+       u64 pool;
+       __s64 new_pool_max;
+       __s32 new_flags, max;
        void *start = *p;
        int err = -EINVAL;
        u16 version;
 
        ceph_decode_16_safe(p, end, version, bad);
-       if (version > CEPH_OSDMAP_INC_VERSION) {
-               pr_warning("got unknown v %d > %d of inc osdmap\n", version,
-                          CEPH_OSDMAP_INC_VERSION);
+       if (version > 6) {
+               pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6);
                goto bad;
        }
 
@@ -807,7 +829,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        epoch = ceph_decode_32(p);
        BUG_ON(epoch != map->epoch+1);
        ceph_decode_copy(p, &modified, sizeof(modified));
-       new_pool_max = ceph_decode_32(p);
+       new_pool_max = ceph_decode_64(p);
        new_flags = ceph_decode_32(p);
 
        /* full map? */
@@ -857,18 +879,9 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        /* new_pool */
        ceph_decode_32_safe(p, end, len, bad);
        while (len--) {
-               __u8 ev;
                struct ceph_pg_pool_info *pi;
 
-               ceph_decode_32_safe(p, end, pool, bad);
-               ceph_decode_need(p, end, 1 + sizeof(pi->v), bad);
-               ev = ceph_decode_8(p);  /* encoding version */
-               if (ev > CEPH_PG_POOL_VERSION) {
-                       pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
-                                  ev, CEPH_PG_POOL_VERSION);
-                       err = -EINVAL;
-                       goto bad;
-               }
+               ceph_decode_64_safe(p, end, pool, bad);
                pi = __lookup_pg_pool(&map->pg_pools, pool);
                if (!pi) {
                        pi = kzalloc(sizeof(*pi), GFP_NOFS);
@@ -894,7 +907,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
        while (len--) {
                struct ceph_pg_pool_info *pi;
 
-               ceph_decode_32_safe(p, end, pool, bad);
+               ceph_decode_64_safe(p, end, pool, bad);
                pi = __lookup_pg_pool(&map->pg_pools, pool);
                if (pi)
                        __remove_pg_pool(&map->pg_pools, pi);
@@ -1097,8 +1110,8 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol,
        pool = __lookup_pg_pool(&osdmap->pg_pools, pgid.pool);
        if (!pool)
                return -EIO;
-       pgid.seed = ceph_str_hash(pool->v.object_hash, oid, strlen(oid));
-       num = le32_to_cpu(pool->v.pg_num);
+       pgid.seed = ceph_str_hash(pool->object_hash, oid, strlen(oid));
+       num = pool->pg_num;
        num_mask = pool->pg_num_mask;
 
        dout("calc_object_layout '%s' pgid %lld.%x\n", oid, pgid.pool,
@@ -1132,8 +1145,7 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
                return NULL;
 
        /* pg_temp? */
-       t = ceph_stable_mod(ps, le32_to_cpu(pool->v.pg_num),
-                           pool->pgp_num_mask);
+       t = ceph_stable_mod(ps, pool->pg_num, pool->pgp_num_mask);
        pgid.seed = t;
        pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
        if (pg) {
@@ -1142,26 +1154,24 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
        }
 
        /* crush */
-       ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset,
-                                pool->v.type, pool->v.size);
+       ruleno = crush_find_rule(osdmap->crush, pool->crush_ruleset,
+                                pool->type, pool->size);
        if (ruleno < 0) {
                pr_err("no crush rule pool %d ruleset %d type %d size %d\n",
-                      poolid, pool->v.crush_ruleset, pool->v.type,
-                      pool->v.size);
+                      poolid, pool->crush_ruleset, pool->type,
+                      pool->size);
                return NULL;
        }
 
-       pps = ceph_stable_mod(ps,
-                             le32_to_cpu(pool->v.pgp_num),
-                             pool->pgp_num_mask);
+       pps = ceph_stable_mod(ps, pool->pgp_num, pool->pgp_num_mask);
        pps += poolid;
        r = crush_do_rule(osdmap->crush, ruleno, pps, osds,
-                         min_t(int, pool->v.size, *num),
+                         min_t(int, pool->size, *num),
                          osdmap->osd_weight);
        if (r < 0) {
                pr_err("error %d from crush rule: pool %d ruleset %d type %d"
-                      " size %d\n", r, poolid, pool->v.crush_ruleset,
-                      pool->v.type, pool->v.size);
+                      " size %d\n", r, poolid, pool->crush_ruleset,
+                      pool->type, pool->size);
                return NULL;
        }
        *num = r;
This page took 0.042954 seconds and 5 git commands to generate.