Hi,

I've the attached changes to geom_uncompress(4) that modularise the
compression support.

It can now be built with support to mkuzip(8) or mkulzma(8) (or both)
independently.

It also make a lot easier to add the support to new compression
methods on geom_uncompress.

Now, building a kernel with 'options GEOM_UNCOMPRESS' (kept for
backward compatibility) adds only the support to read mkulzma images.

Building a kernel with 'options GEOM_UNCOMPRESS_UZIP' will add the
support to read mkuzip images.

The both options can be combined and they will produce a kernel which
can read both formats.

The geom_uncompress module is built with both compression methods
enabled keeping the backward compatibility.

I think we could eventually retire geom_uzip(8) as they are doing
essentially the same thing (with the same implementation and code...).
But this lets a lot of open questions regarding backward
compatibility.

Regards,
Luiz
Index: sys/conf/files
===================================================================
--- sys/conf/files      (revision 265013)
+++ sys/conf/files      (working copy)
@@ -2742,7 +2742,9 @@
 geom/raid3/g_raid3_ctl.c       optional geom_raid3
 geom/shsec/g_shsec.c           optional geom_shsec
 geom/stripe/g_stripe.c         optional geom_stripe
-geom/uncompress/g_uncompress.c optional geom_uncompress
+geom/uncompress/g_uncompress.c optional geom_uncompress | geom_uncompress_uzip
+geom/uncompress/g_uncompress_ulzma.c   optional geom_uncompress
+geom/uncompress/g_uncompress_uzip.c    optional geom_uncompress_uzip
 contrib/xz-embedded/freebsd/xz_malloc.c        \
        optional xz_embedded | geom_uncompress \
        compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ 
-I$S/contrib/xz-embedded/linux/lib/xz/ 
-I$S/contrib/xz-embedded/linux/include/linux/"
@@ -3139,7 +3141,7 @@
 net/vnet.c                     optional vimage
 net/zlib.c                     optional crypto | geom_uzip | ipsec | \
                                         mxge | netgraph_deflate | \
-                                        ddb_ctf | gzio | geom_uncompress
+                                        ddb_ctf | gzio | geom_uncompress_uzip
 net80211/ieee80211.c           optional wlan
 net80211/ieee80211_acl.c       optional wlan wlan_acl
 net80211/ieee80211_action.c    optional wlan
Index: sys/conf/options
===================================================================
--- sys/conf/options    (revision 265013)
+++ sys/conf/options    (working copy)
@@ -124,6 +124,7 @@
 GEOM_STRIPE    opt_geom.h
 GEOM_SUNLABEL  opt_geom.h
 GEOM_UNCOMPRESS        opt_geom.h
+GEOM_UNCOMPRESS_UZIP   opt_geom.h
 GEOM_UZIP      opt_geom.h
 GEOM_VIRSTOR   opt_geom.h
 GEOM_VOL       opt_geom.h
Index: sys/geom/uncompress/g_uncompress.c
===================================================================
--- sys/geom/uncompress/g_uncompress.c  (revision 265013)
+++ sys/geom/uncompress/g_uncompress.c  (working copy)
@@ -27,15 +27,19 @@
 
 /*
  * GEOM UNCOMPRESS module - simple decompression module for use with read-only
- * copressed images maked by mkuzip(8) or mkulzma(8) utilities.
+ * compressed images created by mkuzip(8) or mkulzma(8) utilities.
  *
- * To enable module in kernel config, put this line:
- * device      geom_uncompress
+ * To enable uncompress support in kernel config, add these lines (for ulzma
+ * and uzip support respectively):
+ * options     geom_uncompress
+ * options     geom_uncompress_uzip
  */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_geom.h"
+
 #include <sys/param.h>
 #include <sys/bio.h>
 #include <sys/endian.h>
@@ -47,10 +51,8 @@
 #include <sys/systm.h>
 
 #include <geom/geom.h>
+#include <geom/uncompress/g_uncompress.h>
 
-#include <net/zlib.h>
-#include <contrib/xz-embedded/linux/include/linux/xz.h>
-
 #ifdef GEOM_UNCOMPRESS_DEBUG
 #define        DPRINTF(a)      printf a
 extern int g_debugflags;
