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; }
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; }
/** * 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; }
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; }
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; }
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; }
/** * 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; }
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); }
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; }
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); }
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; }
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); }
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); }
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; }
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; }
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; } }
/* 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 */ }
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; }
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; }
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; }
/* 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 */ }
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; }