Exemplo n.º 1
0
static coa_t gzip1_alloc(tfm_action act)
{
    coa_t coa = NULL;
    int ret = 0;
    switch (act) {
    case TFMA_WRITE:	/* compress */
        coa = reiser4_vmalloc(zlib_deflate_workspacesize());
        if (!coa) {
            ret = -ENOMEM;
            break;
        }
        break;
    case TFMA_READ:	/* decompress */
        coa = reiser4_vmalloc(zlib_inflate_workspacesize());
        if (!coa) {
            ret = -ENOMEM;
            break;
        }
        break;
    default:
        impossible("edward-767",
                   "trying to alloc workspace for unknown tfm action");
    }
    if (ret) {
        warning("edward-768",
                "alloc workspace for gzip1 (tfm action = %d) failed\n",
                act);
        return ERR_PTR(ret);
    }
    return coa;
}
Exemplo n.º 2
0
int sqlzma_init(struct sqlzma_un *un, int do_lzma, unsigned int res_sz)
{
	int err;

	err = -ENOMEM;
	un->un_lzma = do_lzma;
	memset(un->un_a, 0, sizeof(un->un_a));
	un->un_a[SQUN_PROB].buf = un->un_prob;
	un->un_a[SQUN_PROB].sz = sizeof(un->un_prob);
	if (res_sz) {
		un->un_a[SQUN_RESULT].buf = kmalloc(res_sz, GFP_KERNEL);
		if (unlikely(!un->un_a[SQUN_RESULT].buf))
			return err;
		un->un_a[SQUN_RESULT].sz = res_sz;
	}

	un->un_stream.next_in = NULL;
	un->un_stream.avail_in = 0;
#ifdef __KERNEL__
	un->un_stream.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
	if (unlikely(!un->un_stream.workspace))
		return err;
#else
	un->un_stream.opaque = NULL;
	un->un_stream.zalloc = Z_NULL;
	un->un_stream.zfree = Z_NULL;
#endif
	err = zlib_inflateInit(&un->un_stream);
	if (unlikely(err == Z_MEM_ERROR))
		return -ENOMEM;
	BUG_ON(err);
	return err;
}
Exemplo n.º 3
0
/**
 *	z_decomp_alloc - allocate space for a decompressor.
 *	@options: pointer to CCP option data
 *	@opt_len: length of the CCP option at @options.
 *
 *	The @options pointer points to the a buffer containing the
 *	CCP option data for the compression being negotiated.  It is
 *	formatted according to RFC1979, and describes the window
 *	size that we are requesting the peer to use in compressing
 *	data to be sent to us.
 *
 *	Returns the pointer to the private state for the decompressor,
 *	or NULL if we could not allocate enough memory.
 */
