wok-next annotate linux-libre/stuff/004-squashfs-add-xz-compression-support.patch @ rev 16567

Up: slitaz-boot-scripts + slitaz-tools (urgent bug fix)
author Christophe Lincoln <pankso@slitaz.org>
date Thu May 01 22:17:02 2014 +0200 (2014-05-01)
parents
children
rev   line source
gokhlayeh@9257 1 From: Phillip Lougher <phillip@lougher.demon.co.uk>
gokhlayeh@9257 2 Date: Thu, 9 Dec 2010 02:02:29 +0000 (+0000)
gokhlayeh@9257 3 Subject: Squashfs: add XZ compression support
gokhlayeh@9257 4 X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fpkl%2Fsquashfs-xz.git;a=commitdiff_plain;h=d3e6969b9ff1f3a3c6bf3da71433c77046aa80e4
gokhlayeh@9257 5
gokhlayeh@9257 6 Squashfs: add XZ compression support
gokhlayeh@9257 7
gokhlayeh@9257 8 Add XZ decompressor wrapper code.
gokhlayeh@9257 9
gokhlayeh@9257 10 Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
gokhlayeh@9257 11 ---
gokhlayeh@9257 12
gokhlayeh@9257 13 diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
gokhlayeh@9257 14 index c5137fc..39533fe 100644
gokhlayeh@9257 15 --- a/fs/squashfs/squashfs_fs.h
gokhlayeh@9257 16 +++ b/fs/squashfs/squashfs_fs.h
gokhlayeh@9257 17 @@ -238,6 +238,7 @@ struct meta_index {
gokhlayeh@9257 18 #define ZLIB_COMPRESSION 1
gokhlayeh@9257 19 #define LZMA_COMPRESSION 2
gokhlayeh@9257 20 #define LZO_COMPRESSION 3
gokhlayeh@9257 21 +#define XZ_COMPRESSION 4
gokhlayeh@9257 22
gokhlayeh@9257 23 struct squashfs_super_block {
gokhlayeh@9257 24 __le32 s_magic;
gokhlayeh@9257 25 diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c
gokhlayeh@9257 26 new file mode 100644
gokhlayeh@9257 27 index 0000000..053fe35
gokhlayeh@9257 28 --- /dev/null
gokhlayeh@9257 29 +++ b/fs/squashfs/xz_wrapper.c
gokhlayeh@9257 30 @@ -0,0 +1,153 @@
gokhlayeh@9257 31 +/*
gokhlayeh@9257 32 + * Squashfs - a compressed read only filesystem for Linux
gokhlayeh@9257 33 + *
gokhlayeh@9257 34 + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
gokhlayeh@9257 35 + * Phillip Lougher <phillip@lougher.demon.co.uk>
gokhlayeh@9257 36 + *
gokhlayeh@9257 37 + * This program is free software; you can redistribute it and/or
gokhlayeh@9257 38 + * modify it under the terms of the GNU General Public License
gokhlayeh@9257 39 + * as published by the Free Software Foundation; either version 2,
gokhlayeh@9257 40 + * or (at your option) any later version.
gokhlayeh@9257 41 + *
gokhlayeh@9257 42 + * This program is distributed in the hope that it will be useful,
gokhlayeh@9257 43 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
gokhlayeh@9257 44 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
gokhlayeh@9257 45 + * GNU General Public License for more details.
gokhlayeh@9257 46 + *
gokhlayeh@9257 47 + * You should have received a copy of the GNU General Public License
gokhlayeh@9257 48 + * along with this program; if not, write to the Free Software
gokhlayeh@9257 49 + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
gokhlayeh@9257 50 + *
gokhlayeh@9257 51 + * xz_wrapper.c
gokhlayeh@9257 52 + */
gokhlayeh@9257 53 +
gokhlayeh@9257 54 +
gokhlayeh@9257 55 +#include <linux/mutex.h>
gokhlayeh@9257 56 +#include <linux/buffer_head.h>
gokhlayeh@9257 57 +#include <linux/slab.h>
gokhlayeh@9257 58 +#include <linux/xz.h>
gokhlayeh@9257 59 +
gokhlayeh@9257 60 +#include "squashfs_fs.h"
gokhlayeh@9257 61 +#include "squashfs_fs_sb.h"
gokhlayeh@9257 62 +#include "squashfs_fs_i.h"
gokhlayeh@9257 63 +#include "squashfs.h"
gokhlayeh@9257 64 +#include "decompressor.h"
gokhlayeh@9257 65 +
gokhlayeh@9257 66 +struct squashfs_xz {
gokhlayeh@9257 67 + struct xz_dec *state;
gokhlayeh@9257 68 + struct xz_buf buf;
gokhlayeh@9257 69 +};
gokhlayeh@9257 70 +
gokhlayeh@9257 71 +static void *squashfs_xz_init(struct squashfs_sb_info *msblk)
gokhlayeh@9257 72 +{
gokhlayeh@9257 73 + int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
gokhlayeh@9257 74 +
gokhlayeh@9257 75 + struct squashfs_xz *stream = kmalloc(sizeof(*stream), GFP_KERNEL);
gokhlayeh@9257 76 + if (stream == NULL)
gokhlayeh@9257 77 + goto failed;
gokhlayeh@9257 78 + stream->state = xz_dec_init(XZ_PREALLOC, block_size);
gokhlayeh@9257 79 + if (stream->state == NULL)
gokhlayeh@9257 80 + goto failed;
gokhlayeh@9257 81 +
gokhlayeh@9257 82 + return stream;
gokhlayeh@9257 83 +
gokhlayeh@9257 84 +failed:
gokhlayeh@9257 85 + ERROR("Failed to allocate xz workspace\n");
gokhlayeh@9257 86 + kfree(stream);
gokhlayeh@9257 87 + return NULL;
gokhlayeh@9257 88 +}
gokhlayeh@9257 89 +
gokhlayeh@9257 90 +
gokhlayeh@9257 91 +static void squashfs_xz_free(void *strm)
gokhlayeh@9257 92 +{
gokhlayeh@9257 93 + struct squashfs_xz *stream = strm;
gokhlayeh@9257 94 +
gokhlayeh@9257 95 + if (stream) {
gokhlayeh@9257 96 + xz_dec_end(stream->state);
gokhlayeh@9257 97 + kfree(stream);
gokhlayeh@9257 98 + }
gokhlayeh@9257 99 +}
gokhlayeh@9257 100 +
gokhlayeh@9257 101 +
gokhlayeh@9257 102 +static int squashfs_xz_uncompress(struct squashfs_sb_info *msblk, void **buffer,
gokhlayeh@9257 103 + struct buffer_head **bh, int b, int offset, int length, int srclength,
gokhlayeh@9257 104 + int pages)
gokhlayeh@9257 105 +{
gokhlayeh@9257 106 + enum xz_ret xz_err;
gokhlayeh@9257 107 + int avail, total = 0, k = 0, page = 0;
gokhlayeh@9257 108 + struct squashfs_xz *stream = msblk->stream;
gokhlayeh@9257 109 +
gokhlayeh@9257 110 + mutex_lock(&msblk->read_data_mutex);
gokhlayeh@9257 111 +
gokhlayeh@9257 112 + xz_dec_reset(stream->state);
gokhlayeh@9257 113 + stream->buf.in_pos = 0;
gokhlayeh@9257 114 + stream->buf.in_size = 0;
gokhlayeh@9257 115 + stream->buf.out_pos = 0;
gokhlayeh@9257 116 + stream->buf.out_size = PAGE_CACHE_SIZE;
gokhlayeh@9257 117 + stream->buf.out = buffer[page++];
gokhlayeh@9257 118 +
gokhlayeh@9257 119 + do {
gokhlayeh@9257 120 + if (stream->buf.in_pos == stream->buf.in_size && k < b) {
gokhlayeh@9257 121 + avail = min(length, msblk->devblksize - offset);
gokhlayeh@9257 122 + length -= avail;
gokhlayeh@9257 123 + wait_on_buffer(bh[k]);
gokhlayeh@9257 124 + if (!buffer_uptodate(bh[k]))
gokhlayeh@9257 125 + goto release_mutex;
gokhlayeh@9257 126 +
gokhlayeh@9257 127 + if (avail == 0) {
gokhlayeh@9257 128 + offset = 0;
gokhlayeh@9257 129 + put_bh(bh[k++]);
gokhlayeh@9257 130 + continue;
gokhlayeh@9257 131 + }
gokhlayeh@9257 132 +
gokhlayeh@9257 133 + stream->buf.in = bh[k]->b_data + offset;
gokhlayeh@9257 134 + stream->buf.in_size = avail;
gokhlayeh@9257 135 + stream->buf.in_pos = 0;
gokhlayeh@9257 136 + offset = 0;
gokhlayeh@9257 137 + }
gokhlayeh@9257 138 +
gokhlayeh@9257 139 + if (stream->buf.out_pos == stream->buf.out_size
gokhlayeh@9257 140 + && page < pages) {
gokhlayeh@9257 141 + stream->buf.out = buffer[page++];
gokhlayeh@9257 142 + stream->buf.out_pos = 0;
gokhlayeh@9257 143 + total += PAGE_CACHE_SIZE;
gokhlayeh@9257 144 + }
gokhlayeh@9257 145 +
gokhlayeh@9257 146 + xz_err = xz_dec_run(stream->state, &stream->buf);
gokhlayeh@9257 147 +
gokhlayeh@9257 148 + if (stream->buf.in_pos == stream->buf.in_size && k < b)
gokhlayeh@9257 149 + put_bh(bh[k++]);
gokhlayeh@9257 150 + } while (xz_err == XZ_OK);
gokhlayeh@9257 151 +
gokhlayeh@9257 152 + if (xz_err != XZ_STREAM_END) {
gokhlayeh@9257 153 + ERROR("xz_dec_run error, data probably corrupt\n");
gokhlayeh@9257 154 + goto release_mutex;
gokhlayeh@9257 155 + }
gokhlayeh@9257 156 +
gokhlayeh@9257 157 + if (k < b) {
gokhlayeh@9257 158 + ERROR("xz_uncompress error, input remaining\n");
gokhlayeh@9257 159 + goto release_mutex;
gokhlayeh@9257 160 + }
gokhlayeh@9257 161 +
gokhlayeh@9257 162 + total += stream->buf.out_pos;
gokhlayeh@9257 163 + mutex_unlock(&msblk->read_data_mutex);
gokhlayeh@9257 164 + return total;
gokhlayeh@9257 165 +
gokhlayeh@9257 166 +release_mutex:
gokhlayeh@9257 167 + mutex_unlock(&msblk->read_data_mutex);
gokhlayeh@9257 168 +
gokhlayeh@9257 169 + for (; k < b; k++)
gokhlayeh@9257 170 + put_bh(bh[k]);
gokhlayeh@9257 171 +
gokhlayeh@9257 172 + return -EIO;
gokhlayeh@9257 173 +}
gokhlayeh@9257 174 +
gokhlayeh@9257 175 +const struct squashfs_decompressor squashfs_xz_comp_ops = {
gokhlayeh@9257 176 + .init = squashfs_xz_init,
gokhlayeh@9257 177 + .free = squashfs_xz_free,
gokhlayeh@9257 178 + .decompress = squashfs_xz_uncompress,
gokhlayeh@9257 179 + .id = XZ_COMPRESSION,
gokhlayeh@9257 180 + .name = "xz",
gokhlayeh@9257 181 + .supported = 1
gokhlayeh@9257 182 +};
gokhlayeh@9257 183 +