wok-tiny annotate kernel-modular/stuff/004-squashfs-add-xz-compression-support.patch @ rev 1

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