static void *z_decomp_alloc(unsigned char *options, int opt_len)
{
	struct ppp_deflate_state *state;
	int w_size;

	if (opt_len != CILEN_DEFLATE
	    || (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT)
	    || options[1] != CILEN_DEFLATE
	    || DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL
	    || options[3] != DEFLATE_CHK_SEQUENCE)
		return NULL;
	w_size = DEFLATE_SIZE(options[2]);
	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
		return NULL;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (state == NULL)
		return NULL;

	state->w_size         = w_size;
	state->strm.next_out  = NULL;
	state->strm.workspace = kmalloc(zlib_inflate_workspacesize(),
					GFP_KERNEL|__GFP_REPEAT);
	if (state->strm.workspace == NULL)
		goto out_free;

	if (zlib_inflateInit2(&state->strm, -w_size) != Z_OK)
		goto out_free;
	return (void *) state;

out_free:
	z_decomp_free(state);
	return NULL;
}
Exemplo n.º 4
0
static int zlib_decompress_setup(struct crypto_pcomp *tfm, void *params,
				 unsigned int len)
{
	struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm));
	struct z_stream_s *stream = &ctx->decomp_stream;
	struct nlattr *tb[ZLIB_DECOMP_MAX + 1];
	int ret = 0;

	ret = nla_parse(tb, ZLIB_DECOMP_MAX, params, len, NULL);
	if (ret)
		return ret;

	zlib_decomp_exit(ctx);

	ctx->decomp_windowBits = tb[ZLIB_DECOMP_WINDOWBITS]
				 ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
				 : DEF_WBITS;

	stream->workspace = vzalloc(zlib_inflate_workspacesize());
	if (!stream->workspace)
		return -ENOMEM;

	ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
	if (ret != Z_OK) {
		vfree(stream->workspace);
		stream->workspace = NULL;
		return -EINVAL;
	}

	return 0;
}
Exemplo n.º 5
0
int __init jffs2_zlib_init(void)
{
	deflate_workspace = vmalloc(zlib_deflate_workspacesize());
	if (!deflate_workspace) {
		printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize());
		return -ENOMEM;
	}
	D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize()));
	inflate_workspace = vmalloc(zlib_inflate_workspacesize());
	if (!inflate_workspace) {
		printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize());
		vfree(deflate_workspace);
		return -ENOMEM;
	}
	D1(printk(KERN_DEBUG "Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize()));
	return 0;
}
Exemplo n.º 6
0
int __init logfs_compr_init(void)
{
	size_t size = max(zlib_deflate_workspacesize(),
			zlib_inflate_workspacesize());
	stream.workspace = vmalloc(size);
	if (!stream.workspace)
		return -ENOMEM;
	return 0;
}
Exemplo n.º 7
0
/**
 *	z_decomp_alloc - allocate space for a decompressor.
 *	@options: pointer to CCP option data
 *	@opt_len: length of the CCP option at @options.
 *
 *	The @options pointer points to the a buffer containing the
 *	CCP option data for the compression being negotiated.  It is
 *	formatted according to RFC1979, and describes the window
 *	size that we are requesting the peer to use in compressing
 *	data to be sent to us.
 *
 *	Returns the pointer to the private state for the decompressor,
 *	or NULL if we could not allocate enough memory.
 */
static void *z_decomp_alloc(unsigned char *options, int opt_len)
{
	struct ppp_deflate_state *state;
	int w_size;

	if (opt_len != CILEN_DEFLATE ||
	    (options[0] != CI_DEFLATE && options[0] != CI_DEFLATE_DRAFT) ||
	    options[1] != CILEN_DEFLATE ||
	    DEFLATE_METHOD(options[2]) != DEFLATE_METHOD_VAL ||
	    options[3] != DEFLATE_CHK_SEQUENCE)
		return NULL;
	w_size = DEFLATE_SIZE(options[2]);
	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
		return NULL;

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (state == NULL)
		return NULL;

	state->w_size         = w_size;
	state->strm.next_out  = NULL;
/* LGE_CHANGE_S [LS855:[email protected]] 2011-07-11, */ 
#if 0  /* Delete Warning Log - OMAPS00243976 */
	state->strm.workspace = kmalloc(zlib_inflate_workspacesize(),
					GFP_KERNEL|__GFP_REPEAT);
#else
	state->strm.workspace = vmalloc(zlib_inflate_workspacesize());
#endif
/* LGE_CHANGE_E [LS855:[email protected]] 2011-07-11 */
	if (state->strm.workspace == NULL)
		goto out_free;

	if (zlib_inflateInit2(&state->strm, -w_size) != Z_OK)
		goto out_free;
	return (void *) state;

out_free:
	z_decomp_free(state);
	return NULL;
}
int cramfs_uncompress_init_gzip(void)
{
	if (!gzip_initialized++) {
		stream.workspace = vmalloc(zlib_inflate_workspacesize());
		if ( !stream.workspace ) {
			gzip_initialized = 0;
			return -ENOMEM;
		}
		stream.next_in = NULL;
		stream.avail_in = 0;
		zlib_inflateInit(&stream);
	}
	return 0;
}
Exemplo n.º 9
0
static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
{
	z_stream s;
	int r, i, flags;

	/* skip header */
	i = 10;
	flags = src[3];
	if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
		printf("bad gzipped data\n\r");
		exit();
	}
	if ((flags & EXTRA_FIELD) != 0)
		i = 12 + src[10] + (src[11] << 8);
	if ((flags & ORIG_NAME) != 0)
		while (src[i++] != 0)
			;
	if ((flags & COMMENT) != 0)
		while (src[i++] != 0)
			;
	if ((flags & HEAD_CRC) != 0)
		i += 2;
	if (i >= *lenp) {
		printf("gunzip: ran out of data in header\n\r");
		exit();
	}

	if (zlib_inflate_workspacesize() > sizeof(scratch)) {
		printf("gunzip needs more mem\n");
		exit();
	}
	memset(&s, 0, sizeof(s));
	s.workspace = scratch;
	r = zlib_inflateInit2(&s, -MAX_WBITS);
	if (r != Z_OK) {
		printf("inflateInit2 returned %d\n\r", r);
		exit();
	}
	s.next_in = src + i;
	s.avail_in = *lenp - i;
	s.next_out = dst;
	s.avail_out = dstlen;
	r = zlib_inflate(&s, Z_FULL_FLUSH);
	if (r != Z_OK && r != Z_STREAM_END) {
		printf("inflate returned %d msg: %s\n\r", r, s.msg);
		exit();
	}
	*lenp = s.next_out - (unsigned char *) dst;
	zlib_inflateEnd(&s);
}
Exemplo n.º 10
0
Arquivo: png.c Projeto: zandar/barebox
int png_uncompress_init(void)
{
    if (!initialized++) {
        png_stream.workspace = malloc(zlib_inflate_workspacesize());
        if (!png_stream.workspace) {
            initialized = 0;
            return -ENOMEM;
        }
        png_stream.next_in = NULL;
        png_stream.avail_in = 0;
        zlib_inflateInit(&png_stream);
    }
    return 0;
}
Exemplo n.º 11
0
int zlib_init(void)
{
	int size;
        SENTRY;

	size = MAX(spl_zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
	    zlib_inflate_workspacesize());

	zlib_workspace_cache = kmem_cache_create("spl_zlib_workspace_cache",
	    size, 0, NULL, NULL, NULL, NULL, NULL, KMC_VMEM);
        if (!zlib_workspace_cache)
		SRETURN(1);

        SRETURN(0);
}
Exemplo n.º 12
0
static int zlib_decomp_init(void)
{
	struct z_stream_s *stream = &ubifs_zlib_stream;
	int ret;

	stream->workspace = xzalloc(zlib_inflate_workspacesize());

	ret = zlib_inflateInit2(stream, -MAX_WBITS);
	if (ret != Z_OK) {
		free(stream->workspace);
		return -EINVAL;
	}

	return 0;
}
Exemplo n.º 13
0
static void *zlib_init(struct squashfs_sb_info *dummy, void *buff, int len)
{
	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
	if (stream == NULL)
		goto failed;
	stream->workspace = vmalloc(zlib_inflate_workspacesize());
	if (stream->workspace == NULL)
		goto failed;

	return stream;

failed:
	ERROR("Failed to allocate zlib workspace\n");
	kfree(stream);
	return ERR_PTR(-ENOMEM);
}
Exemplo n.º 14
0
void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
{
	z_stream s;
	int r, i, flags;

	/* skip header */
	i = 10;
	flags = src[3];
	if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
		puts("bad gzipped data\n");
		exit();
	}
	if ((flags & EXTRA_FIELD) != 0)
		i = 12 + src[10] + (src[11] << 8);
	if ((flags & ORIG_NAME) != 0)
		while (src[i++] != 0)
			;
	if ((flags & COMMENT) != 0)
		while (src[i++] != 0)
			;
	if ((flags & HEAD_CRC) != 0)
		i += 2;
	if (i >= *lenp) {
		puts("gunzip: ran out of data in header\n");
		exit();
	}

	/* Initialize ourself. */
	s.workspace = zalloc(zlib_inflate_workspacesize());
	r = zlib_inflateInit2(&s, -MAX_WBITS);
	if (r != Z_OK) {
		puts("zlib_inflateInit2 returned "); puthex(r); puts("\n");
		exit();
	}
	s.next_in = src + i;
	s.avail_in = *lenp - i;
	s.next_out = dst;
	s.avail_out = dstlen;
	r = zlib_inflate(&s, Z_FINISH);
	if (r != Z_OK && r != Z_STREAM_END) {
		puts("inflate returned "); puthex(r); puts("\n");
		exit();
	}
	*lenp = s.next_out - (unsigned char *) dst;
	zlib_inflateEnd(&s);
}
Exemplo n.º 15
0
static void *zlib_init(struct squashfs_sb_info *dummy)
{
	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
	if (stream == NULL)
		goto failed;
	stream->workspace = kmalloc(zlib_inflate_workspacesize(),
		GFP_KERNEL);
	if (stream->workspace == NULL)
		goto failed;

	return stream;

failed:
	ERROR("Failed to allocate zlib workspace\n");
	kfree(stream);
	return NULL;
}
Exemplo n.º 16
0
void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp)
{
	z_stream s;
	int r, i, flags;

        
        i = 10;
        flags = src[3];
        if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
                
                exit();
        }
        if ((flags & EXTRA_FIELD) != 0)
                i = 12 + src[10] + (src[11] << 8);
        if ((flags & ORIG_NAME) != 0)
                while (src[i++] != 0)
                        ;
        if ((flags & COMMENT) != 0)
                while (src[i++] != 0)
                        ;
        if ((flags & HEAD_CRC) != 0)
                i += 2;
        if (i >= *lenp) {
                
                exit();
        }

	s.workspace = zalloc(zlib_inflate_workspacesize());
        r = zlib_inflateInit2(&s, -MAX_WBITS);
        if (r != Z_OK) {
                
                exit();
        }
        s.next_in = src + i;
        s.avail_in = *lenp - i;
        s.next_out = dst;
        s.avail_out = dstlen;
        r = zlib_inflate(&s, Z_FINISH);
        if (r != Z_OK && r != Z_STREAM_END) {
                
                exit();
        }
        *lenp = s.next_out - (unsigned char *) dst;
        zlib_inflateEnd(&s);
}
/* _VMKLNX_CODECHECK_: zlib_inflate_blob */
int zlib_inflate_blob(void *gunzip_buf, unsigned int sz,
                      const void *buf, unsigned int len)
{
        const u8 *zbuf = buf;
        struct z_stream_s *strm;
        int rc;
        
#if defined(__VMKLNX__)
	VMK_ASSERT(vmk_PreemptionIsEnabled() == VMK_FALSE);
#endif
        rc = -ENOMEM;
        strm = kmalloc(sizeof(*strm), GFP_KERNEL);
        if (strm == NULL)
                goto gunzip_nomem1;
        strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
        if (strm->workspace == NULL)
                goto gunzip_nomem2;
        
        /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename)
         * expected to be stripped from input
         */
        strm->next_in = zbuf;
        strm->avail_in = len;
        strm->next_out = gunzip_buf;
        strm->avail_out = sz;
        
        rc = zlib_inflateInit2(strm, -MAX_WBITS);
        if (rc == Z_OK) {
                rc = zlib_inflate(strm, Z_FINISH);
                /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
                if (rc == Z_STREAM_END)
                        rc = sz - strm->avail_out;
                else
                        rc = -EINVAL;
                zlib_inflateEnd(strm);
        } else
                rc = -EINVAL;
        
        kfree(strm->workspace);
 gunzip_nomem2:
        kfree(strm);
 gunzip_nomem1:
        return rc; /* returns Z_OK (0) if successful */
}
void gunzip_start(struct gunzip_state *state, void *src, int srclen)
{
	char *hdr = src;
	int hdrlen = 0;

	memset(state, 0, sizeof(*state));

	/* Check for gzip magic number */
	if ((hdr[0] == 0x1f) && (hdr[1] == 0x8b)) {
		/* gzip data, initialize zlib parameters */
		int r, flags;

		state->s.workspace = state->scratch;
		if (zlib_inflate_workspacesize() > sizeof(state->scratch))
			fatal("insufficient scratch space for gunzip\n\r");

		/* skip header */
		hdrlen = 10;
		flags = hdr[3];
		if (hdr[2] != Z_DEFLATED || (flags & RESERVED) != 0)
			fatal("bad gzipped data\n\r");
		if ((flags & EXTRA_FIELD) != 0)
			hdrlen = 12 + hdr[10] + (hdr[11] << 8);
		if ((flags & ORIG_NAME) != 0)
			while (hdr[hdrlen++] != 0)
				;
		if ((flags & COMMENT) != 0)
			while (hdr[hdrlen++] != 0)
				;
		if ((flags & HEAD_CRC) != 0)
			hdrlen += 2;
		if (hdrlen >= srclen)
			fatal("gunzip_start: ran out of data in header\n\r");

		r = zlib_inflateInit2(&state->s, -MAX_WBITS);
		if (r != Z_OK)
			fatal("inflateInit2 returned %d\n\r", r);
	}

	state->s.total_in = hdrlen;
	state->s.next_in = src + hdrlen;
	state->s.avail_in = srclen - hdrlen;
}
Exemplo n.º 19
0
static void allocate_buf_for_compression(void)
{
    size_t size;
    size_t cmpr;

    switch (psinfo->bufsize) {
    /* buffer range for efivars */
    case 1000 ... 2000:
        cmpr = 56;
        break;
    case 2001 ... 3000:
        cmpr = 54;
        break;
    case 3001 ... 3999:
        cmpr = 52;
        break;
    /* buffer range for nvram, erst */
    case 4000 ... 10000:
        cmpr = 45;
        break;
    default:
        cmpr = 60;
        break;
    }

    big_oops_buf_sz = (psinfo->bufsize * 100) / cmpr;
    big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
    if (big_oops_buf) {
        size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
                   zlib_inflate_workspacesize());
        stream.workspace = kmalloc(size, GFP_KERNEL);
        if (!stream.workspace) {
            pr_err("No memory for compression workspace; skipping compression\n");
            kfree(big_oops_buf);
            big_oops_buf = NULL;
        }
    } else {
        pr_err("No memory for uncompressed data; skipping compression\n");
        stream.workspace = NULL;
    }

}
Exemplo n.º 20
0
/* Utility function: initialize zlib, unpack binary blob, clean up zlib,
 * return len or negative error code.
 */
