aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-16 15:11:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-16 15:11:13 -0500
commit5520ebd308927a3beba599a2b68fa8c52f41f43b (patch)
treeb0395c15af7d096e6e6172a9d47bb7a8dec6add0
parentd3072e6a7e9bf7aca200370317f8e297be360b17 (diff)
parent01a678c5a2f41663b8faf03d17e2bbdbf44158a9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus: Squashfs: simplify CONFIG_SQUASHFS_LZO handling Squashfs: move squashfs_i() definition from squashfs.h Squashfs: get rid of default n in Kconfig Squashfs: add missing check in zlib_wrapper Squashfs: remove unnecessary variable in zlib_wrapper Squashfs: Add XZ compression configuration option Squashfs: add XZ compression support
-rw-r--r--fs/squashfs/Kconfig18
-rw-r--r--fs/squashfs/Makefile1
-rw-r--r--fs/squashfs/block.c1
-rw-r--r--fs/squashfs/cache.c1
-rw-r--r--fs/squashfs/decompressor.c16
-rw-r--r--fs/squashfs/decompressor.h9
-rw-r--r--fs/squashfs/fragment.c1
-rw-r--r--fs/squashfs/id.c1
-rw-r--r--fs/squashfs/lzo_wrapper.c1
-rw-r--r--fs/squashfs/squashfs.h8
-rw-r--r--fs/squashfs/squashfs_fs.h1
-rw-r--r--fs/squashfs/squashfs_fs_i.h6
-rw-r--r--fs/squashfs/xattr_id.c1
-rw-r--r--fs/squashfs/xz_wrapper.c153
-rw-r--r--fs/squashfs/zlib_wrapper.c15
15 files changed, 203 insertions, 30 deletions
diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
index e5f63da64d04..aa68a8a31518 100644
--- a/fs/squashfs/Kconfig
+++ b/fs/squashfs/Kconfig
@@ -29,7 +29,6 @@ config SQUASHFS
29config SQUASHFS_XATTR 29config SQUASHFS_XATTR
30 bool "Squashfs XATTR support" 30 bool "Squashfs XATTR support"
31 depends on SQUASHFS 31 depends on SQUASHFS
32 default n
33 help 32 help
34 Saying Y here includes support for extended attributes (xattrs). 33 Saying Y here includes support for extended attributes (xattrs).
35 Xattrs are name:value pairs associated with inodes by 34 Xattrs are name:value pairs associated with inodes by
@@ -40,7 +39,6 @@ config SQUASHFS_XATTR
40config SQUASHFS_LZO 39config SQUASHFS_LZO
41 bool "Include support for LZO compressed file systems" 40 bool "Include support for LZO compressed file systems"
42 depends on SQUASHFS 41 depends on SQUASHFS
43 default n
44 select LZO_DECOMPRESS 42 select LZO_DECOMPRESS
45 help 43 help
46 Saying Y here includes support for reading Squashfs file systems 44 Saying Y here includes support for reading Squashfs file systems
@@ -53,10 +51,24 @@ config SQUASHFS_LZO
53 51
54 If unsure, say N. 52 If unsure, say N.
55 53
54config SQUASHFS_XZ
55 bool "Include support for XZ compressed file systems"
56 depends on SQUASHFS
57 select XZ_DEC
58 help
59 Saying Y here includes support for reading Squashfs file systems
60 compressed with XZ compresssion. XZ gives better compression than
61 the default zlib compression, at the expense of greater CPU and
62 memory overhead.
63
64 XZ is not the standard compression used in Squashfs and so most
65 file systems will be readable without selecting this option.
66
67 If unsure, say N.
68
56config SQUASHFS_EMBEDDED 69config SQUASHFS_EMBEDDED
57 bool "Additional option for memory-constrained systems" 70 bool "Additional option for memory-constrained systems"
58 depends on SQUASHFS 71 depends on SQUASHFS
59 default n
60 help 72 help
61 Saying Y here allows you to specify cache size. 73 Saying Y here allows you to specify cache size.
62 74
diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile
index 7672bac8d328..cecf2bea07af 100644
--- a/fs/squashfs/Makefile
+++ b/fs/squashfs/Makefile
@@ -7,3 +7,4 @@ squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
7squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o 7squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o
8squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o 8squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o
9squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o 9squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o
10squashfs-$(CONFIG_SQUASHFS_XZ) += xz_wrapper.o
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c
index 653c030eb840..2fb2882f0fa7 100644
--- a/fs/squashfs/block.c
+++ b/fs/squashfs/block.c
@@ -34,7 +34,6 @@
34 34
35#include "squashfs_fs.h" 35#include "squashfs_fs.h"
36#include "squashfs_fs_sb.h" 36#include "squashfs_fs_sb.h"
37#include "squashfs_fs_i.h"
38#include "squashfs.h" 37#include "squashfs.h"
39#include "decompressor.h" 38#include "decompressor.h"
40 39
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 57314bee9059..26b15ae34d6f 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -55,7 +55,6 @@
55 55
56#include "squashfs_fs.h" 56#include "squashfs_fs.h"
57#include "squashfs_fs_sb.h" 57#include "squashfs_fs_sb.h"
58#include "squashfs_fs_i.h"
59#include "squashfs.h" 58#include "squashfs.h"
60 59
61/* 60/*
diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c
index 24af9ce9722f..a5940e54c4dd 100644
--- a/fs/squashfs/decompressor.c
+++ b/fs/squashfs/decompressor.c
@@ -27,7 +27,6 @@
27 27
28#include "squashfs_fs.h" 28#include "squashfs_fs.h"
29#include "squashfs_fs_sb.h" 29#include "squashfs_fs_sb.h"
30#include "squashfs_fs_i.h"
31#include "decompressor.h" 30#include "decompressor.h"
32#include "squashfs.h" 31#include "squashfs.h"
33 32
@@ -41,23 +40,26 @@ static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = {
41}; 40};
42 41
43#ifndef CONFIG_SQUASHFS_LZO 42#ifndef CONFIG_SQUASHFS_LZO
44static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = { 43static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
45 NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 44 NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
46}; 45};
47#endif 46#endif
48 47
48#ifndef CONFIG_SQUASHFS_XZ
49static const struct squashfs_decompressor squashfs_xz_comp_ops = {
50 NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0
51};
52#endif
53
49static const struct squashfs_decompressor squashfs_unknown_comp_ops = { 54static const struct squashfs_decompressor squashfs_unknown_comp_ops = {
50 NULL, NULL, NULL, 0, "unknown", 0 55 NULL, NULL, NULL, 0, "unknown", 0
51}; 56};
52 57
53static const struct squashfs_decompressor *decompressor[] = { 58static const struct squashfs_decompressor *decompressor[] = {
54 &squashfs_zlib_comp_ops, 59 &squashfs_zlib_comp_ops,
55 &squashfs_lzma_unsupported_comp_ops,
56#ifdef CONFIG_SQUASHFS_LZO
57 &squashfs_lzo_comp_ops, 60 &squashfs_lzo_comp_ops,
58#else 61 &squashfs_xz_comp_ops,
59 &squashfs_lzo_unsupported_comp_ops, 62 &squashfs_lzma_unsupported_comp_ops,
60#endif
61 &squashfs_unknown_comp_ops 63 &squashfs_unknown_comp_ops
62}; 64};
63 65
diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h
index 7425f80783f6..3b305a70f7aa 100644
--- a/fs/squashfs/decompressor.h
+++ b/fs/squashfs/decompressor.h
@@ -52,4 +52,13 @@ static inline int squashfs_decompress(struct squashfs_sb_info *msblk,
52 return msblk->decompressor->decompress(msblk, buffer, bh, b, offset, 52 return msblk->decompressor->decompress(msblk, buffer, bh, b, offset,
53 length, srclength, pages); 53 length, srclength, pages);
54} 54}
55
56#ifdef CONFIG_SQUASHFS_XZ
57extern const struct squashfs_decompressor squashfs_xz_comp_ops;
58#endif
59
60#ifdef CONFIG_SQUASHFS_LZO
61extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
62#endif
63
55#endif 64#endif
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
index 7c90bbd6879d..7eef571443c6 100644
--- a/fs/squashfs/fragment.c
+++ b/fs/squashfs/fragment.c
@@ -39,7 +39,6 @@
39 39
40#include "squashfs_fs.h" 40#include "squashfs_fs.h"
41#include "squashfs_fs_sb.h" 41#include "squashfs_fs_sb.h"
42#include "squashfs_fs_i.h"
43#include "squashfs.h" 42#include "squashfs.h"
44 43
45/* 44/*
diff --git a/fs/squashfs/id.c b/fs/squashfs/id.c
index b7f64bcd2b70..d8f32452638e 100644
--- a/fs/squashfs/id.c
+++ b/fs/squashfs/id.c
@@ -37,7 +37,6 @@
37 37
38#include "squashfs_fs.h" 38#include "squashfs_fs.h"
39#include "squashfs_fs_sb.h" 39#include "squashfs_fs_sb.h"
40#include "squashfs_fs_i.h"
41#include "squashfs.h" 40#include "squashfs.h"
42 41
43/* 42/*
diff --git a/fs/squashfs/lzo_wrapper.c b/fs/squashfs/lzo_wrapper.c
index 5d87789bf1c1..7da759e34c52 100644
--- a/fs/squashfs/lzo_wrapper.c
+++ b/fs/squashfs/lzo_wrapper.c
@@ -29,7 +29,6 @@
29 29
30#include "squashfs_fs.h" 30#include "squashfs_fs.h"
31#include "squashfs_fs_sb.h" 31#include "squashfs_fs_sb.h"
32#include "squashfs_fs_i.h"
33#include "squashfs.h" 32#include "squashfs.h"
34#include "decompressor.h" 33#include "decompressor.h"
35 34
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
index 5d45569d5f72..ba729d808876 100644
--- a/fs/squashfs/squashfs.h
+++ b/fs/squashfs/squashfs.h
@@ -27,11 +27,6 @@
27 27
28#define WARNING(s, args...) pr_warning("SQUASHFS: "s, ## args) 28#define WARNING(s, args...) pr_warning("SQUASHFS: "s, ## args)
29 29
30static inline struct squashfs_inode_info *squashfs_i(struct inode *inode)
31{
32 return list_entry(inode, struct squashfs_inode_info, vfs_inode);
33}
34
35/* block.c */ 30/* block.c */
36extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *, 31extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *,
37 int, int); 32 int, int);
@@ -104,6 +99,3 @@ extern const struct xattr_handler *squashfs_xattr_handlers[];
104 99
105/* zlib_wrapper.c */ 100/* zlib_wrapper.c */
106extern const struct squashfs_decompressor squashfs_zlib_comp_ops; 101extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
107
108/* lzo_wrapper.c */
109extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index c5137fc9ab11..39533feffd6d 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -238,6 +238,7 @@ struct meta_index {
238#define ZLIB_COMPRESSION 1 238#define ZLIB_COMPRESSION 1
239#define LZMA_COMPRESSION 2 239#define LZMA_COMPRESSION 2
240#define LZO_COMPRESSION 3 240#define LZO_COMPRESSION 3
241#define XZ_COMPRESSION 4
241 242
242struct squashfs_super_block { 243struct squashfs_super_block {
243 __le32 s_magic; 244 __le32 s_magic;
diff --git a/fs/squashfs/squashfs_fs_i.h b/fs/squashfs/squashfs_fs_i.h
index d3e3a37f28a1..359baefc01fc 100644
--- a/fs/squashfs/squashfs_fs_i.h
+++ b/fs/squashfs/squashfs_fs_i.h
@@ -45,4 +45,10 @@ struct squashfs_inode_info {
45 }; 45 };
46 struct inode vfs_inode; 46 struct inode vfs_inode;
47}; 47};
48
49
50static inline struct squashfs_inode_info *squashfs_i(struct inode *inode)
51{
52 return list_entry(inode, struct squashfs_inode_info, vfs_inode);
53}
48#endif 54#endif
diff --git a/fs/squashfs/xattr_id.c b/fs/squashfs/xattr_id.c
index d33be5dd6c32..05385dbe1465 100644
--- a/fs/squashfs/xattr_id.c
+++ b/fs/squashfs/xattr_id.c
@@ -32,7 +32,6 @@
32 32
33#include "squashfs_fs.h" 33#include "squashfs_fs.h"
34#include "squashfs_fs_sb.h" 34#include "squashfs_fs_sb.h"
35#include "squashfs_fs_i.h"
36#include "squashfs.h" 35#include "squashfs.h"
37#include "xattr.h" 36#include "xattr.h"
38 37
diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c
new file mode 100644
index 000000000000..856756ca5ee4
--- /dev/null
+++ b/fs/squashfs/xz_wrapper.c
@@ -0,0 +1,153 @@
1/*
2 * Squashfs - a compressed read only filesystem for Linux
3 *
4 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 * Phillip Lougher <phillip@lougher.demon.co.uk>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 * xz_wrapper.c
22 */
23
24
25#include <linux/mutex.h>
26#include <linux/buffer_head.h>
27#include <linux/slab.h>
28#include <linux/xz.h>
29
30#include "squashfs_fs.h"
31#include "squashfs_fs_sb.h"
32#include "squashfs_fs_i.h"
33#include "squashfs.h"
34#include "decompressor.h"
35
36struct squashfs_xz {
37 struct xz_dec *state;
38 struct xz_buf buf;
39};
40
41static void *squashfs_xz_init(struct squashfs_sb_info *msblk)
42{
43 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
44
45 struct squashfs_xz *stream = kmalloc(sizeof(*stream), GFP_KERNEL);
46 if (stream == NULL)
47 goto failed;
48
49 stream->state = xz_dec_init(XZ_PREALLOC, block_size);
50 if (stream->state == NULL)
51 goto failed;
52
53 return stream;
54
55failed:
56 ERROR("Failed to allocate xz workspace\n");
57 kfree(stream);
58 return NULL;
59}
60
61
62static void squashfs_xz_free(void *strm)
63{
64 struct squashfs_xz *stream = strm;
65
66 if (stream) {
67 xz_dec_end(stream->state);
68 kfree(stream);
69 }
70}
71
72
73static int squashfs_xz_uncompress(struct squashfs_sb_info *msblk, void **buffer,
74 struct buffer_head **bh, int b, int offset, int length, int srclength,
75 int pages)
76{
77 enum xz_ret xz_err;
78 int avail, total = 0, k = 0, page = 0;
79 struct squashfs_xz *stream = msblk->stream;
80
81 mutex_lock(&msblk->read_data_mutex);
82
83 xz_dec_reset(stream->state);
84 stream->buf.in_pos = 0;
85 stream->buf.in_size = 0;
86 stream->buf.out_pos = 0;
87 stream->buf.out_size = PAGE_CACHE_SIZE;
88 stream->buf.out = buffer[page++];
89
90 do {
91 if (stream->buf.in_pos == stream->buf.in_size && k < b) {
92 avail = min(length, msblk->devblksize - offset);
93 length -= avail;
94 wait_on_buffer(bh[k]);
95 if (!buffer_uptodate(bh[k]))
96 goto release_mutex;
97
98 if (avail == 0) {
99 offset = 0;
100 put_bh(bh[k++]);
101 continue;
102 }
103
104 stream->buf.in = bh[k]->b_data + offset;
105 stream->buf.in_size = avail;
106 stream->buf.in_pos = 0;
107 offset = 0;
108 }
109
110 if (stream->buf.out_pos == stream->buf.out_size
111 && page < pages) {
112 stream->buf.out = buffer[page++];
113 stream->buf.out_pos = 0;
114 total += PAGE_CACHE_SIZE;
115 }
116
117 xz_err = xz_dec_run(stream->state, &stream->buf);
118
119 if (stream->buf.in_pos == stream->buf.in_size && k < b)
120 put_bh(bh[k++]);
121 } while (xz_err == XZ_OK);
122
123 if (xz_err != XZ_STREAM_END) {
124 ERROR("xz_dec_run error, data probably corrupt\n");
125 goto release_mutex;
126 }
127
128 if (k < b) {
129 ERROR("xz_uncompress error, input remaining\n");
130 goto release_mutex;
131 }
132
133 total += stream->buf.out_pos;
134 mutex_unlock(&msblk->read_data_mutex);
135 return total;
136
137release_mutex:
138 mutex_unlock(&msblk->read_data_mutex);
139
140 for (; k < b; k++)
141 put_bh(bh[k]);
142
143 return -EIO;
144}
145
146const struct squashfs_decompressor squashfs_xz_comp_ops = {
147 .init = squashfs_xz_init,
148 .free = squashfs_xz_free,
149 .decompress = squashfs_xz_uncompress,
150 .id = XZ_COMPRESSION,
151 .name = "xz",
152 .supported = 1
153};
diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c
index 7a603874e483..818a5e063faf 100644
--- a/fs/squashfs/zlib_wrapper.c
+++ b/fs/squashfs/zlib_wrapper.c
@@ -29,7 +29,6 @@
29 29
30#include "squashfs_fs.h" 30#include "squashfs_fs.h"
31#include "squashfs_fs_sb.h" 31#include "squashfs_fs_sb.h"
32#include "squashfs_fs_i.h"
33#include "squashfs.h" 32#include "squashfs.h"
34#include "decompressor.h" 33#include "decompressor.h"
35 34
@@ -66,8 +65,8 @@ static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
66 struct buffer_head **bh, int b, int offset, int length, int srclength, 65 struct buffer_head **bh, int b, int offset, int length, int srclength,
67 int pages) 66 int pages)
68{ 67{
69 int zlib_err = 0, zlib_init = 0; 68 int zlib_err, zlib_init = 0;
70 int avail, bytes, k = 0, page = 0; 69 int k = 0, page = 0;
71 z_stream *stream = msblk->stream; 70 z_stream *stream = msblk->stream;
72 71
73 mutex_lock(&msblk->read_data_mutex); 72 mutex_lock(&msblk->read_data_mutex);
@@ -75,11 +74,10 @@ static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
75 stream->avail_out = 0; 74 stream->avail_out = 0;
76 stream->avail_in = 0; 75 stream->avail_in = 0;
77 76
78 bytes = length;
79 do { 77 do {
80 if (stream->avail_in == 0 && k < b) { 78 if (stream->avail_in == 0 && k < b) {
81 avail = min(bytes, msblk->devblksize - offset); 79 int avail = min(length, msblk->devblksize - offset);
82 bytes -= avail; 80 length -= avail;
83 wait_on_buffer(bh[k]); 81 wait_on_buffer(bh[k]);
84 if (!buffer_uptodate(bh[k])) 82 if (!buffer_uptodate(bh[k]))
85 goto release_mutex; 83 goto release_mutex;
@@ -128,6 +126,11 @@ static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
128 goto release_mutex; 126 goto release_mutex;
129 } 127 }
130 128
129 if (k < b) {
130 ERROR("zlib_uncompress error, data remaining\n");
131 goto release_mutex;
132 }
133
131 length = stream->total_out; 134 length = stream->total_out;
132 mutex_unlock(&msblk->read_data_mutex); 135 mutex_unlock(&msblk->read_data_mutex);
133 return length; 136 return length;