From: Geert Uytterhoeven <Geert.Uytterhoeven@xxxxxxxxxxx> Modify SquashFS 3.4 to use the "zlib" crypto module instead of making direct calls to the zlib/inflate library Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@xxxxxxxxxxx> --- fs/Kconfig | 3 + fs/squashfs/inode.c | 65 +++++++++++++++++++++-------------------- include/linux/squashfs_fs_sb.h | 3 + 3 files changed, 38 insertions(+), 33 deletions(-) --- a/fs/Kconfig +++ b/fs/Kconfig @@ -1350,7 +1350,8 @@ config CRAMFS config SQUASHFS tristate "SquashFS 3.4 - Squashed file system support" - select ZLIB_INFLATE + select CRYPTO + select CRYPTO_ZLIB help Saying Y here includes support for SquashFS 3.4 (a Compressed Read-Only File System). Squashfs is a highly compressed read-only --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c @@ -23,7 +23,6 @@ #include <linux/squashfs_fs.h> #include <linux/module.h> -#include <linux/zlib.h> #include <linux/fs.h> #include <linux/squashfs_fs_sb.h> #include <linux/squashfs_fs_i.h> @@ -36,6 +35,9 @@ #include "squashfs.h" +#define SQUASHFS_CRYPTO_ALG "zlib" + + static struct dentry *squashfs_fh_to_dentry(struct super_block *s, struct fid *fid, int fh_len, int fh_type); static struct dentry *squashfs_fh_to_parent(struct super_block *s, @@ -236,7 +238,10 @@ SQSH_EXTERN unsigned int squashfs_read_d } if (compressed) { - int zlib_err = 0; + int error = 0; + void *next_out; + int avail_out; + unsigned int total_out = 0, dlen; /* * uncompress block @@ -244,8 +249,8 @@ SQSH_EXTERN unsigned int squashfs_read_d mutex_lock(&msblk->read_data_mutex); - msblk->stream.next_out = buffer; - msblk->stream.avail_out = srclength; + next_out = buffer; + avail_out = srclength; for (bytes = 0; k < b; k++) { avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); @@ -254,16 +259,8 @@ SQSH_EXTERN unsigned int squashfs_read_d if (!buffer_uptodate(bh[k])) goto release_mutex; - msblk->stream.next_in = bh[k]->b_data + offset; - msblk->stream.avail_in = avail_bytes; - if (k == 0) { - zlib_err = zlib_inflateInit(&msblk->stream); - if (zlib_err != Z_OK) { - ERROR("zlib_inflateInit returned unexpected result 0x%x," - " srclength %d\n", zlib_err, srclength); - goto release_mutex; - } + total_out = 0; if (avail_bytes == 0) { offset = 0; @@ -272,29 +269,32 @@ SQSH_EXTERN unsigned int squashfs_read_d } } - zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); - if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) { - ERROR("zlib_inflate returned unexpected result 0x%x," - " srclength %d, avail_in %d, avail_out %d\n", zlib_err, - srclength, msblk->stream.avail_in, msblk->stream.avail_out); + dlen = avail_out; + error = crypto_comp_decompress(msblk->tfm, + bh[k]->b_data + offset, + avail_bytes, next_out, + &dlen); + if (error && error != -EAGAIN) { + ERROR("crypto_comp_decompress returned " + "unexpected result %d, srclength %d, " + "avail_bytes %d, avail_out %d\n", + error, srclength, avail_bytes, + avail_out); goto release_mutex; } + next_out += dlen; + avail_out -= dlen; + total_out += dlen; bytes += avail_bytes; offset = 0; brelse(bh[k]); } - if (zlib_err != Z_STREAM_END) + if (error) goto release_mutex; - zlib_err = zlib_inflateEnd(&msblk->stream); - if (zlib_err != Z_OK) { - ERROR("zlib_inflateEnd returned unexpected result 0x%x," - " srclength %d\n", zlib_err, srclength); - goto release_mutex; - } - bytes = msblk->stream.total_out; + bytes = total_out; mutex_unlock(&msblk->read_data_mutex); } else { int i; @@ -1104,9 +1104,12 @@ static int squashfs_fill_super(struct su } msblk = s->s_fs_info; - msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()); - if (msblk->stream.workspace == NULL) { - ERROR("Failed to allocate zlib workspace\n"); + msblk->tfm = crypto_alloc_comp(SQUASHFS_CRYPTO_ALG, 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(msblk->tfm)) { + ERROR("Failed to load %s crypto module\n", + SQUASHFS_CRYPTO_ALG); + msblk->tfm = NULL; goto failure; } sblk = &msblk->sblk; @@ -1273,7 +1276,7 @@ failed_mount: vfree(msblk->read_page); squashfs_cache_delete(msblk->block_cache); kfree(msblk->fragment_index_2); - vfree(msblk->stream.workspace); + crypto_free_comp(msblk->tfm); kfree(s->s_fs_info); s->s_fs_info = NULL; return -EINVAL; @@ -2084,7 +2087,7 @@ static void squashfs_put_super(struct su kfree(sbi->fragment_index); kfree(sbi->fragment_index_2); kfree(sbi->meta_index); - vfree(sbi->stream.workspace); + crypto_free_comp(sbi->tfm); kfree(s->s_fs_info); s->s_fs_info = NULL; } --- a/include/linux/squashfs_fs_sb.h +++ b/include/linux/squashfs_fs_sb.h @@ -24,6 +24,7 @@ */ #include <linux/squashfs_fs.h> +#include <linux/crypto.h> struct squashfs_cache_entry { long long block; @@ -67,7 +68,7 @@ struct squashfs_sb_info { struct mutex read_page_mutex; struct mutex meta_index_mutex; struct meta_index *meta_index; - z_stream stream; + struct crypto_comp *tfm; long long *inode_lookup_table; int (*read_inode)(struct inode *i, squashfs_inode_t \ inode); -- With kind regards, Geert Uytterhoeven Software Architect Sony Techsoft Centre Europe The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium Phone: +32 (0)2 700 8453 Fax: +32 (0)2 700 8622 E-mail: Geert.Uytterhoeven@xxxxxxxxxxx Internet: http://www.sony-europe.com/ A division of Sony Europe (Belgium) N.V. VAT BE 0413.825.160 · RPR Brussels Fortis · BIC GEBABEBB · IBAN BE41293037680010 -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html