^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2013
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Phillip Lougher <phillip@squashfs.org.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "squashfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "squashfs_fs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "decompressor.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "squashfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * This file implements single-threaded decompression in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * decompressor framework
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct squashfs_stream {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) void *squashfs_decompressor_create(struct squashfs_sb_info *msblk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) void *comp_opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct squashfs_stream *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) stream = kmalloc(sizeof(*stream), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (stream == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) stream->stream = msblk->decompressor->init(msblk, comp_opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (IS_ERR(stream->stream)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) err = PTR_ERR(stream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) kfree(comp_opts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) mutex_init(&stream->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) kfree(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void squashfs_decompressor_destroy(struct squashfs_sb_info *msblk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct squashfs_stream *stream = msblk->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) msblk->decompressor->free(stream->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) kfree(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int squashfs_decompress(struct squashfs_sb_info *msblk, struct bio *bio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int offset, int length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct squashfs_page_actor *output)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct squashfs_stream *stream = msblk->stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) mutex_lock(&stream->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) res = msblk->decompressor->decompress(msblk, stream->stream, bio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) offset, length, output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) mutex_unlock(&stream->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ERROR("%s decompression failed, data probably corrupt\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) msblk->decompressor->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int squashfs_max_decompressors(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }