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