diff options
author | Phillip Lougher <phillip@lougher.demon.co.uk> | 2009-10-05 23:04:15 -0400 |
---|---|---|
committer | Phillip Lougher <phillip@lougher.demon.co.uk> | 2010-01-20 16:47:47 -0500 |
commit | 4c0f0bb2351bee3de8dd7715ee199454a59f1230 (patch) | |
tree | c552993587a8e87f7ebc0fe0955efdde94cc8884 /fs | |
parent | f1a40359f8d8ba073257ed31a513e492621bcbc5 (diff) |
Squashfs: add a decompressor framework
This adds a decompressor framework which allows multiple compression
algorithms to be cleanly supported.
Also update zlib wrapper and other code to use the new framework.
Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/squashfs/Makefile | 2 | ||||
-rw-r--r-- | fs/squashfs/block.c | 3 | ||||
-rw-r--r-- | fs/squashfs/decompressor.c | 58 | ||||
-rw-r--r-- | fs/squashfs/decompressor.h | 55 | ||||
-rw-r--r-- | fs/squashfs/squashfs.h | 14 | ||||
-rw-r--r-- | fs/squashfs/squashfs_fs_sb.h | 41 | ||||
-rw-r--r-- | fs/squashfs/super.c | 45 | ||||
-rw-r--r-- | fs/squashfs/zlib_wrapper.c | 17 |
8 files changed, 184 insertions, 51 deletions
diff --git a/fs/squashfs/Makefile b/fs/squashfs/Makefile index a397e6f12ab5..df8a19ef870d 100644 --- a/fs/squashfs/Makefile +++ b/fs/squashfs/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
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 | 7 | squashfs-y += namei.o super.o symlink.o zlib_wrapper.o decompressor.o |
diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index 3f836e181eb8..1cb0d81b164b 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "squashfs_fs_sb.h" | 36 | #include "squashfs_fs_sb.h" |
37 | #include "squashfs_fs_i.h" | 37 | #include "squashfs_fs_i.h" |
38 | #include "squashfs.h" | 38 | #include "squashfs.h" |
39 | #include "decompressor.h" | ||
39 | 40 | ||
40 | /* | 41 | /* |
41 | * Read the metadata block length, this is stored in the first two | 42 | * Read the metadata block length, this is stored in the first two |
@@ -151,7 +152,7 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | |||
151 | } | 152 | } |
152 | 153 | ||
153 | if (compressed) { | 154 | if (compressed) { |
154 | length = squashfs_zlib_uncompress(msblk, buffer, bh, b, offset, | 155 | length = squashfs_decompress(msblk, buffer, bh, b, offset, |
155 | length, srclength, pages); | 156 | length, srclength, pages); |
156 | if (length < 0) | 157 | if (length < 0) |
157 | goto read_failure; | 158 | goto read_failure; |
diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c new file mode 100644 index 000000000000..0072ccdac1e2 --- /dev/null +++ b/fs/squashfs/decompressor.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Squashfs - a compressed read only filesystem for Linux | ||
3 | * | ||
4 | * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | ||
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 | * decompressor.c | ||
22 | */ | ||
23 | |||
24 | #include <linux/types.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/buffer_head.h> | ||
27 | |||
28 | #include "squashfs_fs.h" | ||
29 | #include "squashfs_fs_sb.h" | ||
30 | #include "squashfs_fs_i.h" | ||
31 | #include "decompressor.h" | ||
32 | #include "squashfs.h" | ||
33 | |||
34 | /* | ||
35 | * This file (and decompressor.h) implements a decompressor framework for | ||
36 | * Squashfs, allowing multiple decompressors to be easily supported | ||
37 | */ | ||
38 | |||
39 | static const struct squashfs_decompressor squashfs_unknown_comp_ops = { | ||
40 | NULL, NULL, NULL, 0, "unknown", 0 | ||
41 | }; | ||
42 | |||
43 | static const struct squashfs_decompressor *decompressor[] = { | ||
44 | &squashfs_zlib_comp_ops, | ||
45 | &squashfs_unknown_comp_ops | ||
46 | }; | ||
47 | |||
48 | |||
49 | const struct squashfs_decompressor *squashfs_lookup_decompressor(int id) | ||
50 | { | ||
51 | int i; | ||
52 | |||
53 | for (i = 0; decompressor[i]->id; i++) | ||
54 | if (id == decompressor[i]->id) | ||
55 | break; | ||
56 | |||
57 | return decompressor[i]; | ||
58 | } | ||
diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h new file mode 100644 index 000000000000..7425f80783f6 --- /dev/null +++ b/fs/squashfs/decompressor.h | |||
@@ -0,0 +1,55 @@ | |||
1 | #ifndef DECOMPRESSOR_H | ||
2 | #define DECOMPRESSOR_H | ||
3 | /* | ||
4 | * Squashfs - a compressed read only filesystem for Linux | ||
5 | * | ||
6 | * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | ||
7 | * Phillip Lougher <phillip@lougher.demon.co.uk> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version 2, | ||
12 | * or (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
22 | * | ||
23 | * decompressor.h | ||
24 | */ | ||
25 | |||
26 | struct squashfs_decompressor { | ||
27 | void *(*init)(struct squashfs_sb_info *); | ||
28 | void (*free)(void *); | ||
29 | int (*decompress)(struct squashfs_sb_info *, void **, | ||
30 | struct buffer_head **, int, int, int, int, int); | ||
31 | int id; | ||
32 | char *name; | ||
33 | int supported; | ||
34 | }; | ||
35 | |||
36 | static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk) | ||
37 | { | ||
38 | return msblk->decompressor->init(msblk); | ||
39 | } | ||
40 | |||
41 | static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk, | ||
42 | void *s) | ||
43 | { | ||
44 | if (msblk->decompressor) | ||
45 | msblk->decompressor->free(s); | ||
46 | } | ||
47 | |||
48 | static inline int squashfs_decompress(struct squashfs_sb_info *msblk, | ||
49 | void **buffer, struct buffer_head **bh, int b, int offset, int length, | ||
50 | int srclength, int pages) | ||
51 | { | ||
52 | return msblk->decompressor->decompress(msblk, buffer, bh, b, offset, | ||
53 | length, srclength, pages); | ||
54 | } | ||
55 | #endif | ||
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h index 9c2f76a1c50b..fe2587af5512 100644 --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h | |||
@@ -51,6 +51,9 @@ extern struct squashfs_cache_entry *squashfs_get_datablock(struct super_block *, | |||
51 | u64, int); | 51 | u64, int); |
52 | extern int squashfs_read_table(struct super_block *, void *, u64, int); | 52 | extern int squashfs_read_table(struct super_block *, void *, u64, int); |
53 | 53 | ||
54 | /* decompressor.c */ | ||
55 | extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); | ||
56 | |||
54 | /* export.c */ | 57 | /* export.c */ |
55 | extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, | 58 | extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, |
56 | unsigned int); | 59 | unsigned int); |
@@ -70,14 +73,8 @@ extern struct inode *squashfs_iget(struct super_block *, long long, | |||
70 | unsigned int); | 73 | unsigned int); |
71 | extern int squashfs_read_inode(struct inode *, long long); | 74 | extern int squashfs_read_inode(struct inode *, long long); |
72 | 75 | ||
73 | /* zlib_wrapper.c */ | ||
74 | extern void *squashfs_zlib_init(void); | ||
75 | extern void squashfs_zlib_free(void *); | ||
76 | extern int squashfs_zlib_uncompress(struct squashfs_sb_info *, void **, | ||
77 | struct buffer_head **, int, int, int, int, int); | ||
78 | |||
79 | /* | 76 | /* |
80 | * Inodes and files operations | 77 | * Inodes, files and decompressor operations |
81 | */ | 78 | */ |
82 | 79 | ||
83 | /* dir.c */ | 80 | /* dir.c */ |
@@ -94,3 +91,6 @@ extern const struct inode_operations squashfs_dir_inode_ops; | |||
94 | 91 | ||
95 | /* symlink.c */ | 92 | /* symlink.c */ |
96 | extern const struct address_space_operations squashfs_symlink_aops; | 93 | extern const struct address_space_operations squashfs_symlink_aops; |
94 | |||
95 | /* zlib_wrapper.c */ | ||
96 | extern const struct squashfs_decompressor squashfs_zlib_comp_ops; | ||
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h index 23a67fa40b03..753335085e41 100644 --- a/fs/squashfs/squashfs_fs_sb.h +++ b/fs/squashfs/squashfs_fs_sb.h | |||
@@ -52,25 +52,26 @@ struct squashfs_cache_entry { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | struct squashfs_sb_info { | 54 | struct squashfs_sb_info { |
55 | int devblksize; | 55 | const struct squashfs_decompressor *decompressor; |
56 | int devblksize_log2; | 56 | int devblksize; |
57 | struct squashfs_cache *block_cache; | 57 | int devblksize_log2; |
58 | struct squashfs_cache *fragment_cache; | 58 | struct squashfs_cache *block_cache; |
59 | struct squashfs_cache *read_page; | 59 | struct squashfs_cache *fragment_cache; |
60 | int next_meta_index; | 60 | struct squashfs_cache *read_page; |
61 | __le64 *id_table; | 61 | int next_meta_index; |
62 | __le64 *fragment_index; | 62 | __le64 *id_table; |
63 | unsigned int *fragment_index_2; | 63 | __le64 *fragment_index; |
64 | struct mutex read_data_mutex; | 64 | unsigned int *fragment_index_2; |
65 | struct mutex meta_index_mutex; | 65 | struct mutex read_data_mutex; |
66 | struct meta_index *meta_index; | 66 | struct mutex meta_index_mutex; |
67 | void *stream; | 67 | struct meta_index *meta_index; |
68 | __le64 *inode_lookup_table; | 68 | void *stream; |
69 | u64 inode_table; | 69 | __le64 *inode_lookup_table; |
70 | u64 directory_table; | 70 | u64 inode_table; |
71 | unsigned int block_size; | 71 | u64 directory_table; |
72 | unsigned short block_log; | 72 | unsigned int block_size; |
73 | long long bytes_used; | 73 | unsigned short block_log; |
74 | unsigned int inodes; | 74 | long long bytes_used; |
75 | unsigned int inodes; | ||
75 | }; | 76 | }; |
76 | #endif | 77 | #endif |
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index b9f8c6a92d6a..3550aec2f655 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
@@ -41,27 +41,35 @@ | |||
41 | #include "squashfs_fs_sb.h" | 41 | #include "squashfs_fs_sb.h" |
42 | #include "squashfs_fs_i.h" | 42 | #include "squashfs_fs_i.h" |
43 | #include "squashfs.h" | 43 | #include "squashfs.h" |
44 | #include "decompressor.h" | ||
44 | 45 | ||
45 | static struct file_system_type squashfs_fs_type; | 46 | static struct file_system_type squashfs_fs_type; |
46 | static const struct super_operations squashfs_super_ops; | 47 | static const struct super_operations squashfs_super_ops; |
47 | 48 | ||
48 | static int supported_squashfs_filesystem(short major, short minor, short comp) | 49 | static const struct squashfs_decompressor *supported_squashfs_filesystem(short |
50 | major, short minor, short id) | ||
49 | { | 51 | { |
52 | const struct squashfs_decompressor *decompressor; | ||
53 | |||
50 | if (major < SQUASHFS_MAJOR) { | 54 | if (major < SQUASHFS_MAJOR) { |
51 | ERROR("Major/Minor mismatch, older Squashfs %d.%d " | 55 | ERROR("Major/Minor mismatch, older Squashfs %d.%d " |
52 | "filesystems are unsupported\n", major, minor); | 56 | "filesystems are unsupported\n", major, minor); |
53 | return -EINVAL; | 57 | return NULL; |
54 | } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { | 58 | } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { |
55 | ERROR("Major/Minor mismatch, trying to mount newer " | 59 | ERROR("Major/Minor mismatch, trying to mount newer " |
56 | "%d.%d filesystem\n", major, minor); | 60 | "%d.%d filesystem\n", major, minor); |
57 | ERROR("Please update your kernel\n"); | 61 | ERROR("Please update your kernel\n"); |
58 | return -EINVAL; | 62 | return NULL; |
59 | } | 63 | } |
60 | 64 | ||
61 | if (comp != ZLIB_COMPRESSION) | 65 | decompressor = squashfs_lookup_decompressor(id); |
62 | return -EINVAL; | 66 | if (!decompressor->supported) { |
67 | ERROR("Filesystem uses \"%s\" compression. This is not " | ||
68 | "supported\n", decompressor->name); | ||
69 | return NULL; | ||
70 | } | ||
63 | 71 | ||
64 | return 0; | 72 | return decompressor; |
65 | } | 73 | } |
66 | 74 | ||
67 | 75 | ||
@@ -86,10 +94,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
86 | } | 94 | } |
87 | msblk = sb->s_fs_info; | 95 | msblk = sb->s_fs_info; |
88 | 96 | ||
89 | msblk->stream = squashfs_zlib_init(); | ||
90 | if (msblk->stream == NULL) | ||
91 | goto failure; | ||
92 | |||
93 | sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); | 97 | sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); |
94 | if (sblk == NULL) { | 98 | if (sblk == NULL) { |
95 | ERROR("Failed to allocate squashfs_super_block\n"); | 99 | ERROR("Failed to allocate squashfs_super_block\n"); |
@@ -116,25 +120,25 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
116 | goto failed_mount; | 120 | goto failed_mount; |
117 | } | 121 | } |
118 | 122 | ||
123 | err = -EINVAL; | ||
124 | |||
119 | /* Check it is a SQUASHFS superblock */ | 125 | /* Check it is a SQUASHFS superblock */ |
120 | sb->s_magic = le32_to_cpu(sblk->s_magic); | 126 | sb->s_magic = le32_to_cpu(sblk->s_magic); |
121 | if (sb->s_magic != SQUASHFS_MAGIC) { | 127 | if (sb->s_magic != SQUASHFS_MAGIC) { |
122 | if (!silent) | 128 | if (!silent) |
123 | ERROR("Can't find a SQUASHFS superblock on %s\n", | 129 | ERROR("Can't find a SQUASHFS superblock on %s\n", |
124 | bdevname(sb->s_bdev, b)); | 130 | bdevname(sb->s_bdev, b)); |
125 | err = -EINVAL; | ||
126 | goto failed_mount; | 131 | goto failed_mount; |
127 | } | 132 | } |
128 | 133 | ||
129 | /* Check the MAJOR & MINOR versions and compression type */ | 134 | /* Check the MAJOR & MINOR versions and lookup compression type */ |
130 | err = supported_squashfs_filesystem(le16_to_cpu(sblk->s_major), | 135 | msblk->decompressor = supported_squashfs_filesystem( |
136 | le16_to_cpu(sblk->s_major), | ||
131 | le16_to_cpu(sblk->s_minor), | 137 | le16_to_cpu(sblk->s_minor), |
132 | le16_to_cpu(sblk->compression)); | 138 | le16_to_cpu(sblk->compression)); |
133 | if (err < 0) | 139 | if (msblk->decompressor == NULL) |
134 | goto failed_mount; | 140 | goto failed_mount; |
135 | 141 | ||
136 | err = -EINVAL; | ||
137 | |||
138 | /* | 142 | /* |
139 | * Check if there's xattrs in the filesystem. These are not | 143 | * Check if there's xattrs in the filesystem. These are not |
140 | * supported in this version, so warn that they will be ignored. | 144 | * supported in this version, so warn that they will be ignored. |
@@ -201,6 +205,10 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
201 | 205 | ||
202 | err = -ENOMEM; | 206 | err = -ENOMEM; |
203 | 207 | ||
208 | msblk->stream = squashfs_decompressor_init(msblk); | ||
209 | if (msblk->stream == NULL) | ||
210 | goto failed_mount; | ||
211 | |||
204 | msblk->block_cache = squashfs_cache_init("metadata", | 212 | msblk->block_cache = squashfs_cache_init("metadata", |
205 | SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); | 213 | SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); |
206 | if (msblk->block_cache == NULL) | 214 | if (msblk->block_cache == NULL) |
@@ -288,7 +296,7 @@ failed_mount: | |||
288 | squashfs_cache_delete(msblk->block_cache); | 296 | squashfs_cache_delete(msblk->block_cache); |
289 | squashfs_cache_delete(msblk->fragment_cache); | 297 | squashfs_cache_delete(msblk->fragment_cache); |
290 | squashfs_cache_delete(msblk->read_page); | 298 | squashfs_cache_delete(msblk->read_page); |
291 | squashfs_zlib_free(msblk->stream); | 299 | squashfs_decompressor_free(msblk, msblk->stream); |
292 | kfree(msblk->inode_lookup_table); | 300 | kfree(msblk->inode_lookup_table); |
293 | kfree(msblk->fragment_index); | 301 | kfree(msblk->fragment_index); |
294 | kfree(msblk->id_table); | 302 | kfree(msblk->id_table); |
@@ -298,7 +306,6 @@ failed_mount: | |||
298 | return err; | 306 | return err; |
299 | 307 | ||
300 | failure: | 308 | failure: |
301 | squashfs_zlib_free(msblk->stream); | ||
302 | kfree(sb->s_fs_info); | 309 | kfree(sb->s_fs_info); |
303 | sb->s_fs_info = NULL; | 310 | sb->s_fs_info = NULL; |
304 | return -ENOMEM; | 311 | return -ENOMEM; |
@@ -342,7 +349,7 @@ static void squashfs_put_super(struct super_block *sb) | |||
342 | squashfs_cache_delete(sbi->block_cache); | 349 | squashfs_cache_delete(sbi->block_cache); |
343 | squashfs_cache_delete(sbi->fragment_cache); | 350 | squashfs_cache_delete(sbi->fragment_cache); |
344 | squashfs_cache_delete(sbi->read_page); | 351 | squashfs_cache_delete(sbi->read_page); |
345 | squashfs_zlib_free(sbi->stream); | 352 | squashfs_decompressor_free(sbi, sbi->stream); |
346 | kfree(sbi->id_table); | 353 | kfree(sbi->id_table); |
347 | kfree(sbi->fragment_index); | 354 | kfree(sbi->fragment_index); |
348 | kfree(sbi->meta_index); | 355 | kfree(sbi->meta_index); |
diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c index c814594d522e..4dd70e04333b 100644 --- a/fs/squashfs/zlib_wrapper.c +++ b/fs/squashfs/zlib_wrapper.c | |||
@@ -30,8 +30,9 @@ | |||
30 | #include "squashfs_fs_sb.h" | 30 | #include "squashfs_fs_sb.h" |
31 | #include "squashfs_fs_i.h" | 31 | #include "squashfs_fs_i.h" |
32 | #include "squashfs.h" | 32 | #include "squashfs.h" |
33 | #include "decompressor.h" | ||
33 | 34 | ||
34 | void *squashfs_zlib_init() | 35 | static void *zlib_init(struct squashfs_sb_info *dummy) |
35 | { | 36 | { |
36 | z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); | 37 | z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); |
37 | if (stream == NULL) | 38 | if (stream == NULL) |
@@ -50,7 +51,7 @@ failed: | |||
50 | } | 51 | } |
51 | 52 | ||
52 | 53 | ||
53 | void squashfs_zlib_free(void *strm) | 54 | static void zlib_free(void *strm) |
54 | { | 55 | { |
55 | z_stream *stream = strm; | 56 | z_stream *stream = strm; |
56 | 57 | ||
@@ -60,7 +61,7 @@ void squashfs_zlib_free(void *strm) | |||
60 | } | 61 | } |
61 | 62 | ||
62 | 63 | ||
63 | int squashfs_zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, | 64 | static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer, |
64 | 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, |
65 | int pages) | 66 | int pages) |
66 | { | 67 | { |
@@ -137,3 +138,13 @@ release_mutex: | |||
137 | 138 | ||
138 | return -EIO; | 139 | return -EIO; |
139 | } | 140 | } |
141 | |||
142 | const struct squashfs_decompressor squashfs_zlib_comp_ops = { | ||
143 | .init = zlib_init, | ||
144 | .free = zlib_free, | ||
145 | .decompress = zlib_uncompress, | ||
146 | .id = ZLIB_COMPRESSION, | ||
147 | .name = "zlib", | ||
148 | .supported = 1 | ||
149 | }; | ||
150 | |||