mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-05 10:04:12 +08:00
68252eb5f8
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 or at your option any later version this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details you should have received a copy of the gnu general public license along with this program if not write to the free software foundation 51 franklin street fifth floor boston ma 02110 1301 usa extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 23 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190520170857.458548087@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
118 lines
2.4 KiB
C
118 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Squashfs - a compressed read only filesystem for Linux
|
|
*
|
|
* Copyright (c) 2010 LG Electronics
|
|
* Chan Jeong <chan.jeong@lge.com>
|
|
*
|
|
* lzo_wrapper.c
|
|
*/
|
|
|
|
#include <linux/mutex.h>
|
|
#include <linux/buffer_head.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/lzo.h>
|
|
|
|
#include "squashfs_fs.h"
|
|
#include "squashfs_fs_sb.h"
|
|
#include "squashfs.h"
|
|
#include "decompressor.h"
|
|
#include "page_actor.h"
|
|
|
|
struct squashfs_lzo {
|
|
void *input;
|
|
void *output;
|
|
};
|
|
|
|
static void *lzo_init(struct squashfs_sb_info *msblk, void *buff)
|
|
{
|
|
int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
|
|
|
|
struct squashfs_lzo *stream = kzalloc(sizeof(*stream), GFP_KERNEL);
|
|
if (stream == NULL)
|
|
goto failed;
|
|
stream->input = vmalloc(block_size);
|
|
if (stream->input == NULL)
|
|
goto failed;
|
|
stream->output = vmalloc(block_size);
|
|
if (stream->output == NULL)
|
|
goto failed2;
|
|
|
|
return stream;
|
|
|
|
failed2:
|
|
vfree(stream->input);
|
|
failed:
|
|
ERROR("Failed to allocate lzo workspace\n");
|
|
kfree(stream);
|
|
return ERR_PTR(-ENOMEM);
|
|
}
|
|
|
|
|
|
static void lzo_free(void *strm)
|
|
{
|
|
struct squashfs_lzo *stream = strm;
|
|
|
|
if (stream) {
|
|
vfree(stream->input);
|
|
vfree(stream->output);
|
|
}
|
|
kfree(stream);
|
|
}
|
|
|
|
|
|
static int lzo_uncompress(struct squashfs_sb_info *msblk, void *strm,
|
|
struct buffer_head **bh, int b, int offset, int length,
|
|
struct squashfs_page_actor *output)
|
|
{
|
|
struct squashfs_lzo *stream = strm;
|
|
void *buff = stream->input, *data;
|
|
int avail, i, bytes = length, res;
|
|
size_t out_len = output->length;
|
|
|
|
for (i = 0; i < b; i++) {
|
|
avail = min(bytes, msblk->devblksize - offset);
|
|
memcpy(buff, bh[i]->b_data + offset, avail);
|
|
buff += avail;
|
|
bytes -= avail;
|
|
offset = 0;
|
|
put_bh(bh[i]);
|
|
}
|
|
|
|
res = lzo1x_decompress_safe(stream->input, (size_t)length,
|
|
stream->output, &out_len);
|
|
if (res != LZO_E_OK)
|
|
goto failed;
|
|
|
|
res = bytes = (int)out_len;
|
|
data = squashfs_first_page(output);
|
|
buff = stream->output;
|
|
while (data) {
|
|
if (bytes <= PAGE_SIZE) {
|
|
memcpy(data, buff, bytes);
|
|
break;
|
|
} else {
|
|
memcpy(data, buff, PAGE_SIZE);
|
|
buff += PAGE_SIZE;
|
|
bytes -= PAGE_SIZE;
|
|
data = squashfs_next_page(output);
|
|
}
|
|
}
|
|
squashfs_finish_page(output);
|
|
|
|
return res;
|
|
|
|
failed:
|
|
return -EIO;
|
|
}
|
|
|
|
const struct squashfs_decompressor squashfs_lzo_comp_ops = {
|
|
.init = lzo_init,
|
|
.free = lzo_free,
|
|
.decompress = lzo_uncompress,
|
|
.id = LZO_COMPRESSION,
|
|
.name = "lzo",
|
|
.supported = 1
|
|
};
|