svn commit: r283104 - head/sys/geom/uncompress

Adrian Chadd adrian at freebsd.org
Tue May 19 17:36:35 UTC 2015


Hi,

How big are the images you were using?

Did you try on the smaller footprint boards (eg things with < 128MB
RAM) to see if it changed behaviour?


-a


On 19 May 2015 at 02:28, Andrey V. Elsukov <ae at freebsd.org> wrote:
> Author: ae
> Date: Tue May 19 09:28:52 2015
> New Revision: 283104
> URL: https://svnweb.freebsd.org/changeset/base/283104
>
> Log:
>   Read GEOM_UNCOMPRESS metadata using several requests that fit into
>   MAXPHYS. For large compressed images the metadata size can be bigger
>   than MAXPHYS and this triggers KASSERT in g_read_data().
>   Also use g_free() to free memory allocated by g_read_data().
>
>   PR:           199476
>   MFC after:    2 weeks
>
> Modified:
>   head/sys/geom/uncompress/g_uncompress.c
>
> Modified: head/sys/geom/uncompress/g_uncompress.c
> ==============================================================================
> --- head/sys/geom/uncompress/g_uncompress.c     Tue May 19 09:22:06 2015        (r283103)
> +++ head/sys/geom/uncompress/g_uncompress.c     Tue May 19 09:28:52 2015        (r283104)
> @@ -464,7 +464,8 @@ g_uncompress_taste(struct g_class *mp, s
>         struct g_provider *pp2;
>         struct g_consumer *cp;
>         struct g_geom *gp;
> -       uint32_t i, total_offsets, type;
> +       uint64_t *offsets;
> +       uint32_t i, r, total, total_offsets, type;
>         uint8_t *buf;
>         int error;
>
> @@ -499,8 +500,8 @@ g_uncompress_taste(struct g_class *mp, s
>          */
>         DPRINTF(("%s: media sectorsize %u, mediasize %jd\n",
>             gp->name, pp->sectorsize, (intmax_t)pp->mediasize));
> -       i = roundup(sizeof(struct cloop_header), pp->sectorsize);
> -       buf = g_read_data(cp, 0, i, NULL);
> +       total = roundup(sizeof(struct cloop_header), pp->sectorsize);
> +       buf = g_read_data(cp, 0, total, NULL);
>         if (buf == NULL)
>                 goto err;
>         header = (struct cloop_header *) buf;
> @@ -557,20 +558,29 @@ g_uncompress_taste(struct g_class *mp, s
>                     gp->name, sc->nblocks);
>                 goto err;
>         }
> -       free(buf, M_GEOM);
> +       g_free(buf);
>
> -       i = roundup((sizeof(struct cloop_header) +
> -           total_offsets * sizeof(uint64_t)), pp->sectorsize);
> -       buf = g_read_data(cp, 0, i, NULL);
> -       if (buf == NULL)
> -               goto err;
>         sc->offsets = malloc(total_offsets * sizeof(uint64_t),
> -           M_GEOM_UNCOMPRESS, M_WAITOK);
> -       for (i = 0; i <= total_offsets; i++) {
> -               sc->offsets[i] = be64toh(((uint64_t *)
> -                   (buf+sizeof(struct cloop_header)))[i]);
> +           M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
> +       total = roundup((sizeof(struct cloop_header) +
> +           total_offsets * sizeof(uint64_t)), pp->sectorsize);
> +#define        RSZ     ((total - r) > MAXPHYS ? MAXPHYS: (total - r))
> +       for (r = 0, i = 0; r < total; r += MAXPHYS) {
> +               buf = g_read_data(cp, r, RSZ, &error);
> +               if (buf == NULL) {
> +                       free(sc->offsets, M_GEOM_UNCOMPRESS);
> +                       goto err;
> +               }
> +               offsets = (uint64_t *)buf;
> +               if (r == 0)
> +                       offsets +=
> +                           sizeof(struct cloop_header) / sizeof(uint64_t);
> +               for (; i < total_offsets && offsets < (uint64_t *)(buf + RSZ);
> +                   i++, offsets++)
> +                       sc->offsets[i] = be64toh(*offsets);
> +               g_free(buf);
>         }
> -       free(buf, M_GEOM);
> +#undef RSZ
>         buf = NULL;
>         DPRINTF(("%s: done reading offsets\n", gp->name));
>         mtx_init(&sc->last_mtx, "geom_uncompress cache", NULL, MTX_DEF);
> @@ -619,7 +629,7 @@ err:
>         g_topology_lock();
>         g_access(cp, -1, 0, 0);
>         if (buf != NULL)
> -               free(buf, M_GEOM);
> +               g_free(buf);
>         if (gp->softc != NULL) {
>                 g_uncompress_softc_free(gp->softc, NULL);
>                 gp->softc = NULL;
>


More information about the svn-src-all mailing list