diff options
-rw-r--r-- | fs/squashfs/decompressor.c | 34 | ||||
-rw-r--r-- | fs/squashfs/decompressor.h | 7 | ||||
-rw-r--r-- | fs/squashfs/lzo_wrapper.c | 4 | ||||
-rw-r--r-- | fs/squashfs/squashfs.h | 1 | ||||
-rw-r--r-- | fs/squashfs/squashfs_fs.h | 4 | ||||
-rw-r--r-- | fs/squashfs/super.c | 11 | ||||
-rw-r--r-- | fs/squashfs/xz_wrapper.c | 5 | ||||
-rw-r--r-- | fs/squashfs/zlib_wrapper.c | 4 |
8 files changed, 54 insertions, 16 deletions
diff --git a/fs/squashfs/decompressor.c b/fs/squashfs/decompressor.c index a5940e54c4dd..e921bd213738 100644 --- a/fs/squashfs/decompressor.c +++ b/fs/squashfs/decompressor.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/slab.h> | ||
26 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
27 | 28 | ||
28 | #include "squashfs_fs.h" | 29 | #include "squashfs_fs.h" |
@@ -74,3 +75,36 @@ const struct squashfs_decompressor *squashfs_lookup_decompressor(int id) | |||
74 | 75 | ||
75 | return decompressor[i]; | 76 | return decompressor[i]; |
76 | } | 77 | } |
78 | |||
79 | |||
80 | void *squashfs_decompressor_init(struct super_block *sb, unsigned short flags) | ||
81 | { | ||
82 | struct squashfs_sb_info *msblk = sb->s_fs_info; | ||
83 | void *strm, *buffer = NULL; | ||
84 | int length = 0; | ||
85 | |||
86 | /* | ||
87 | * Read decompressor specific options from file system if present | ||
88 | */ | ||
89 | if (SQUASHFS_COMP_OPTS(flags)) { | ||
90 | buffer = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL); | ||
91 | if (buffer == NULL) | ||
92 | return ERR_PTR(-ENOMEM); | ||
93 | |||
94 | length = squashfs_read_data(sb, &buffer, | ||
95 | sizeof(struct squashfs_super_block), 0, NULL, | ||
96 | PAGE_CACHE_SIZE, 1); | ||
97 | |||
98 | if (length < 0) { | ||
99 | strm = ERR_PTR(length); | ||
100 | goto finished; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | strm = msblk->decompressor->init(msblk, buffer, length); | ||
105 | |||
106 | finished: | ||
107 | kfree(buffer); | ||
108 | |||
109 | return strm; | ||
110 | } | ||
diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h index 3b305a70f7aa..099745ad5691 100644 --- a/fs/squashfs/decompressor.h +++ b/fs/squashfs/decompressor.h | |||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | struct squashfs_decompressor { | 26 | struct squashfs_decompressor { |
27 | void *(*init)(struct squashfs_sb_info *); | 27 | void *(*init)(struct squashfs_sb_info *, void *, int); |
28 | void (*free)(void *); | 28 | void (*free)(void *); |
29 | int (*decompress)(struct squashfs_sb_info *, void **, | 29 | int (*decompress)(struct squashfs_sb_info *, void **, |
30 | struct buffer_head **, int, int, int, int, int); | 30 | struct buffer_head **, int, int, int, int, int); |
@@ -33,11 +33,6 @@ struct squashfs_decompressor { | |||
33 | int supported; | 33 | int supported; |
34 | }; | 34 | }; |
35 | 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, | 36 | static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk, |
42 | void *s) | 37 | void *s) |
43 | { | 38 | { |
diff --git a/fs/squashfs/lzo_wrapper.c b/fs/squashfs/lzo_wrapper.c index 7da759e34c52..00f4dfc5f088 100644 --- a/fs/squashfs/lzo_wrapper.c +++ b/fs/squashfs/lzo_wrapper.c | |||
@@ -37,7 +37,7 @@ struct squashfs_lzo { | |||
37 | void *output; | 37 | void *output; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | static void *lzo_init(struct squashfs_sb_info *msblk) | 40 | static void *lzo_init(struct squashfs_sb_info *msblk, void *buff, int len) |
41 | { | 41 | { |
42 | int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); | 42 | int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); |
43 | 43 | ||
@@ -58,7 +58,7 @@ failed2: | |||
58 | failed: | 58 | failed: |
59 | ERROR("Failed to allocate lzo workspace\n"); | 59 | ERROR("Failed to allocate lzo workspace\n"); |
60 | kfree(stream); | 60 | kfree(stream); |
61 | return NULL; | 61 | return ERR_PTR(-ENOMEM); |
62 | } | 62 | } |
63 | 63 | ||
64 | 64 | ||
diff --git a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h index ba729d808876..1f2e608b8785 100644 --- a/fs/squashfs/squashfs.h +++ b/fs/squashfs/squashfs.h | |||
@@ -48,6 +48,7 @@ extern int squashfs_read_table(struct super_block *, void *, u64, int); | |||
48 | 48 | ||
49 | /* decompressor.c */ | 49 | /* decompressor.c */ |
50 | extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); | 50 | extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int); |
51 | extern void *squashfs_decompressor_init(struct super_block *, unsigned short); | ||
51 | 52 | ||
52 | /* export.c */ | 53 | /* export.c */ |
53 | extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, | 54 | extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64, |
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h index 39533feffd6d..4582c568ef4d 100644 --- a/fs/squashfs/squashfs_fs.h +++ b/fs/squashfs/squashfs_fs.h | |||
@@ -57,6 +57,7 @@ | |||
57 | #define SQUASHFS_ALWAYS_FRAG 5 | 57 | #define SQUASHFS_ALWAYS_FRAG 5 |
58 | #define SQUASHFS_DUPLICATE 6 | 58 | #define SQUASHFS_DUPLICATE 6 |
59 | #define SQUASHFS_EXPORT 7 | 59 | #define SQUASHFS_EXPORT 7 |
60 | #define SQUASHFS_COMP_OPT 10 | ||
60 | 61 | ||
61 | #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) | 62 | #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) |
62 | 63 | ||
@@ -81,6 +82,9 @@ | |||
81 | #define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ | 82 | #define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ |
82 | SQUASHFS_EXPORT) | 83 | SQUASHFS_EXPORT) |
83 | 84 | ||
85 | #define SQUASHFS_COMP_OPTS(flags) SQUASHFS_BIT(flags, \ | ||
86 | SQUASHFS_COMP_OPT) | ||
87 | |||
84 | /* Max number of types and file types */ | 88 | /* Max number of types and file types */ |
85 | #define SQUASHFS_DIR_TYPE 1 | 89 | #define SQUASHFS_DIR_TYPE 1 |
86 | #define SQUASHFS_REG_TYPE 2 | 90 | #define SQUASHFS_REG_TYPE 2 |
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 20700b9f2b4c..95467db71a8e 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
@@ -199,10 +199,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
199 | 199 | ||
200 | err = -ENOMEM; | 200 | err = -ENOMEM; |
201 | 201 | ||
202 | msblk->stream = squashfs_decompressor_init(msblk); | ||
203 | if (msblk->stream == NULL) | ||
204 | goto failed_mount; | ||
205 | |||
206 | msblk->block_cache = squashfs_cache_init("metadata", | 202 | msblk->block_cache = squashfs_cache_init("metadata", |
207 | SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); | 203 | SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); |
208 | if (msblk->block_cache == NULL) | 204 | if (msblk->block_cache == NULL) |
@@ -215,6 +211,13 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) | |||
215 | goto failed_mount; | 211 | goto failed_mount; |
216 | } | 212 | } |
217 | 213 | ||
214 | msblk->stream = squashfs_decompressor_init(sb, flags); | ||
215 | if (IS_ERR(msblk->stream)) { | ||
216 | err = PTR_ERR(msblk->stream); | ||
217 | msblk->stream = NULL; | ||
218 | goto failed_mount; | ||
219 | } | ||
220 | |||
218 | /* Allocate and read id index table */ | 221 | /* Allocate and read id index table */ |
219 | msblk->id_table = squashfs_read_id_index_table(sb, | 222 | msblk->id_table = squashfs_read_id_index_table(sb, |
220 | le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids)); | 223 | le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids)); |
diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c index c4eb40018256..397adea72eb9 100644 --- a/fs/squashfs/xz_wrapper.c +++ b/fs/squashfs/xz_wrapper.c | |||
@@ -38,7 +38,8 @@ struct squashfs_xz { | |||
38 | struct xz_buf buf; | 38 | struct xz_buf buf; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static void *squashfs_xz_init(struct squashfs_sb_info *msblk) | 41 | static void *squashfs_xz_init(struct squashfs_sb_info *msblk, void *buff, |
42 | int len) | ||
42 | { | 43 | { |
43 | int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); | 44 | int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); |
44 | 45 | ||
@@ -55,7 +56,7 @@ static void *squashfs_xz_init(struct squashfs_sb_info *msblk) | |||
55 | failed: | 56 | failed: |
56 | ERROR("Failed to allocate xz workspace\n"); | 57 | ERROR("Failed to allocate xz workspace\n"); |
57 | kfree(stream); | 58 | kfree(stream); |
58 | return NULL; | 59 | return ERR_PTR(-ENOMEM); |
59 | } | 60 | } |
60 | 61 | ||
61 | 62 | ||
diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c index 4661ae2b1cec..195b0d035e9b 100644 --- a/fs/squashfs/zlib_wrapper.c +++ b/fs/squashfs/zlib_wrapper.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "squashfs.h" | 32 | #include "squashfs.h" |
33 | #include "decompressor.h" | 33 | #include "decompressor.h" |
34 | 34 | ||
35 | static void *zlib_init(struct squashfs_sb_info *dummy) | 35 | static void *zlib_init(struct squashfs_sb_info *dummy, void *buff, int len) |
36 | { | 36 | { |
37 | z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); | 37 | z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); |
38 | if (stream == NULL) | 38 | if (stream == NULL) |
@@ -47,7 +47,7 @@ static void *zlib_init(struct squashfs_sb_info *dummy) | |||
47 | failed: | 47 | failed: |
48 | ERROR("Failed to allocate zlib workspace\n"); | 48 | ERROR("Failed to allocate zlib workspace\n"); |
49 | kfree(stream); | 49 | kfree(stream); |
50 | return NULL; | 50 | return ERR_PTR(-ENOMEM); |
51 | } | 51 | } |
52 | 52 | ||
53 | 53 | ||