Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Squashfs - a compressed read only filesystem for Linux
  4 *
  5 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  6 * Phillip Lougher <phillip@squashfs.org.uk>
  7 *
  8 * zlib_wrapper.c
  9 */
 10
 11
 12#include <linux/mutex.h>
 13#include <linux/bio.h>
 14#include <linux/slab.h>
 15#include <linux/zlib.h>
 16#include <linux/vmalloc.h>
 17
 18#include "squashfs_fs.h"
 19#include "squashfs_fs_sb.h"
 20#include "squashfs.h"
 21#include "decompressor.h"
 22#include "page_actor.h"
 23
 24static void *zlib_init(struct squashfs_sb_info *dummy, void *buff)
 25{
 26	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
 27	if (stream == NULL)
 28		goto failed;
 29	stream->workspace = vmalloc(zlib_inflate_workspacesize());
 30	if (stream->workspace == NULL)
 31		goto failed;
 32
 33	return stream;
 34
 35failed:
 36	ERROR("Failed to allocate zlib workspace\n");
 37	kfree(stream);
 38	return ERR_PTR(-ENOMEM);
 39}
 40
 41
 42static void zlib_free(void *strm)
 43{
 44	z_stream *stream = strm;
 45
 46	if (stream)
 47		vfree(stream->workspace);
 48	kfree(stream);
 49}
 50
 51
 52static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm,
 53	struct bio *bio, int offset, int length,
 54	struct squashfs_page_actor *output)
 55{
 56	struct bvec_iter_all iter_all = {};
 57	struct bio_vec *bvec = bvec_init_iter_all(&iter_all);
 58	int zlib_init = 0, error = 0;
 59	z_stream *stream = strm;
 60
 61	stream->avail_out = PAGE_SIZE;
 62	stream->next_out = squashfs_first_page(output);
 63	stream->avail_in = 0;
 64
 65	if (IS_ERR(stream->next_out)) {
 66		error = PTR_ERR(stream->next_out);
 67		goto finish;
 68	}
 69
 70	for (;;) {
 71		int zlib_err;
 72
 73		if (stream->avail_in == 0) {
 74			const void *data;
 75			int avail;
 76
 77			if (!bio_next_segment(bio, &iter_all)) {
 78				/* Z_STREAM_END must be reached. */
 79				error = -EIO;
 80				break;
 81			}
 82
 83			avail = min(length, ((int)bvec->bv_len) - offset);
 84			data = bvec_virt(bvec);
 85			length -= avail;
 86			stream->next_in = data + offset;
 87			stream->avail_in = avail;
 88			offset = 0;
 89		}
 90
 91		if (stream->avail_out == 0) {
 92			stream->next_out = squashfs_next_page(output);
 93			if (IS_ERR(stream->next_out)) {
 94				error = PTR_ERR(stream->next_out);
 95				break;
 96			} else if (stream->next_out != NULL)
 97				stream->avail_out = PAGE_SIZE;
 98		}
 99
100		if (!zlib_init) {
101			zlib_err = zlib_inflateInit(stream);
102			if (zlib_err != Z_OK) {
103				error = -EIO;
104				break;
105			}
106			zlib_init = 1;
107		}
108
109		zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
110		if (zlib_err == Z_STREAM_END)
111			break;
112		if (zlib_err != Z_OK) {
113			error = -EIO;
114			break;
115		}
116	}
117
118finish:
 
 
 
119	squashfs_finish_page(output);
120
121	if (!error)
122		if (zlib_inflateEnd(stream) != Z_OK)
123			error = -EIO;
 
 
 
 
 
 
 
 
 
 
 
 
124
125	return error ? error : stream->total_out;
126}
127
128const struct squashfs_decompressor squashfs_zlib_comp_ops = {
129	.init = zlib_init,
130	.free = zlib_free,
131	.decompress = zlib_uncompress,
132	.id = ZLIB_COMPRESSION,
133	.name = "zlib",
134	.alloc_buffer = 1,
135	.supported = 1
136};
137
v5.4
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Squashfs - a compressed read only filesystem for Linux
  4 *
  5 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  6 * Phillip Lougher <phillip@squashfs.org.uk>
  7 *
  8 * zlib_wrapper.c
  9 */
 10
 11
 12#include <linux/mutex.h>
 13#include <linux/buffer_head.h>
 14#include <linux/slab.h>
 15#include <linux/zlib.h>
 16#include <linux/vmalloc.h>
 17
 18#include "squashfs_fs.h"
 19#include "squashfs_fs_sb.h"
 20#include "squashfs.h"
 21#include "decompressor.h"
 22#include "page_actor.h"
 23
 24static void *zlib_init(struct squashfs_sb_info *dummy, void *buff)
 25{
 26	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
 27	if (stream == NULL)
 28		goto failed;
 29	stream->workspace = vmalloc(zlib_inflate_workspacesize());
 30	if (stream->workspace == NULL)
 31		goto failed;
 32
 33	return stream;
 34
 35failed:
 36	ERROR("Failed to allocate zlib workspace\n");
 37	kfree(stream);
 38	return ERR_PTR(-ENOMEM);
 39}
 40
 41
 42static void zlib_free(void *strm)
 43{
 44	z_stream *stream = strm;
 45
 46	if (stream)
 47		vfree(stream->workspace);
 48	kfree(stream);
 49}
 50
 51
 52static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm,
 53	struct buffer_head **bh, int b, int offset, int length,
 54	struct squashfs_page_actor *output)
 55{
 56	int zlib_err, zlib_init = 0, k = 0;
 
 
 57	z_stream *stream = strm;
 58
 59	stream->avail_out = PAGE_SIZE;
 60	stream->next_out = squashfs_first_page(output);
 61	stream->avail_in = 0;
 62
 63	do {
 64		if (stream->avail_in == 0 && k < b) {
 65			int avail = min(length, msblk->devblksize - offset);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 66			length -= avail;
 67			stream->next_in = bh[k]->b_data + offset;
 68			stream->avail_in = avail;
 69			offset = 0;
 70		}
 71
 72		if (stream->avail_out == 0) {
 73			stream->next_out = squashfs_next_page(output);
 74			if (stream->next_out != NULL)
 
 
 
 75				stream->avail_out = PAGE_SIZE;
 76		}
 77
 78		if (!zlib_init) {
 79			zlib_err = zlib_inflateInit(stream);
 80			if (zlib_err != Z_OK) {
 81				squashfs_finish_page(output);
 82				goto out;
 83			}
 84			zlib_init = 1;
 85		}
 86
 87		zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
 
 
 
 
 
 
 
 88
 89		if (stream->avail_in == 0 && k < b)
 90			put_bh(bh[k++]);
 91	} while (zlib_err == Z_OK);
 92
 93	squashfs_finish_page(output);
 94
 95	if (zlib_err != Z_STREAM_END)
 96		goto out;
 97
 98	zlib_err = zlib_inflateEnd(stream);
 99	if (zlib_err != Z_OK)
100		goto out;
101
102	if (k < b)
103		goto out;
104
105	return stream->total_out;
106
107out:
108	for (; k < b; k++)
109		put_bh(bh[k]);
110
111	return -EIO;
112}
113
114const struct squashfs_decompressor squashfs_zlib_comp_ops = {
115	.init = zlib_init,
116	.free = zlib_free,
117	.decompress = zlib_uncompress,
118	.id = ZLIB_COMPRESSION,
119	.name = "zlib",
 
120	.supported = 1
121};
122