int zlib_inflate_blob(void *gunzip_buf, unsigned int sz,
		      const void *buf, unsigned int len)
{
	const u8 *zbuf = buf;
	struct z_stream_s *strm;
	int rc;

	rc = -ENOMEM;
	strm = MALLOC(sizeof(*strm));
	if (strm == NULL)
		goto gunzip_nomem1;
	strm->workspace = MALLOC(zlib_inflate_workspacesize());
	if (strm->workspace == NULL)
		goto gunzip_nomem2;

	/* gzip header (1f,8b,08... 10 bytes total + possible asciz filename)
	 * expected to be stripped from input
	 */
	strm->next_in = zbuf;
	strm->avail_in = len;
	strm->next_out = gunzip_buf;
	strm->avail_out = sz;

	rc = zlib_inflateInit2(strm, -MAX_WBITS);
	if (rc == Z_OK) {
		rc = zlib_inflate(strm, Z_FINISH);
		/* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
		if (rc == Z_STREAM_END)
			rc = sz - strm->avail_out;
		else
			rc = -EINVAL;
		zlib_inflateEnd(strm);
	} else
		rc = -EINVAL;

	FREE(strm->workspace);
gunzip_nomem2:
	FREE(strm);
gunzip_nomem1:
	return rc; /* returns Z_OK (0) if successful */
}
Exemplo n.º 21
0
int sqlzma_init(struct sqlzma_un *un, int do_lzma, unsigned int res_sz)
{
	int err;

	err = -ENOMEM;
	un->un_lzma = do_lzma;
	memset(un->un_a, 0, sizeof(un->un_a));
	un->un_a[SQUN_PROB].buf = un->un_prob;
	un->un_a[SQUN_PROB].sz = sizeof(un->un_prob);
	if (res_sz) {
		un->un_a[SQUN_RESULT].buf = kmalloc(res_sz, GFP_KERNEL);
		if (unlikely(!un->un_a[SQUN_RESULT].buf))
			return err;
		un->un_a[SQUN_RESULT].sz = res_sz;
	}

	un->un_stream.next_in = NULL;
	un->un_stream.avail_in = 0;
//#if defined(CONFIG_MIPS_BRCM)
#if 1 // disable zlib inflate
	/* The FS is compressed with LZMA for BRCM: do not use zlib */
	un->un_stream.workspace = NULL;
	err = 0;
#else
#ifdef __KERNEL__
	un->un_stream.workspace = kmalloc(zlib_inflate_workspacesize(),
					  GFP_KERNEL);
	if (unlikely(!un->un_stream.workspace))
		return err;
#else
	un->un_stream.opaque = NULL;
	un->un_stream.zalloc = Z_NULL;
	un->un_stream.zfree = Z_NULL;
#endif
	err = zlib_inflateInit(&un->un_stream);
	if (unlikely(err == Z_MEM_ERROR))
		return -ENOMEM;
#endif
	BUG_ON(err);
	return err;
}
Exemplo n.º 22
0
static int deflate_decomp_init(struct deflate_ctx *ctx)
{
    int ret = 0;
    struct z_stream_s *stream = &ctx->decomp_stream;

    stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
    if (!stream->workspace ) {
        ret = -ENOMEM;
        goto out;
    }
    ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
    if (ret != Z_OK) {
        ret = -EINVAL;
        goto out_free;
    }
out:
    return ret;
out_free:
    kfree(stream->workspace);
    goto out;
}
Exemplo n.º 23
0
static int deflate_decomp_init(struct deflate_ctx *ctx, int format)
{
	int ret = 0;
	struct z_stream_s *stream = &ctx->decomp_stream;

	stream->workspace = vzalloc(zlib_inflate_workspacesize());
	if (!stream->workspace) {
		ret = -ENOMEM;
		goto out;
	}
	if (format)
		ret = zlib_inflateInit(stream);
	else
		ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
	if (ret != Z_OK) {
		ret = -EINVAL;
		goto out_free;
	}
out:
	return ret;
out_free:
	vfree(stream->workspace);
	goto out;
}
Exemplo n.º 24
0
/* Included from initramfs et al code */
STATIC int INIT __gunzip(unsigned char *buf, long len,
		       long (*fill)(void*, unsigned long),
		       long (*flush)(void*, unsigned long),
		       unsigned char *out_buf, long out_len,
		       long *pos,
		       void(*error)(char *x)) {
	u8 *zbuf;
	struct z_stream_s *strm;
	int rc;

	rc = -1;
	if (flush) {
		out_len = 0x8000; /* 32 K */
		out_buf = malloc(out_len);
	} else {
		if (!out_len)
			out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */
	}
	if (!out_buf) {
		error("Out of memory while allocating output buffer");
		goto gunzip_nomem1;
	}

	if (buf)
		zbuf = buf;
	else {
		zbuf = malloc(GZIP_IOBUF_SIZE);
		len = 0;
	}
	if (!zbuf) {
		error("Out of memory while allocating input buffer");
		goto gunzip_nomem2;
	}

	strm = malloc(sizeof(*strm));
	if (strm == NULL) {
		error("Out of memory while allocating z_stream");
		goto gunzip_nomem3;
	}

	strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
				 sizeof(struct inflate_state));
	if (strm->workspace == NULL) {
		error("Out of memory while allocating workspace");
		goto gunzip_nomem4;
	}

	if (!fill)
		fill = nofill;

	if (len == 0)
		len = fill(zbuf, GZIP_IOBUF_SIZE);

	/* verify the gzip header */
	if (len < 10 ||
	   zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
		if (pos)
			*pos = 0;
		error("Not a gzip file");
		goto gunzip_5;
	}

	/* skip over gzip header (1f,8b,08... 10 bytes total +
	 * possible asciz filename)
	 */
	strm->next_in = zbuf + 10;
	strm->avail_in = len - 10;
	/* skip over asciz filename */
	if (zbuf[3] & 0x8) {
		do {
			/*
			 * If the filename doesn't fit into the buffer,
			 * the file is very probably corrupt. Don't try
			 * to read more data.
			 */
			if (strm->avail_in == 0) {
				error("header error");
				goto gunzip_5;
			}
			--strm->avail_in;
		} while (*strm->next_in++);
	}

	strm->next_out = out_buf;
	strm->avail_out = out_len;

	rc = zlib_inflateInit2(strm, -MAX_WBITS);

	if (!flush) {
		WS(strm)->inflate_state.wsize = 0;
		WS(strm)->inflate_state.window = NULL;
	}

	while (rc == Z_OK) {
		if (strm->avail_in == 0) {
			/* TODO: handle case where both pos and fill are set */
			len = fill(zbuf, GZIP_IOBUF_SIZE);
			if (len < 0) {
				rc = -1;
				error("read error");
				break;
			}
			strm->next_in = zbuf;
			strm->avail_in = len;
		}
		rc = zlib_inflate(strm, 0);

		/* Write any data generated */
		if (flush && strm->next_out > out_buf) {
			long l = strm->next_out - out_buf;
			if (l != flush(out_buf, l)) {
				rc = -1;
				error("write error");
				break;
			}
			strm->next_out = out_buf;
			strm->avail_out = out_len;
		}

		/* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
		if (rc == Z_STREAM_END) {
			rc = 0;
			break;
		} else if (rc != Z_OK) {
			error("uncompression error");
			rc = -1;
		}
	}

	zlib_inflateEnd(strm);
	if (pos)
		/* add + 8 to skip over trailer */
		*pos = strm->next_in - zbuf+8;

gunzip_5:
	free(strm->workspace);
gunzip_nomem4:
	free(strm);
gunzip_nomem3:
	if (!buf)
		free(zbuf);
gunzip_nomem2:
	if (flush)
		free(out_buf);
gunzip_nomem1:
	return rc; /* returns Z_OK (0) if successful */
}
Exemplo n.º 25
0
static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct squashfs_sb_info *msblk;
	struct squashfs_super_block *sblk = NULL;
	char b[BDEVNAME_SIZE];
	struct inode *root;
	long long root_inode;
	unsigned short flags;
	unsigned int fragments;
	u64 lookup_table_start;
	int err;

	TRACE("Entered squashfs_fill_superblock\n");

	sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL);
	if (sb->s_fs_info == NULL) {
		ERROR("Failed to allocate squashfs_sb_info\n");
		return -ENOMEM;
	}
	msblk = sb->s_fs_info;

	msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(),
		GFP_KERNEL);
	if (msblk->stream.workspace == NULL) {
		ERROR("Failed to allocate zlib workspace\n");
		goto failure;
	}

	sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
	if (sblk == NULL) {
		ERROR("Failed to allocate squashfs_super_block\n");
		goto failure;
	}

	msblk->devblksize = sb_min_blocksize(sb, BLOCK_SIZE);
	msblk->devblksize_log2 = ffz(~msblk->devblksize);

	mutex_init(&msblk->read_data_mutex);
	mutex_init(&msblk->meta_index_mutex);

	/*
	 * msblk->bytes_used is checked in squashfs_read_table to ensure reads
	 * are not beyond filesystem end.  But as we're using
	 * squashfs_read_table here to read the superblock (including the value
	 * of bytes_used) we need to set it to an initial sensible dummy value
	 */
	msblk->bytes_used = sizeof(*sblk);
	err = squashfs_read_table(sb, sblk, SQUASHFS_START, sizeof(*sblk));

	if (err < 0) {
		ERROR("unable to read squashfs_super_block\n");
		goto failed_mount;
	}

	/* Check it is a SQUASHFS superblock */
	sb->s_magic = le32_to_cpu(sblk->s_magic);
	if (sb->s_magic != SQUASHFS_MAGIC) {
		if (!silent)
			ERROR("Can't find a SQUASHFS superblock on %s\n",
						bdevname(sb->s_bdev, b));
		err = -EINVAL;
		goto failed_mount;
	}

	/* Check the MAJOR & MINOR versions and compression type */
	err = supported_squashfs_filesystem(le16_to_cpu(sblk->s_major),
			le16_to_cpu(sblk->s_minor),
			le16_to_cpu(sblk->compression));
	if (err < 0)
		goto failed_mount;

	err = -EINVAL;

	/*
	 * Check if there's xattrs in the filesystem.  These are not
	 * supported in this version, so warn that they will be ignored.
	 */
	if (le64_to_cpu(sblk->xattr_table_start) != SQUASHFS_INVALID_BLK)
		ERROR("Xattrs in filesystem, these will be ignored\n");

	/* Check the filesystem does not extend beyond the end of the
	   block device */
	msblk->bytes_used = le64_to_cpu(sblk->bytes_used);
	if (msblk->bytes_used < 0 || msblk->bytes_used >
			i_size_read(sb->s_bdev->bd_inode))
		goto failed_mount;

	/* Check block size for sanity */
	msblk->block_size = le32_to_cpu(sblk->block_size);
	if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
		goto failed_mount;

	/*
	 * Check the system page size is not larger than the filesystem
	 * block size (by default 128K).  This is currently not supported.
	 */
	if (PAGE_CACHE_SIZE > msblk->block_size) {
		ERROR("Page size > filesystem block size (%d).  This is "
			"currently not supported!\n", msblk->block_size);
		goto failed_mount;
	}

	msblk->block_log = le16_to_cpu(sblk->block_log);
	if (msblk->block_log > SQUASHFS_FILE_MAX_LOG)
		goto failed_mount;

	/* Check the root inode for sanity */
	root_inode = le64_to_cpu(sblk->root_inode);
	if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
		goto failed_mount;

	msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
	msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
	msblk->inodes = le32_to_cpu(sblk->inodes);
	flags = le16_to_cpu(sblk->flags);

	TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b));
	TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(flags)
				? "un" : "");
	TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(flags)
				? "un" : "");
	TRACE("Filesystem size %lld bytes\n", msblk->bytes_used);
	TRACE("Block size %d\n", msblk->block_size);
	TRACE("Number of inodes %d\n", msblk->inodes);
	TRACE("Number of fragments %d\n", le32_to_cpu(sblk->fragments));
	TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids));
	TRACE("sblk->inode_table_start %llx\n", msblk->inode_table);
	TRACE("sblk->directory_table_start %llx\n", msblk->directory_table);
	TRACE("sblk->fragment_table_start %llx\n",
		(u64) le64_to_cpu(sblk->fragment_table_start));
	TRACE("sblk->id_table_start %llx\n",
		(u64) le64_to_cpu(sblk->id_table_start));

	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_flags |= MS_RDONLY;
	sb->s_op = &squashfs_super_ops;

	err = -ENOMEM;

	msblk->block_cache = squashfs_cache_init("metadata",
			SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
	if (msblk->block_cache == NULL)
		goto failed_mount;

	/* Allocate read_page block */
	msblk->read_page = squashfs_cache_init("data", 1, msblk->block_size);
	if (msblk->read_page == NULL) {
		ERROR("Failed to allocate read_page block\n");
		goto failed_mount;
	}

	/* Allocate and read id index table */
	msblk->id_table = squashfs_read_id_index_table(sb,
		le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids));
	if (IS_ERR(msblk->id_table)) {
		err = PTR_ERR(msblk->id_table);
		msblk->id_table = NULL;
		goto failed_mount;
	}

	fragments = le32_to_cpu(sblk->fragments);
	if (fragments == 0)
		goto allocate_lookup_table;

	msblk->fragment_cache = squashfs_cache_init("fragment",
		SQUASHFS_CACHED_FRAGMENTS, msblk->block_size);
	if (msblk->fragment_cache == NULL) {
		err = -ENOMEM;
		goto failed_mount;
	}

	/* Allocate and read fragment index table */
	msblk->fragment_index = squashfs_read_fragment_index_table(sb,
		le64_to_cpu(sblk->fragment_table_start), fragments);
	if (IS_ERR(msblk->fragment_index)) {
		err = PTR_ERR(msblk->fragment_index);
		msblk->fragment_index = NULL;
		goto failed_mount;
	}

