#include <linux/rbtree.h>
 #include <linux/ceph/types.h>
+#include <linux/ceph/decode.h>
 #include <linux/ceph/ceph_fs.h>
 #include <linux/crush/crush.h>
 
        return &map->osd_addr[osd];
 }
 
+static inline int ceph_decode_pgid(void **p, void *end, struct ceph_pg *pgid)
+{
+       __u8 version;
+
+       if (!ceph_has_room(p, end, 1 + 8 + 4 + 4)) {
+               pr_warning("incomplete pg encoding");
+
+               return -EINVAL;
+       }
+       version = ceph_decode_8(p);
+       if (version > 1) {
+               pr_warning("do not understand pg encoding %d > 1",
+                       (int)version);
+               return -EINVAL;
+       }
+
+       pgid->pool = ceph_decode_64(p);
+       pgid->seed = ceph_decode_32(p);
+       *p += 4;        /* skip deprecated preferred value */
+
+       return 0;
+}
+
 extern struct ceph_osdmap *osdmap_decode(void **p, void *end);
 extern struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
                                            struct ceph_osdmap *map,
 
        complete_all(&req->r_safe_completion);  /* fsync waiter */
 }
 
-static int __decode_pgid(void **p, void *end, struct ceph_pg *pgid)
-{
-       __u8 v;
-
-       ceph_decode_need(p, end, 1 + 8 + 4 + 4, bad);
-       v = ceph_decode_8(p);
-       if (v > 1) {
-               pr_warning("do not understand pg encoding %d > 1", v);
-               return -EINVAL;
-       }
-       pgid->pool = ceph_decode_64(p);
-       pgid->seed = ceph_decode_32(p);
-       *p += 4;
-       return 0;
-
-bad:
-       pr_warning("incomplete pg encoding");
-       return -EINVAL;
-}
-
 /*
  * handle osd op reply.  either call the callback if it is specified,
  * or do the completion to wake up the waiting thread.
        ceph_decode_need(&p, end, object_len, bad);
        p += object_len;
 
-       err = __decode_pgid(&p, end, &pg);
+       err = ceph_decode_pgid(&p, end, &pg);
        if (err)
                goto bad;
 
 
        return 0;
 }
 
-static int __decode_pgid(void **p, void *end, struct ceph_pg *pg)
-{
-       u8 v;
-
-       ceph_decode_need(p, end, 1+8+4+4, bad);
-       v = ceph_decode_8(p);
-       if (v != 1)
-               goto bad;
-       pg->pool = ceph_decode_64(p);
-       pg->seed = ceph_decode_32(p);
-       *p += 4; /* skip preferred */
-       return 0;
-
-bad:
-       dout("error decoding pgid\n");
-       return -EINVAL;
-}
-
 /*
  * decode a full map.
  */
                struct ceph_pg pgid;
                struct ceph_pg_mapping *pg;
 
-               err = __decode_pgid(p, end, &pgid);
+               err = ceph_decode_pgid(p, end, &pgid);
                if (err)
                        goto bad;
                ceph_decode_need(p, end, sizeof(u32), bad);
                struct ceph_pg pgid;
                u32 pglen;
 
-               err = __decode_pgid(p, end, &pgid);
+               err = ceph_decode_pgid(p, end, &pgid);
                if (err)
                        goto bad;
                ceph_decode_need(p, end, sizeof(u32), bad);