diff options
Diffstat (limited to 'fs/squashfs')
-rw-r--r-- | fs/squashfs/Kconfig | 12 | ||||
-rw-r--r-- | fs/squashfs/cache.c | 4 | ||||
-rw-r--r-- | fs/squashfs/decompressor.c | 34 | ||||
-rw-r--r-- | fs/squashfs/decompressor.h | 7 | ||||
-rw-r--r-- | fs/squashfs/dir.c | 9 | ||||
-rw-r--r-- | fs/squashfs/lzo_wrapper.c | 4 | ||||
-rw-r--r-- | fs/squashfs/namei.c | 12 | ||||
-rw-r--r-- | fs/squashfs/squashfs.h | 1 | ||||
-rw-r--r-- | fs/squashfs/squashfs_fs.h | 4 | ||||
-rw-r--r-- | fs/squashfs/super.c | 15 | ||||
-rw-r--r-- | fs/squashfs/xz_wrapper.c | 53 | ||||
-rw-r--r-- | fs/squashfs/zlib_wrapper.c | 10 |
12 files changed, 128 insertions, 37 deletions
diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig index aa68a8a31518..efc309fa3035 100644 --- a/fs/squashfs/Kconfig +++ b/fs/squashfs/Kconfig | |||
@@ -5,12 +5,12 @@ 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/lzo compression to compress both | 8 | filesystem for Linux. It uses zlib, lzo or xz compression to |
9 | files, inodes and directories. Inodes in the system are very small | 9 | compress both files, inodes and directories. Inodes in the system |
10 | and all blocks are packed to minimise data overhead. Block sizes | 10 | are very small and all blocks are packed to minimise data overhead. |
11 | greater than 4K are supported up to a maximum of 1 Mbytes (default | 11 | Block sizes greater than 4K are supported up to a maximum of 1 Mbytes |
12 | block size 128K). SquashFS 4.0 supports 64 bit filesystems and files | 12 | (default block size 128K). SquashFS 4.0 supports 64 bit filesystems |
13 | (larger than 4GB), full uid/gid information, hard links and | 13 | and files (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 |
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index 26b15ae34d6f..c37b520132ff 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c | |||
@@ -104,7 +104,7 @@ struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb, | |||
104 | entry = &cache->entry[i]; | 104 | entry = &cache->entry[i]; |
105 | 105 | ||
106 | /* | 106 | /* |
107 | * Initialise choosen cache entry, and fill it in from | 107 | * Initialise chosen cache entry, and fill it in from |
108 | * disk. | 108 | * disk. |
109 | */ | 109 | */ |
110 | cache->unused--; | 110 | cache->unused--; |
@@ -286,7 +286,7 @@ cleanup: | |||
286 | 286 | ||
287 | 287 | ||
288 | /* | 288 | /* |
289 | * Copy upto length bytes from cache entry to buffer starting at offset bytes | 289 | * Copy up to length bytes from cache entry to buffer starting at offset bytes |
290 | * into the cache entry. If there's not length bytes then copy the number of | 290 | * into the cache entry. If there's not length bytes then copy the number of |
291 | * bytes available. In all cases return the number of bytes copied. | 291 | * bytes available. In all cases return the number of bytes copied. |
292 | */ | 292 | */ |
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/dir.c b/fs/squashfs/dir.c index 0dc340aa2be9..3f79cd1d0c19 100644 --- a/fs/squashfs/dir.c +++ b/fs/squashfs/dir.c | |||
@@ -172,6 +172,11 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
172 | length += sizeof(dirh); | 172 | length += sizeof(dirh); |
173 | 173 | ||
174 | dir_count = le32_to_cpu(dirh.count) + 1; | 174 | dir_count = le32_to_cpu(dirh.count) + 1; |
175 | |||
176 | /* dir_count should never be larger than 256 */ | ||
177 | if (dir_count > 256) | ||
178 | goto failed_read; | ||
179 | |||
175 | while (dir_count--) { | 180 | while (dir_count--) { |
176 | /* | 181 | /* |
177 | * Read directory entry. | 182 | * Read directory entry. |
@@ -183,6 +188,10 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) | |||
183 | 188 | ||
184 | size = le16_to_cpu(dire->size) + 1; | 189 | size = le16_to_cpu(dire->size) + 1; |
185 | 190 | ||
191 | /* size should never be larger than SQUASHFS_NAME_LEN */ | ||
192 | if (size > SQUASHFS_NAME_LEN) | ||
193 | goto failed_read; | ||
194 | |||
186 | err = squashfs_read_metadata(inode->i_sb, dire->name, | 195 | err = squashfs_read_metadata(inode->i_sb, dire->name, |
187 | &block, &offset, size); | 196 | &block, &offset, size); |
188 | if (err < 0) | 197 | if (err < 0) |
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/namei.c b/fs/squashfs/namei.c index 7a9464d08cf6..5d922a6701ab 100644 --- a/fs/squashfs/namei.c +++ b/fs/squashfs/namei.c | |||
@@ -176,6 +176,11 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, | |||
176 | length += sizeof(dirh); | 176 | length += sizeof(dirh); |
177 | 177 | ||
178 | dir_count = le32_to_cpu(dirh.count) + 1; | 178 | dir_count = le32_to_cpu(dirh.count) + 1; |
179 | |||
180 | /* dir_count should never be larger than 256 */ | ||
181 | if (dir_count > 256) | ||
182 | goto data_error; | ||
183 | |||
179 | while (dir_count--) { | 184 | while (dir_count--) { |
180 | /* | 185 | /* |
181 | * Read directory entry. | 186 | * Read directory entry. |
@@ -187,6 +192,10 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, | |||
187 | 192 | ||
188 | size = le16_to_cpu(dire->size) + 1; | 193 | size = le16_to_cpu(dire->size) + 1; |
189 | 194 | ||
195 | /* size should never be larger than SQUASHFS_NAME_LEN */ | ||
196 | if (size > SQUASHFS_NAME_LEN) | ||
197 | goto data_error; | ||
198 | |||
190 | err = squashfs_read_metadata(dir->i_sb, dire->name, | 199 | err = squashfs_read_metadata(dir->i_sb, dire->name, |
191 | &block, &offset, size); | 200 | &block, &offset, size); |
192 | if (err < 0) | 201 | if (err < 0) |
@@ -228,6 +237,9 @@ exit_lookup: | |||
228 | d_add(dentry, inode); | 237 | d_add(dentry, inode); |
229 | return ERR_PTR(0); | 238 | return ERR_PTR(0); |
230 | 239 | ||
240 | data_error: | ||
241 | err = -EIO; | ||
242 | |||
231 | read_failure: | 243 | read_failure: |
232 | ERROR("Unable to read directory block [%llx:%x]\n", | 244 | ERROR("Unable to read directory block [%llx:%x]\n", |
233 | squashfs_i(dir)->start + msblk->directory_table, | 245 | squashfs_i(dir)->start + msblk->directory_table, |
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..5c8184c061a4 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)); |
@@ -370,8 +373,8 @@ static void squashfs_put_super(struct super_block *sb) | |||
370 | } | 373 | } |
371 | 374 | ||
372 | 375 | ||
373 | static struct dentry *squashfs_mount(struct file_system_type *fs_type, int flags, | 376 | static struct dentry *squashfs_mount(struct file_system_type *fs_type, |
374 | const char *dev_name, void *data) | 377 | int flags, const char *dev_name, void *data) |
375 | { | 378 | { |
376 | return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super); | 379 | return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super); |
377 | } | 380 | } |
diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c index c4eb40018256..aa47a286d1f8 100644 --- a/fs/squashfs/xz_wrapper.c +++ b/fs/squashfs/xz_wrapper.c | |||
@@ -26,10 +26,10 @@ | |||
26 | #include <linux/buffer_head.h> | 26 | #include <linux/buffer_head.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/xz.h> | 28 | #include <linux/xz.h> |
29 | #include <linux/bitops.h> | ||
29 | 30 | ||
30 | #include "squashfs_fs.h" | 31 | #include "squashfs_fs.h" |
31 | #include "squashfs_fs_sb.h" | 32 | #include "squashfs_fs_sb.h" |
32 | #include "squashfs_fs_i.h" | ||
33 | #include "squashfs.h" | 33 | #include "squashfs.h" |
34 | #include "decompressor.h" | 34 | #include "decompressor.h" |
35 | 35 | ||
@@ -38,24 +38,57 @@ 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 | struct comp_opts { |
42 | __le32 dictionary_size; | ||
43 | __le32 flags; | ||
44 | }; | ||
45 | |||
46 | static void *squashfs_xz_init(struct squashfs_sb_info *msblk, void *buff, | ||
47 | int len) | ||
42 | { | 48 | { |
43 | int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); | 49 | struct comp_opts *comp_opts = buff; |
50 | struct squashfs_xz *stream; | ||
51 | int dict_size = msblk->block_size; | ||
52 | int err, n; | ||
53 | |||
54 | if (comp_opts) { | ||
55 | /* check compressor options are the expected length */ | ||
56 | if (len < sizeof(*comp_opts)) { | ||
57 | err = -EIO; | ||
58 | goto failed; | ||
59 | } | ||
44 | 60 | ||
45 | struct squashfs_xz *stream = kmalloc(sizeof(*stream), GFP_KERNEL); | 61 | dict_size = le32_to_cpu(comp_opts->dictionary_size); |
46 | if (stream == NULL) | 62 | |
63 | /* the dictionary size should be 2^n or 2^n+2^(n+1) */ | ||
64 | n = ffs(dict_size) - 1; | ||
65 | if (dict_size != (1 << n) && dict_size != (1 << n) + | ||
66 | (1 << (n + 1))) { | ||
67 | err = -EIO; | ||
68 | goto failed; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | dict_size = max_t(int, dict_size, SQUASHFS_METADATA_SIZE); | ||
73 | |||
74 | stream = kmalloc(sizeof(*stream), GFP_KERNEL); | ||
75 | if (stream == NULL) { | ||
76 | err = -ENOMEM; | ||
47 | goto failed; | 77 | goto failed; |
78 | } | ||
48 | 79 | ||
49 | stream->state = xz_dec_init(XZ_PREALLOC, block_size); | 80 | stream->state = xz_dec_init(XZ_PREALLOC, dict_size); |
50 | if (stream->state == NULL) | 81 | if (stream->state == NULL) { |
82 | kfree(stream); | ||
83 | err = -ENOMEM; | ||
51 | goto failed; | 84 | goto failed; |
85 | } | ||
52 | 86 | ||
53 | return stream; | 87 | return stream; |
54 | 88 | ||
55 | failed: | 89 | failed: |
56 | ERROR("Failed to allocate xz workspace\n"); | 90 | ERROR("Failed to initialise xz decompressor\n"); |
57 | kfree(stream); | 91 | return ERR_PTR(err); |
58 | return NULL; | ||
59 | } | 92 | } |
60 | 93 | ||
61 | 94 | ||
diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c index 4661ae2b1cec..517688b32ffa 100644 --- a/fs/squashfs/zlib_wrapper.c +++ b/fs/squashfs/zlib_wrapper.c | |||
@@ -26,19 +26,19 @@ | |||
26 | #include <linux/buffer_head.h> | 26 | #include <linux/buffer_head.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/zlib.h> | 28 | #include <linux/zlib.h> |
29 | #include <linux/vmalloc.h> | ||
29 | 30 | ||
30 | #include "squashfs_fs.h" | 31 | #include "squashfs_fs.h" |
31 | #include "squashfs_fs_sb.h" | 32 | #include "squashfs_fs_sb.h" |
32 | #include "squashfs.h" | 33 | #include "squashfs.h" |
33 | #include "decompressor.h" | 34 | #include "decompressor.h" |
34 | 35 | ||
35 | static void *zlib_init(struct squashfs_sb_info *dummy) | 36 | static void *zlib_init(struct squashfs_sb_info *dummy, void *buff, int len) |
36 | { | 37 | { |
37 | z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); | 38 | z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); |
38 | if (stream == NULL) | 39 | if (stream == NULL) |
39 | goto failed; | 40 | goto failed; |
40 | stream->workspace = kmalloc(zlib_inflate_workspacesize(), | 41 | stream->workspace = vmalloc(zlib_inflate_workspacesize()); |
41 | GFP_KERNEL); | ||
42 | if (stream->workspace == NULL) | 42 | if (stream->workspace == NULL) |
43 | goto failed; | 43 | goto failed; |
44 | 44 | ||
@@ -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 | ||
@@ -56,7 +56,7 @@ static void zlib_free(void *strm) | |||
56 | z_stream *stream = strm; | 56 | z_stream *stream = strm; |
57 | 57 | ||
58 | if (stream) | 58 | if (stream) |
59 | kfree(stream->workspace); | 59 | vfree(stream->workspace); |
60 | kfree(stream); | 60 | kfree(stream); |
61 | } | 61 | } |
62 | 62 | ||