@@ -58,12 +60,10 @@
 #define        DPRINTF(a)
 #endif
 
-static MALLOC_DEFINE(M_GEOM_UNCOMPRESS, "geom_uncompress",
+MALLOC_DEFINE(M_GEOM_UNCOMPRESS, "geom_uncompress",
     "GEOM UNCOMPRESS data structures");
 
 #define        UNCOMPRESS_CLASS_NAME   "UNCOMPRESS"
-#define        GEOM_UZIP_MAJVER '2'
-#define        GEOM_ULZMA_MAJVER '3'
 
 /*
  * Maximum allowed valid block size (to prevent foot-shooting)
@@ -71,28 +71,17 @@
 #define        MAX_BLKSZ       (MAXPHYS)
 
 /*
- * Integer values (block size, number of blocks, offsets)
- * are stored in big-endian (network) order on disk and struct cloop_header
- * and in native order in struct g_uncompress_softc
+ * Integer values (block size, number of blocks, offsets) are stored in native
+ * order in struct g_uncompress_softc.
  */
 
-#define        CLOOP_MAGIC_LEN 128
 static char CLOOP_MAGIC_START[] = "#!/bin/sh\n";
 
-struct cloop_header {
-       char magic[CLOOP_MAGIC_LEN];    /* cloop magic */
-       uint32_t blksz;                 /* block size */
-       uint32_t nblocks;               /* number of blocks */
-};
-
 struct g_uncompress_softc {
        uint32_t blksz;                 /* block size */
        uint32_t nblocks;               /* number of blocks */
        uint64_t *offsets;
-       enum {
-               GEOM_UZIP = 1,
-               GEOM_ULZMA
-       } type;
+       int type;
 
        struct mtx last_mtx;
        uint32_t last_blk;              /* last blk no */
@@ -99,11 +88,16 @@
        char *last_buf;                 /* last blk data */
        int req_total;                  /* total requests */
        int req_cached;                 /* cached requests */
+};
 
-       /* XZ decoder structs */
-       struct xz_buf *b;
-       struct xz_dec *s;
-       z_stream *zs;
+static struct g_uncompress_desc *g_uncompress[] = {
+#ifdef GEOM_UNCOMPRESS
+       &g_uncompress_ulzma,
+#endif
+#ifdef GEOM_UNCOMPRESS_UZIP
+       &g_uncompress_uzip,
+#endif
+       NULL
 };
 
 static void
@@ -119,25 +113,8 @@
                sc->offsets = 0;
        }
 
-       switch (sc->type) {
-       case GEOM_ULZMA:
-               if (sc->b) {
-                       free(sc->b, M_GEOM_UNCOMPRESS);
-                       sc->b = 0;
-               }
-               if (sc->s) {
-                       xz_dec_end(sc->s);
-                       sc->s = 0;
-               }
-               break;
-       case GEOM_UZIP:
-               if (sc->zs) {
-                       inflateEnd(sc->zs);
-                       free(sc->zs, M_GEOM_UNCOMPRESS);
-                       sc->zs = 0;
-               }
-               break;
-       }
+       /* Call the free method. */
+       g_uncompress[sc->type]->d_free(g_uncompress[sc->type]);
 
        mtx_destroy(&sc->last_mtx);
        free(sc->last_buf, M_GEOM_UNCOMPRESS);
@@ -144,23 +121,7 @@
        free(sc, M_GEOM_UNCOMPRESS);
 }
 
-static void *
-z_alloc(void *nil, u_int type, u_int size)
-{
-       void *ptr;
-
-       ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
-       return (ptr);
-}
-
 static void
