1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * uncompress.c 3*1da177e4SLinus Torvalds * 4*1da177e4SLinus Torvalds * (C) Copyright 1999 Linus Torvalds 5*1da177e4SLinus Torvalds * 6*1da177e4SLinus Torvalds * cramfs interfaces to the uncompression library. There's really just 7*1da177e4SLinus Torvalds * three entrypoints: 8*1da177e4SLinus Torvalds * 9*1da177e4SLinus Torvalds * - cramfs_uncompress_init() - called to initialize the thing. 10*1da177e4SLinus Torvalds * - cramfs_uncompress_exit() - tell me when you're done 11*1da177e4SLinus Torvalds * - cramfs_uncompress_block() - uncompress a block. 12*1da177e4SLinus Torvalds * 13*1da177e4SLinus Torvalds * NOTE NOTE NOTE! The uncompression is entirely single-threaded. We 14*1da177e4SLinus Torvalds * only have one stream, and we'll initialize it only once even if it 15*1da177e4SLinus Torvalds * then is used by multiple filesystems. 16*1da177e4SLinus Torvalds */ 17*1da177e4SLinus Torvalds 18*1da177e4SLinus Torvalds #include <linux/kernel.h> 19*1da177e4SLinus Torvalds #include <linux/errno.h> 20*1da177e4SLinus Torvalds #include <linux/vmalloc.h> 21*1da177e4SLinus Torvalds #include <linux/zlib.h> 22*1da177e4SLinus Torvalds 23*1da177e4SLinus Torvalds static z_stream stream; 24*1da177e4SLinus Torvalds static int initialized; 25*1da177e4SLinus Torvalds 26*1da177e4SLinus Torvalds /* Returns length of decompressed data. */ 27*1da177e4SLinus Torvalds int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen) 28*1da177e4SLinus Torvalds { 29*1da177e4SLinus Torvalds int err; 30*1da177e4SLinus Torvalds 31*1da177e4SLinus Torvalds stream.next_in = src; 32*1da177e4SLinus Torvalds stream.avail_in = srclen; 33*1da177e4SLinus Torvalds 34*1da177e4SLinus Torvalds stream.next_out = dst; 35*1da177e4SLinus Torvalds stream.avail_out = dstlen; 36*1da177e4SLinus Torvalds 37*1da177e4SLinus Torvalds err = zlib_inflateReset(&stream); 38*1da177e4SLinus Torvalds if (err != Z_OK) { 39*1da177e4SLinus Torvalds printk("zlib_inflateReset error %d\n", err); 40*1da177e4SLinus Torvalds zlib_inflateEnd(&stream); 41*1da177e4SLinus Torvalds zlib_inflateInit(&stream); 42*1da177e4SLinus Torvalds } 43*1da177e4SLinus Torvalds 44*1da177e4SLinus Torvalds err = zlib_inflate(&stream, Z_FINISH); 45*1da177e4SLinus Torvalds if (err != Z_STREAM_END) 46*1da177e4SLinus Torvalds goto err; 47*1da177e4SLinus Torvalds return stream.total_out; 48*1da177e4SLinus Torvalds 49*1da177e4SLinus Torvalds err: 50*1da177e4SLinus Torvalds printk("Error %d while decompressing!\n", err); 51*1da177e4SLinus Torvalds printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen); 52*1da177e4SLinus Torvalds return 0; 53*1da177e4SLinus Torvalds } 54*1da177e4SLinus Torvalds 55*1da177e4SLinus Torvalds int cramfs_uncompress_init(void) 56*1da177e4SLinus Torvalds { 57*1da177e4SLinus Torvalds if (!initialized++) { 58*1da177e4SLinus Torvalds stream.workspace = vmalloc(zlib_inflate_workspacesize()); 59*1da177e4SLinus Torvalds if ( !stream.workspace ) { 60*1da177e4SLinus Torvalds initialized = 0; 61*1da177e4SLinus Torvalds return -ENOMEM; 62*1da177e4SLinus Torvalds } 63*1da177e4SLinus Torvalds stream.next_in = NULL; 64*1da177e4SLinus Torvalds stream.avail_in = 0; 65*1da177e4SLinus Torvalds zlib_inflateInit(&stream); 66*1da177e4SLinus Torvalds } 67*1da177e4SLinus Torvalds return 0; 68*1da177e4SLinus Torvalds } 69*1da177e4SLinus Torvalds 70*1da177e4SLinus Torvalds int cramfs_uncompress_exit(void) 71*1da177e4SLinus Torvalds { 72*1da177e4SLinus Torvalds if (!--initialized) { 73*1da177e4SLinus Torvalds zlib_inflateEnd(&stream); 74*1da177e4SLinus Torvalds vfree(stream.workspace); 75*1da177e4SLinus Torvalds } 76*1da177e4SLinus Torvalds return 0; 77*1da177e4SLinus Torvalds } 78