diff mbox

libceph: fix decoding of pgids

Message ID 1362608124-7567-1-git-send-email-sage@inktank.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sage Weil March 6, 2013, 10:15 p.m. UTC
In 4f6a7e5ee1393ec4b243b39dac9f36992d161540 we effectively dropped support
for the legacy encoding for the OSDMap and incremental.  However, we didn't
fix the decoding for the pgid.

Signed-off-by: Sage Weil <sage@inktank.com>
---
 net/ceph/osdmap.c |   40 +++++++++++++++++++++++++++-------------
 1 file changed, 27 insertions(+), 13 deletions(-)

Comments

Yehuda Sadeh March 6, 2013, 10:48 p.m. UTC | #1
On Wed, Mar 6, 2013 at 2:15 PM, Sage Weil <sage@inktank.com> wrote:
> In 4f6a7e5ee1393ec4b243b39dac9f36992d161540 we effectively dropped support
> for the legacy encoding for the OSDMap and incremental.  However, we didn't
> fix the decoding for the pgid.
>
> Signed-off-by: Sage Weil <sage@inktank.com>
> ---
>  net/ceph/osdmap.c |   40 +++++++++++++++++++++++++++-------------
>  1 file changed, 27 insertions(+), 13 deletions(-)
>
> diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
> index a47ee06..6975102 100644
> --- a/net/ceph/osdmap.c
> +++ b/net/ceph/osdmap.c
> @@ -654,6 +654,24 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
>         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.
>   */
> @@ -745,13 +763,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
>         for (i = 0; i < len; i++) {
>                 int n, j;
>                 struct ceph_pg pgid;
> -               struct ceph_pg_v1 pgid_v1;
>                 struct ceph_pg_mapping *pg;
>
> -               ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
> -               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
> -               pgid.pool = le32_to_cpu(pgid_v1.pool);
> -               pgid.seed = le16_to_cpu(pgid_v1.ps);
> +               err = __decode_pgid(p, end, &pgid);
> +               if (err)
> +                       goto bad;
>                 n = ceph_decode_32(p);
>                 err = -EINVAL;
>                 if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
> @@ -818,8 +834,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
>         u16 version;
>
>         ceph_decode_16_safe(p, end, version, bad);
> -       if (version > 6) {
> -               pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6);
> +       if (version != 6) {
> +               pr_warning("got unknown v %d != 6 of inc osdmap\n", version);
>                 goto bad;
>         }
>
> @@ -963,15 +979,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
>         while (len--) {
>                 struct ceph_pg_mapping *pg;
>                 int j;
> -               struct ceph_pg_v1 pgid_v1;
>                 struct ceph_pg pgid;
>                 u32 pglen;
> -               ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
> -               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
> -               pgid.pool = le32_to_cpu(pgid_v1.pool);
> -               pgid.seed = le16_to_cpu(pgid_v1.ps);
> -               pglen = ceph_decode_32(p);
>
> +               err = __decode_pgid(p, end, &pgid);
> +               if (err)
> +                       goto bad;

maybe missing?

ceph_decode_need(p, end, sizeof(u32), bad);

> +               pglen = ceph_decode_32(p);
>                 if (pglen) {
>                         ceph_decode_need(p, end, pglen*sizeof(u32), bad);
>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sage Weil March 6, 2013, 10:58 p.m. UTC | #2
On Wed, 6 Mar 2013, Yehuda Sadeh wrote:
> On Wed, Mar 6, 2013 at 2:15 PM, Sage Weil <sage@inktank.com> wrote:
> > In 4f6a7e5ee1393ec4b243b39dac9f36992d161540 we effectively dropped support
> > for the legacy encoding for the OSDMap and incremental.  However, we didn't
> > fix the decoding for the pgid.
> >
> > Signed-off-by: Sage Weil <sage@inktank.com>
> > ---
> >  net/ceph/osdmap.c |   40 +++++++++++++++++++++++++++-------------
> >  1 file changed, 27 insertions(+), 13 deletions(-)
> >
> > diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
> > index a47ee06..6975102 100644
> > --- a/net/ceph/osdmap.c
> > +++ b/net/ceph/osdmap.c
> > @@ -654,6 +654,24 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
> >         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.
> >   */
> > @@ -745,13 +763,11 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
> >         for (i = 0; i < len; i++) {
> >                 int n, j;
> >                 struct ceph_pg pgid;
> > -               struct ceph_pg_v1 pgid_v1;
> >                 struct ceph_pg_mapping *pg;
> >
> > -               ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
> > -               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
> > -               pgid.pool = le32_to_cpu(pgid_v1.pool);
> > -               pgid.seed = le16_to_cpu(pgid_v1.ps);
> > +               err = __decode_pgid(p, end, &pgid);
> > +               if (err)
> > +                       goto bad;
> >                 n = ceph_decode_32(p);
> >                 err = -EINVAL;
> >                 if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
> > @@ -818,8 +834,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
> >         u16 version;
> >
> >         ceph_decode_16_safe(p, end, version, bad);
> > -       if (version > 6) {
> > -               pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6);
> > +       if (version != 6) {
> > +               pr_warning("got unknown v %d != 6 of inc osdmap\n", version);
> >                 goto bad;
> >         }
> >
> > @@ -963,15 +979,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
> >         while (len--) {
> >                 struct ceph_pg_mapping *pg;
> >                 int j;
> > -               struct ceph_pg_v1 pgid_v1;
> >                 struct ceph_pg pgid;
> >                 u32 pglen;
> > -               ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
> > -               ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
> > -               pgid.pool = le32_to_cpu(pgid_v1.pool);
> > -               pgid.seed = le16_to_cpu(pgid_v1.ps);
> > -               pglen = ceph_decode_32(p);
> >
> > +               err = __decode_pgid(p, end, &pgid);
> > +               if (err)
> > +                       goto bad;
> 
> maybe missing?
> 
> ceph_decode_need(p, end, sizeof(u32), bad);

Yup, for both call sites.  Pushed updated patch to testing.

Thanks!
sage


> 
> > +               pglen = ceph_decode_32(p);
> >                 if (pglen) {
> >                         ceph_decode_need(p, end, pglen*sizeof(u32), bad);
> >
> > --
> > 1.7.9.5
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index a47ee06..6975102 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -654,6 +654,24 @@  static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
 	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.
  */
@@ -745,13 +763,11 @@  struct ceph_osdmap *osdmap_decode(void **p, void *end)
 	for (i = 0; i < len; i++) {
 		int n, j;
 		struct ceph_pg pgid;
-		struct ceph_pg_v1 pgid_v1;
 		struct ceph_pg_mapping *pg;
 
-		ceph_decode_need(p, end, sizeof(u32) + sizeof(u64), bad);
-		ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
-		pgid.pool = le32_to_cpu(pgid_v1.pool);
-		pgid.seed = le16_to_cpu(pgid_v1.ps);
+		err = __decode_pgid(p, end, &pgid);
+		if (err)
+			goto bad;
 		n = ceph_decode_32(p);
 		err = -EINVAL;
 		if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
@@ -818,8 +834,8 @@  struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
 	u16 version;
 
 	ceph_decode_16_safe(p, end, version, bad);
-	if (version > 6) {
-		pr_warning("got unknown v %d > %d of inc osdmap\n", version, 6);
+	if (version != 6) {
+		pr_warning("got unknown v %d != 6 of inc osdmap\n", version);
 		goto bad;
 	}
 
@@ -963,15 +979,13 @@  struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
 	while (len--) {
 		struct ceph_pg_mapping *pg;
 		int j;
-		struct ceph_pg_v1 pgid_v1;
 		struct ceph_pg pgid;
 		u32 pglen;
-		ceph_decode_need(p, end, sizeof(u64) + sizeof(u32), bad);
-		ceph_decode_copy(p, &pgid_v1, sizeof(pgid_v1));
-		pgid.pool = le32_to_cpu(pgid_v1.pool);
-		pgid.seed = le16_to_cpu(pgid_v1.ps);
-		pglen = ceph_decode_32(p);
 
+		err = __decode_pgid(p, end, &pgid);
+		if (err)
+			goto bad;
+		pglen = ceph_decode_32(p);
 		if (pglen) {
 			ceph_decode_need(p, end, pglen*sizeof(u32), bad);