allocate_lookup_table:
	lookup_table_start = le64_to_cpu(sblk->lookup_table_start);
	if (lookup_table_start == SQUASHFS_INVALID_BLK)
		goto allocate_root;

	/* Allocate and read inode lookup table */
	msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
		lookup_table_start, msblk->inodes);
	if (IS_ERR(msblk->inode_lookup_table)) {
		err = PTR_ERR(msblk->inode_lookup_table);
		msblk->inode_lookup_table = NULL;
		goto failed_mount;
	}

	sb->s_export_op = &squashfs_export_ops;

allocate_root:
	root = new_inode(sb);
	if (!root) {
		err = -ENOMEM;
		goto failed_mount;
	}

	err = squashfs_read_inode(root, root_inode);
	if (err) {
		iget_failed(root);
		goto failed_mount;
	}
	insert_inode_hash(root);

	sb->s_root = d_alloc_root(root);
	if (sb->s_root == NULL) {
		ERROR("Root inode create failed\n");
		err = -ENOMEM;
		iput(root);
		goto failed_mount;
	}

	TRACE("Leaving squashfs_fill_super\n");
	kfree(sblk);
	return 0;

failed_mount:
	squashfs_cache_delete(msblk->block_cache);
	squashfs_cache_delete(msblk->fragment_cache);
	squashfs_cache_delete(msblk->read_page);
	kfree(msblk->inode_lookup_table);
	kfree(msblk->fragment_index);
	kfree(msblk->id_table);
	kfree(msblk->stream.workspace);
	kfree(sb->s_fs_info);
	sb->s_fs_info = NULL;
	kfree(sblk);
	return err;

failure:
	kfree(msblk->stream.workspace);
	kfree(sb->s_fs_info);
	sb->s_fs_info = NULL;
	return -ENOMEM;
}