-z_free(void *nil, void *ptr)
-{
-
-       free(ptr, M_GEOM_UNCOMPRESS);
-}
-
-static void
 g_uncompress_done(struct bio *bp)
 {
        struct g_uncompress_softc *sc;
@@ -254,33 +215,9 @@
                        hexdump(bp->bio_data + pos, dlen, 0, 0);
 #endif
 
-               switch (sc->type) {
-               case GEOM_ULZMA:
-                       sc->b->in = bp->bio_data + pos;
-                       sc->b->out = sc->last_buf;
-                       sc->b->in_pos = sc->b->out_pos = 0;
-                       sc->b->in_size = dlen;
-                       sc->b->out_size = (size_t)-1;
-
-                       err = (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END) ?
-                           1 : 0;
-                       /* TODO decoder recovery, if needed */
-                       break;
-               case GEOM_UZIP:
-                       sc->zs->next_in = bp->bio_data + pos;
-                       sc->zs->avail_in = dlen;
-                       sc->zs->next_out = sc->last_buf;
-                       sc->zs->avail_out = sc->blksz;
-
-                       err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ?
-                           1 : 0;
-                       if ((err) || (inflateReset(sc->zs) != Z_OK))
-                               printf("%s: UZIP decoder reset failed\n",
-                                    gp->name);
-                       break;
-               }
-
-               if (err) {
+               if (g_uncompress[sc->type]->d_decom(g_uncompress[sc->type],
+                   gp->name, bp->bio_data + pos, len, sc->last_buf,
+                   sc->blksz) != 0) {
                        sc->last_blk = -1;
                        mtx_unlock(&sc->last_mtx);
                        DPRINTF(("%s: done: inflate failed, code=%d\n",
@@ -291,7 +228,7 @@
 
 #ifdef GEOM_UNCOMPRESS_DEBUG
                if (g_debugflags & 32)
-                       hexdump(sc->last_buf, sc->b->out_size, 0, 0);
+                       hexdump(sc->last_buf, sc->blksz, 0, 0);
 #endif
 
                sc->last_blk = i;
@@ -521,24 +458,16 @@
                goto err;
        }
 
-       switch (header->magic[0x0b]) {
-       case 'L':
-               type = GEOM_ULZMA;
-               if (header->magic[0x0c] < GEOM_ULZMA_MAJVER) {
-                       DPRINTF(("%s: image version too old\n", gp->name));
+       for (i = 0; g_uncompress[i] != NULL; i++) {
+               error = g_uncompress[i]->d_taste(header, gp->name);
+               if (error == 1) {
+                       /* Match. */
+                       type = i;
+                       break;
+               } else if (error == -1)
                        goto err;
-               }
-               printf("%s: GEOM_ULZMA image found\n", gp->name);
-               break;
-       case 'V':
-               type = GEOM_UZIP;
-               if (header->magic[0x0c] < GEOM_UZIP_MAJVER) {
-                       DPRINTF(("%s: image version too old\n", gp->name));
-                       goto err;
-               }
-               printf("%s: GEOM_UZIP image found\n", gp->name);
-               break;
-       default:
+       }
+       if (g_uncompress[i] == NULL) {
                DPRINTF(("%s: unsupported image type\n", gp->name));
                goto err;
        }
@@ -588,23 +517,9 @@
        sc->req_total = 0;
        sc->req_cached = 0;
 
-       switch (sc->type) {
-       case GEOM_ULZMA:
-               xz_crc32_init();
-               sc->s = xz_dec_init(XZ_SINGLE, 0);
-               sc->b = (struct xz_buf*)malloc(sizeof(struct xz_buf),
-                   M_GEOM_UNCOMPRESS, M_WAITOK);
-               break;
-       case GEOM_UZIP:
-               sc->zs = (z_stream *)malloc(sizeof(z_stream),
-                   M_GEOM_UNCOMPRESS, M_WAITOK);
-               sc->zs->zalloc = z_alloc;
-               sc->zs->zfree = z_free;
-               if (inflateInit(sc->zs) != Z_OK) {
-                       goto err;
-               }
-               break;
-       }
+       /* Initialize the compression method. */
+       if (g_uncompress[sc->type]->d_init(g_uncompress[sc->type]) != 0)
+               goto err;
 
        g_topology_lock();
        pp2 = g_new_providerf(gp, "%s", gp->name);
Index: sys/modules/geom/geom_uncompress/Makefile
===================================================================
--- sys/modules/geom/geom_uncompress/Makefile   (revision 265013)
+++ sys/modules/geom/geom_uncompress/Makefile   (working copy)
@@ -10,8 +10,9 @@
 CFLAGS+= -I${.CURDIR}/../../../geom/uncompress/ \
        -I${.CURDIR}/../../../contrib/xz-embedded/freebsd \
        -I${.CURDIR}/../../../contrib/xz-embedded/linux/lib/xz/
-SRCS=  g_uncompress.c xz_crc32.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c \
-    xz_malloc.c
+CFLAGS+=-DGEOM_UNCOMPRESS -DGEOM_UNCOMPRESS_UZIP
+SRCS=  g_uncompress.c g_uncompress_ulzma.c g_uncompress_uzip.c opt_geom.h
+SRCS+= xz_crc32.c xz_dec_bcj.c xz_dec_lzma2.c xz_dec_stream.c xz_malloc.c
 SRCS+= xz.h xz_config.h xz_lzma2.h xz_malloc.h xz_private.h xz_stream.h
 
 .include <bsd.kmod.mk>
--- /dev/null   2014-04-27 10:33:00.000000000 -0300
+++ sys/geom/uncompress/g_uncompress.h  2014-04-26 16:18:34.821549524 -0300
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2010-2012 Aleksandr Rybalko
+ * Copyright (c) 2004 Max Khon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _G_UNCOMPRESS_H_
+#define _G_UNCOMPRESS_H_
+
+MALLOC_DECLARE(M_GEOM_UNCOMPRESS);
+
+#define        CLOOP_MAGIC_LEN 128
+#define        CLOOP_TYPE      0x0b
+#define        CLOOP_VERSION   0x0c
+
+/*
+ * Integer values (block size, number of blocks, offsets) are stored in
+ * big-endian (network) order on disk and struct cloop_header.
+ */
+struct cloop_header {
+       char magic[CLOOP_MAGIC_LEN];    /* cloop magic */
+       uint32_t blksz;                 /* block size */
+       uint32_t nblocks;               /* number of blocks */
+}; 
+
+struct g_uncompress_desc;
+
+typedef int g_uncompress_decom_t (struct g_uncompress_desc *, char *,
+       caddr_t, off_t, caddr_t, off_t);
+typedef void g_uncompress_free_t (struct g_uncompress_desc *);
+typedef int g_uncompress_init_t (struct g_uncompress_desc *);
+typedef int g_uncompress_taste_t (struct cloop_header *, char *);
+
+struct g_uncompress_desc {
+       void                    *d_data;
+       g_uncompress_decom_t    *d_decom;
+       g_uncompress_free_t     *d_free;
+       g_uncompress_init_t     *d_init;
+       g_uncompress_taste_t    *d_taste;
+};
+
+/* Supported compression methods. */
+#ifdef GEOM_UNCOMPRESS
+extern struct g_uncompress_desc g_uncompress_ulzma;
+#endif
+#ifdef GEOM_UNCOMPRESS_UZIP
+extern struct g_uncompress_desc g_uncompress_uzip;
+#endif
+
+#endif /* _G_UNCOMPRESS_H_ */
--- /dev/null   2014-04-27 10:33:00.000000000 -0300
+++ sys/geom/uncompress/g_uncompress_ulzma.c    2014-04-26 16:19:04.003547710 
-0300
@@ -0,0 +1,129 @@
+/*-
+ * Copyright (c) 2010-2012 Aleksandr Rybalko
+ * Copyright (c) 2004 Max Khon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * GEOM ULZMA module - simple decompression module for use with read-only
+ * compressed images created by mkulzma(8).
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <geom/uncompress/g_uncompress.h>
+
+#include <contrib/xz-embedded/linux/include/linux/xz.h>
+
+#define        GEOM_ULZMA_MAJVER       '3'
+
+struct g_uncompress_ulzma_softc {
+       /* XZ decoder structs */
+       struct xz_buf *b;
+       struct xz_dec *s;
+};
+
+static void
+g_uncompress_ulzma_free(struct g_uncompress_desc *uncompress)
+{
+       struct g_uncompress_ulzma_softc *sc;
+                
+       sc = (struct g_uncompress_ulzma_softc *)uncompress->d_data;
+       if (sc) {
+               if (sc->b) {
+                       free(sc->b, M_GEOM_UNCOMPRESS);
+                       sc->b = NULL;
+               }
+               if (sc->s) {
+                       xz_dec_end(sc->s);
+                       sc->s = NULL;
+               }
+               free(sc, M_GEOM_UNCOMPRESS);
+               uncompress->d_data = NULL;
+       }
+}
+
+static int
+g_uncompress_ulzma_init(struct g_uncompress_desc *uncompress)
+{
+       struct g_uncompress_ulzma_softc *sc;
+
+       sc = (struct g_uncompress_ulzma_softc *)malloc(sizeof(*sc),
+           M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
+       xz_crc32_init();
+       sc->s = xz_dec_init(XZ_SINGLE, 0);
+       sc->b = (struct xz_buf *)malloc(sizeof(struct xz_buf),
+           M_GEOM_UNCOMPRESS, M_WAITOK);
+
+       uncompress->d_data = (void *)sc;
+
+       return (0);
+}
+
+static int
+g_uncompress_ulzma_decom(struct g_uncompress_desc *uncompress, char *provider,
+       caddr_t in, off_t inlen, caddr_t out, off_t outlen)
+{
+       struct g_uncompress_ulzma_softc *sc;
+
+       sc = (struct g_uncompress_ulzma_softc *)uncompress->d_data;
+       sc->b->in = in;
+       sc->b->out = out;
+       sc->b->in_pos = sc->b->out_pos = 0;
+       sc->b->in_size = inlen;
+       sc->b->out_size = (size_t)-1;
+
+       if (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END)
+               return (-1);
+
+       return (0);
+}
+
+static int
+g_uncompress_ulzma_taste(struct cloop_header *header, char *provider)
+{       
+
+       if (header->magic[CLOOP_TYPE] != 'L')
+               return (0);
+       if (header->magic[CLOOP_VERSION] < GEOM_ULZMA_MAJVER) {
+               printf("%s: image version too old\n", provider);
+               return (-1);
+       }
+       printf("%s: GEOM_ULZMA image found\n", provider);
+
+       return (1);
+}
+
+struct g_uncompress_desc g_uncompress_ulzma = {
+       .d_decom = g_uncompress_ulzma_decom,
+       .d_free = g_uncompress_ulzma_free,
+       .d_init = g_uncompress_ulzma_init,
+       .d_taste = g_uncompress_ulzma_taste,
+};
--- /dev/null   2014-04-27 10:33:00.000000000 -0300
+++ sys/geom/uncompress/g_uncompress_uzip.c     2014-04-26 16:40:11.413462855 
-0300
@@ -0,0 +1,148 @@
+/*-
+ * Copyright (c) 2010-2012 Aleksandr Rybalko
+ * Copyright (c) 2004 Max Khon
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * GEOM UZIP module - simple decompression module for use with read-only
+ * compressed images created by mkuzip(8).
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <geom/uncompress/g_uncompress.h>
+
+#include <net/zlib.h>
+
+#define        GEOM_UZIP_MAJVER        '2'
+
+struct g_uncompress_uzip_softc {
+       z_stream *zs;
+};
+
+static void
+g_uncompress_uzip_free(struct g_uncompress_desc *uncompress)
+{
+       struct g_uncompress_uzip_softc *sc;
+
+       sc = (struct g_uncompress_uzip_softc *)uncompress->d_data;
+       if (sc) {
+               if (sc->zs) {
+                       inflateEnd(sc->zs);
+                       free(sc->zs, M_GEOM_UNCOMPRESS);
+                       sc->zs = NULL;
+               }
+               free(sc, M_GEOM_UNCOMPRESS);
+               uncompress->d_data = NULL;
+       }
+}
+
+static void *
+z_alloc(void *nil, u_int type, u_int size)
+{
+       void *ptr;
+
+       ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
+       return (ptr);
+}
+
+static void
+z_free(void *nil, void *ptr)
+{
+
+       free(ptr, M_GEOM_UNCOMPRESS);
+}
+
+static int
+g_uncompress_uzip_init(struct g_uncompress_desc *uncompress)
+{
+       struct g_uncompress_uzip_softc *sc;
+
+       sc = (struct g_uncompress_uzip_softc *)malloc(sizeof(*sc),
+           M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
+       sc->zs = (z_stream *)malloc(sizeof(z_stream),
+           M_GEOM_UNCOMPRESS, M_WAITOK);
+       sc->zs->zalloc = z_alloc;
+       sc->zs->zfree = z_free;
+       if (inflateInit(sc->zs) != Z_OK) {
+               free (sc->zs, M_GEOM_UNCOMPRESS);
+               free (sc, M_GEOM_UNCOMPRESS);
+               return (-1);
+       }
+
+       uncompress->d_data = (void *)sc;
+
+       return (0);
+}
+
+static int
+g_uncompress_uzip_decom(struct g_uncompress_desc *uncompress, char *provider,
+       caddr_t in, off_t inlen, caddr_t out, off_t outlen)
+{
+       int err;
+       struct g_uncompress_uzip_softc *sc;
+
+       sc = (struct g_uncompress_uzip_softc *)uncompress->d_data;
+       sc->zs->next_in = in;
+       sc->zs->avail_in = inlen;
+       sc->zs->next_out = out;
+       sc->zs->avail_out = outlen;
+
+       err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ?  1 : 0;
+       if (err || inflateReset(sc->zs) != Z_OK) {
+               printf("%s: UZIP decoder reset failed\n", provider);
+               return (-1);
+       }
+
+       return (0);
+}
+
+static int
+g_uncompress_uzip_taste(struct cloop_header *header, char *provider)
+{
+
+       if (header->magic[CLOOP_TYPE] != 'V')
+               return (0);
+       if (header->magic[CLOOP_VERSION] < GEOM_UZIP_MAJVER) {
+               printf("%s: image version too old\n", provider);
+               return (-1);
+       }
+       printf("%s: GEOM_UZIP image found\n", provider);
+
+       return (1);
+}
+
+struct g_uncompress_desc g_uncompress_uzip = {
+       .d_decom = g_uncompress_uzip_decom,
+       .d_free = g_uncompress_uzip_free,
+       .d_init = g_uncompress_uzip_init,
+       .d_taste = g_uncompress_uzip_taste,
+};
Index: share/man/man4/geom_uncompress.4
===================================================================
--- share/man/man4/geom_uncompress.4    (revision 265013)
+++ share/man/man4/geom_uncompress.4    (working copy)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 9, 2014
+.Dd April 27, 2014
 .Dt GEOM_UNCOMPRESS 4
 .Os
 .Sh NAME
@@ -31,10 +31,11 @@
 .Nm geom_uncompress
 .Nd "GEOM based compressed disk images"
 .Sh SYNOPSIS
-To compile this driver into the kernel, place the following line in your
+To compile this driver into the kernel, place the following lines in your
 kernel configuration file:
 .Bd -ragged -offset indent
 .Cd "options GEOM_UNCOMPRESS"
+.Cd "options GEOM_UNCOMPRESS_UZIP"
 .Ed
 .Pp
 Alternatively, to load the driver as a module at boot time, place the
@@ -89,6 +90,18 @@
    Sectorsize: 512
    Mode: r1w0e0
 .Ed
+.Pp
+The compression support can be chosen in kernel configuration:
+.Bl -tag -width ".Sy options GEOM_UNCOMPRESS_UZIP"
+.It Sy options GEOM_UNCOMPRESS
+Enable the support for mkulzma(8) images.
+.It Sy options GEOM_UNCOMPRESS_UZIP
+Enable the support for mkuzip(8) images.
+.El
+.Pp
+The
+.Nm
+module is built with both compression methods enabled.
 .Sh SEE ALSO
 .Xr GEOM 4 ,
 .Xr md 4 ,
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-geom
To unsubscribe, send any mail to "[email protected]"

Reply via email to