diff options
-rw-r--r-- | Documentation/filesystems/squashfs.txt | 2 | ||||
-rw-r--r-- | fs/squashfs/Kconfig | 25 | ||||
-rw-r--r-- | fs/squashfs/Makefile | 4 | ||||
-rw-r--r-- | fs/squashfs/decompressor.c | 6 | ||||
-rw-r--r-- | fs/squashfs/lzo_wrapper.c | 136 | ||||
-rw-r--r-- | fs/squashfs/squashfs.h | 3 | ||||
-rw-r--r-- | fs/squashfs/squashfs_fs.h | 20 | ||||
-rw-r--r-- | fs/squashfs/xattr.c | 4 | ||||
-rw-r--r-- | fs/squashfs/xattr.h | 2 |
9 files changed, 181 insertions, 21 deletions
diff --git a/Documentation/filesystems/squashfs.txt b/Documentation/filesystems/squashfs.txt index 203f7202cc9e..66699afd66ca 100644 --- a/Documentation/filesystems/squashfs.txt +++ b/Documentation/filesystems/squashfs.txt | |||
@@ -2,7 +2,7 @@ SQUASHFS 4.0 FILESYSTEM | |||
2 | ======================= | 2 | ======================= |
3 | 3 | ||
4 | Squashfs is a compressed read-only filesystem for Linux. | 4 | Squashfs is a compressed read-only filesystem for Linux. |
5 | It uses zlib compression to compress files, inodes and directories. | 5 | It uses zlib/lzo compression to compress files, inodes and directories. |
6 | Inodes in the system are very small and all blocks are packed to minimise | 6 | Inodes in the system are very small and all blocks are packed to minimise |
7 | data overhead. Block sizes greater than 4K are supported up to a maximum | 7 | data overhead. Block sizes greater than 4K are supported up to a maximum |
8 | of 1Mbytes (default block size 128K). | 8 | of 1Mbytes (default block size 128K). |
diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig index cc6ce8a84c21..e5f63da64d04 100644 --- a/fs/squashfs/Kconfig +++ b/fs/squashfs/Kconfig | |||
@@ -5,13 +5,13 @@ config SQUASHFS | |||
5 | help | 5 | help |
6 | Saying Y here includes support for SquashFS 4.0 (a Compressed | 6 | Saying Y here includes support for SquashFS 4.0 (a Compressed |
7 | Read-Only File System). Squashfs is a highly compressed read-only | 7 | Read-Only File System). Squashfs is a highly compressed read-only |
8 | filesystem for Linux. It uses zlib compression to compress both | 8 | filesystem for Linux. It uses zlib/lzo compression to compress both |
9 | files, inodes and directories. Inodes in the system are very small | 9 | files, inodes and directories. Inodes in the system are very small |
10 | and all blocks are packed to minimise data overhead. Block sizes | 10 | and all blocks are packed to minimise data overhead. Block sizes |
11 | greater than 4K are supported up to a maximum of 1 Mbytes (default | 11 | greater than 4K are supported up to a maximum of 1 Mbytes (default |
12 | block size 128K). SquashFS 4.0 supports 64 bit filesystems and files | 12 | block size 128K). SquashFS 4.0 supports 64 bit filesystems and files |
13 | (larger than 4GB), full uid/gid information, hard links and | 13 | (larger than 4GB), full uid/gid information, hard links and |
14 | timestamps. | 14 | timestamps. |
15 | 15 | ||
16 | Squashfs is intended for general read-only filesystem use, for | 16 | Squashfs is intended for general read-only filesystem use, for |
17 | archival use (i.e. in cases where a .tar.gz file may be used), and in | 17 | archival use (i.e. in cases where a .tar.gz file may be used), and in |
@@ -26,7 +26,7 @@ config SQUASHFS | |||
26 | 26 | ||
27 | If unsure, say N. | 27 | If unsure, say N. |
28 | 28 | ||
29 | config SQUASHFS_XATTRS | 29 | config SQUASHFS_XATTR |
30 | bool "Squashfs XATTR support" | 30 | bool "Squashfs XATTR support" |
31 | depends on SQUASHFS | 31 | depends on SQUASHFS |
32 | default n | 32 | default n |
@@ -37,9 +37,24 @@ config SQUASHFS_XATTRS | |||
37 | 37 | ||
38 | If unsure, say N. | 38 | If unsure, say N. |
39 | 39 | ||
40 | config SQUASHFS_EMBEDDED | 40 | config SQUASHFS_LZO |
41 | bool "Include support for LZO compressed file systems" | ||
42 | depends on SQUASHFS | ||
43 | default n | ||
44 | select LZO_DECOMPRESS | ||
45 | help | ||
46 | Saying Y here includes support for reading Squashfs file systems | ||
47 | compressed with LZO compresssion. LZO compression is mainly | ||
48 | aimed at embedded systems with slower CPUs where the overheads | ||
49 | of zlib are too high. | ||
41 | 50 | ||
42 | bool "Additional option for memory-constrained systems" | 51 | LZO is not the standard compression used in Squashfs and so most |
52 | file systems will be readable without selecting this option. | ||
53 | |||
54 | If unsure, say N. | ||
55 | |||
56 | config SQUASHFS_EMBEDDED | ||
57 | bool "Additional option for memory-constrained systems" | ||
43 | depends on SQUASHFS | 58 | depends on SQUASHFS |
44 | default n | 59 | default n |
45 | help | 60 | help |
diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile index 2cee3e9fa452..7672bac8d328 100644 --- a/fs/squashfs/Makefile +++ b/fs/squashfs/Makefile | |||
@@ -5,5 +5,5 @@ | |||
5 | obj-$(CONFIG_SQUASHFS) += squashfs.o | 5 | obj-$(CONFIG_SQUASHFS) += squashfs.o |
6 | squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o | 6 | squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o |
7 | squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o | 7 | squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o |
8 | squashfs-$(CONFIG_SQUASHFS_XATTRS) += xattr.o xattr_id.o | 8 | squashfs-$(CONFIG_SQUASHFS_XATTR) += xattr.o xattr_id.o |
9 | 9 | squashfs-$(CONFIG_SQUASHFS_LZO) += lzo_wrapper.o | |
diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c index 157478da6ac9..24af9ce9722f 100644 --- a/fs/squashfs/decompressor.c +++ b/fs/squashfs/decompressor.c | |||
@@ -40,9 +40,11 @@ static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = { | |||
40 | NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0 | 40 | NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0 |
41 | }; | 41 | }; |
42 | 42 | ||
43 | #ifndef CONFIG_SQUASHFS_LZO | ||
43 | static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = { | 44 | static const struct squashfs_decompressor squashfs_lzo_unsupported_comp_ops = { |
44 | NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 | 45 | NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 |
45 | }; | 46 | }; |
47 | #endif | ||
46 | 48 | ||
47 | static const struct squashfs_decompressor squashfs_unknown_comp_ops = { | 49 | static const struct squashfs_decompressor squashfs_unknown_comp_ops = { |
48 | NULL, NULL, NULL, 0, "unknown", 0 | 50 | NULL, NULL, NULL, 0, "unknown", 0 |
@@ -51,7 +53,11 @@ static const struct squashfs_decompressor squashfs_unknown_comp_ops = { | |||
51 | static const struct squashfs_decompressor *decompressor[] = { | 53 | static const struct squashfs_decompressor *decompressor[] = { |
52 | &squashfs_zlib_comp_ops, | 54 | &squashfs_zlib_comp_ops, |
53 | &squashfs_lzma_unsupported_comp_ops, | 55 | &squashfs_lzma_unsupported_comp_ops, |
56 | #ifdef CONFIG_SQUASHFS_LZO | ||
57 | &squashfs_lzo_comp_ops, | ||
58 | #else | ||
54 | &squashfs_lzo_unsupported_comp_ops, | 59 | &squashfs_lzo_unsupported_comp_ops, |
60 | #endif | ||
55 | &squashfs_unknown_comp_ops | 61 | &squashfs_unknown_comp_ops |
56 | }; | 62 | }; |
57 | 63 | ||
diff --git a/fs/squashfs/lzo_wrapper.c b/fs/squashfs/lzo_wrapper.c new file mode 100644 index 000000000000..5d87789bf1c1 --- /dev/null +++ b/fs/squashfs/lzo_wrapper.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Squashfs - a compressed read only filesystem for Linux | ||
3 | * | ||
4 | * Copyright (c) 2010 LG Electronics | ||
5 | * Chan Jeong <chan.jeong@lge.com> | ||
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 | * lzo_wrapper.c | ||
22 | */ | ||
23 | |||
24 | #include <linux/mutex.h> | ||
25 | #include <linux/buffer_head.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | #include <linux/lzo.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 | |||
36 | struct squashfs_lzo { | ||
37 | void *input; | ||
38 | void *output; | ||
39 | }; | ||
40 | |||
41 | static void *lzo_init(struct squashfs_sb_info *msblk) | ||
42 | { | ||
43 | int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); | ||
44 | |||
45 | struct squashfs_lzo *stream = kzalloc(sizeof(*stream), GFP_KERNEL); | ||
46 | if (stream == NULL) | ||
47 | goto failed; | ||
48 | stream->input = vmalloc(block_size); | ||
49 | if (stream->input == NULL) | ||
50 | goto failed; | ||
51 | stream->output = vmalloc(block_size); | ||
52 | if (stream->output == NULL) | ||
53 | goto failed2; | ||
54 | |||
55 | return stream; | ||
56 | |||
57 | failed2: | ||
58 | vfree(stream->input); | ||
59 | failed: | ||
60 | ERROR("Failed to allocate lzo workspace\n"); | ||
61 | kfree(stream); | ||
62 | return NULL; | ||
63 | } | ||
64 | |||
65 | |||
66 | static void lzo_free(void *strm) | ||
67 | { | ||
68 | struct squashfs_lzo *stream = strm; | ||
69 | |||
70 | if (stream) { | ||
71 | vfree(stream->input); | ||
72 | vfree(stream->output); | ||
73 | } | ||
74 | kfree(stream); | ||
75 | } | ||
76 | |||
77 | |||
78 | static int lzo_uncompress(struct squashfs_sb_info *msblk, void **buffer, | ||
79 | struct buffer_head **bh, int b, int offset, int length, int srclength, | ||
80 | int pages) | ||
81 | { | ||
82 | struct squashfs_lzo *stream = msblk->stream; | ||
83 | void *buff = stream->input; | ||
84 | int avail, i, bytes = length, res; | ||
85 | size_t out_len = srclength; | ||
86 | |||
87 | mutex_lock(&msblk->read_data_mutex); | ||
88 | |||
89 | for (i = 0; i < b; i++) { | ||
90 | wait_on_buffer(bh[i]); | ||
91 | if (!buffer_uptodate(bh[i])) | ||
92 | goto block_release; | ||
93 | |||
94 | avail = min(bytes, msblk->devblksize - offset); | ||
95 | memcpy(buff, bh[i]->b_data + offset, avail); | ||
96 | buff += avail; | ||
97 | bytes -= avail; | ||
98 | offset = 0; | ||
99 | put_bh(bh[i]); | ||
100 | } | ||
101 | |||
102 | res = lzo1x_decompress_safe(stream->input, (size_t)length, | ||
103 | stream->output, &out_len); | ||
104 | if (res != LZO_E_OK) | ||
105 | goto failed; | ||
106 | |||
107 | res = bytes = (int)out_len; | ||
108 | for (i = 0, buff = stream->output; bytes && i < pages; i++) { | ||
109 | avail = min_t(int, bytes, PAGE_CACHE_SIZE); | ||
110 | memcpy(buffer[i], buff, avail); | ||
111 | buff += avail; | ||
112 | bytes -= avail; | ||
113 | } | ||
114 | |||
115 | mutex_unlock(&msblk->read_data_mutex); | ||
116 | return res; | ||
117 | |||
118 | block_release: | ||
119 | for (; i < b; i++) | ||
120 | put_bh(bh[i]); | ||
121 | |||
122 | failed: | ||
123 | mutex_unlock(&msblk->read_data_mutex); | ||
124 | |||
125 | ERROR("lzo decompression failed, data probably corrupt\n"); | ||
126 | return -EIO; | ||
127 | } | ||
128 | |||
129 | const struct squashfs_decompressor squashfs_lzo_comp_ops = { | ||
130 | .init = lzo_init, | ||
131 | .free = lzo_free, | ||
132 | .decompress = lzo_uncompress, | ||
133 | .id = LZO_COMPRESSION, | ||
134 | .name = "lzo", | ||
135 | .supported = 1 | ||
136 | }; | ||
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h index 733a17c42945..5d45569d5f72 100644 --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h | |||
@@ -104,3 +104,6 @@ extern const struct xattr_handler *squashfs_xattr_handlers[]; | |||
104 | 104 | ||
105 | /* zlib_wrapper.c */ | 105 | /* zlib_wrapper.c */ |
106 | extern const struct squashfs_decompressor squashfs_zlib_comp_ops; | 106 | extern const struct squashfs_decompressor squashfs_zlib_comp_ops; |
107 | |||
108 | /* lzo_wrapper.c */ | ||
109 | extern const struct squashfs_decompressor squashfs_lzo_comp_ops; | ||
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h index 8eabb808b78d..c5137fc9ab11 100644 --- a/fs/squashfs/squashfs_fs.h +++ b/fs/squashfs/squashfs_fs.h | |||
@@ -274,7 +274,7 @@ struct squashfs_base_inode { | |||
274 | __le16 uid; | 274 | __le16 uid; |
275 | __le16 guid; | 275 | __le16 guid; |
276 | __le32 mtime; | 276 | __le32 mtime; |
277 | __le32 inode_number; | 277 | __le32 inode_number; |
278 | }; | 278 | }; |
279 | 279 | ||
280 | struct squashfs_ipc_inode { | 280 | struct squashfs_ipc_inode { |
@@ -283,7 +283,7 @@ struct squashfs_ipc_inode { | |||
283 | __le16 uid; | 283 | __le16 uid; |
284 | __le16 guid; | 284 | __le16 guid; |
285 | __le32 mtime; | 285 | __le32 mtime; |
286 | __le32 inode_number; | 286 | __le32 inode_number; |
287 | __le32 nlink; | 287 | __le32 nlink; |
288 | }; | 288 | }; |
289 | 289 | ||
@@ -293,7 +293,7 @@ struct squashfs_lipc_inode { | |||
293 | __le16 uid; | 293 | __le16 uid; |
294 | __le16 guid; | 294 | __le16 guid; |
295 | __le32 mtime; | 295 | __le32 mtime; |
296 | __le32 inode_number; | 296 | __le32 inode_number; |
297 | __le32 nlink; | 297 | __le32 nlink; |
298 | __le32 xattr; | 298 | __le32 xattr; |
299 | }; | 299 | }; |
@@ -304,7 +304,7 @@ struct squashfs_dev_inode { | |||
304 | __le16 uid; | 304 | __le16 uid; |
305 | __le16 guid; | 305 | __le16 guid; |
306 | __le32 mtime; | 306 | __le32 mtime; |
307 | __le32 inode_number; | 307 | __le32 inode_number; |
308 | __le32 nlink; | 308 | __le32 nlink; |
309 | __le32 rdev; | 309 | __le32 rdev; |
310 | }; | 310 | }; |
@@ -315,7 +315,7 @@ struct squashfs_ldev_inode { | |||
315 | __le16 uid; | 315 | __le16 uid; |
316 | __le16 guid; | 316 | __le16 guid; |
317 | __le32 mtime; | 317 | __le32 mtime; |
318 | __le32 inode_number; | 318 | __le32 inode_number; |
319 | __le32 nlink; | 319 | __le32 nlink; |
320 | __le32 rdev; | 320 | __le32 rdev; |
321 | __le32 xattr; | 321 | __le32 xattr; |
@@ -327,7 +327,7 @@ struct squashfs_symlink_inode { | |||
327 | __le16 uid; | 327 | __le16 uid; |
328 | __le16 guid; | 328 | __le16 guid; |
329 | __le32 mtime; | 329 | __le32 mtime; |
330 | __le32 inode_number; | 330 | __le32 inode_number; |
331 | __le32 nlink; | 331 | __le32 nlink; |
332 | __le32 symlink_size; | 332 | __le32 symlink_size; |
333 | char symlink[0]; | 333 | char symlink[0]; |
@@ -339,7 +339,7 @@ struct squashfs_reg_inode { | |||
339 | __le16 uid; | 339 | __le16 uid; |
340 | __le16 guid; | 340 | __le16 guid; |
341 | __le32 mtime; | 341 | __le32 mtime; |
342 | __le32 inode_number; | 342 | __le32 inode_number; |
343 | __le32 start_block; | 343 | __le32 start_block; |
344 | __le32 fragment; | 344 | __le32 fragment; |
345 | __le32 offset; | 345 | __le32 offset; |
@@ -353,7 +353,7 @@ struct squashfs_lreg_inode { | |||
353 | __le16 uid; | 353 | __le16 uid; |
354 | __le16 guid; | 354 | __le16 guid; |
355 | __le32 mtime; | 355 | __le32 mtime; |
356 | __le32 inode_number; | 356 | __le32 inode_number; |
357 | __le64 start_block; | 357 | __le64 start_block; |
358 | __le64 file_size; | 358 | __le64 file_size; |
359 | __le64 sparse; | 359 | __le64 sparse; |
@@ -370,7 +370,7 @@ struct squashfs_dir_inode { | |||
370 | __le16 uid; | 370 | __le16 uid; |
371 | __le16 guid; | 371 | __le16 guid; |
372 | __le32 mtime; | 372 | __le32 mtime; |
373 | __le32 inode_number; | 373 | __le32 inode_number; |
374 | __le32 start_block; | 374 | __le32 start_block; |
375 | __le32 nlink; | 375 | __le32 nlink; |
376 | __le16 file_size; | 376 | __le16 file_size; |
@@ -384,7 +384,7 @@ struct squashfs_ldir_inode { | |||
384 | __le16 uid; | 384 | __le16 uid; |
385 | __le16 guid; | 385 | __le16 guid; |
386 | __le32 mtime; | 386 | __le32 mtime; |
387 | __le32 inode_number; | 387 | __le32 inode_number; |
388 | __le32 nlink; | 388 | __le32 nlink; |
389 | __le32 file_size; | 389 | __le32 file_size; |
390 | __le32 start_block; | 390 | __le32 start_block; |
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c index c7655e8b31cd..652b8541f9c6 100644 --- a/fs/squashfs/xattr.c +++ b/fs/squashfs/xattr.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 19 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 | * | 20 | * |
21 | * xattr_id.c | 21 | * xattr.c |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
@@ -295,7 +295,7 @@ static const struct xattr_handler squashfs_xattr_security_handler = { | |||
295 | .get = squashfs_security_get | 295 | .get = squashfs_security_get |
296 | }; | 296 | }; |
297 | 297 | ||
298 | static inline const struct xattr_handler *squashfs_xattr_handler(int type) | 298 | static const struct xattr_handler *squashfs_xattr_handler(int type) |
299 | { | 299 | { |
300 | if (type & ~(SQUASHFS_XATTR_PREFIX_MASK | SQUASHFS_XATTR_VALUE_OOL)) | 300 | if (type & ~(SQUASHFS_XATTR_PREFIX_MASK | SQUASHFS_XATTR_VALUE_OOL)) |
301 | /* ignore unrecognised type */ | 301 | /* ignore unrecognised type */ |
diff --git a/fs/squashfs/xattr.h b/fs/squashfs/xattr.h index 9da071ae181c..49fe0d719fbf 100644 --- a/fs/squashfs/xattr.h +++ b/fs/squashfs/xattr.h | |||
@@ -21,7 +21,7 @@ | |||
21 | * xattr.h | 21 | * xattr.h |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifdef CONFIG_SQUASHFS_XATTRS | 24 | #ifdef CONFIG_SQUASHFS_XATTR |
25 | extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64, | 25 | extern __le64 *squashfs_read_xattr_id_table(struct super_block *, u64, |
26 | u64 *, int *); | 26 | u64 *, int *); |
27 | extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *, | 27 | extern int squashfs_xattr_lookup(struct super_block *, unsigned int, int *, |