diff options
-rw-r--r-- | crypto/deflate.c | 3 | ||||
-rw-r--r-- | crypto/zlib.c | 18 | ||||
-rw-r--r-- | drivers/net/ppp_deflate.c | 2 | ||||
-rw-r--r-- | fs/btrfs/zlib.c | 3 | ||||
-rw-r--r-- | fs/jffs2/compr_zlib.c | 7 | ||||
-rw-r--r-- | fs/logfs/compr.c | 2 | ||||
-rw-r--r-- | include/linux/zlib.h | 11 | ||||
-rw-r--r-- | lib/zlib_deflate/deflate.c | 31 | ||||
-rw-r--r-- | lib/zlib_deflate/defutil.h | 17 |
9 files changed, 71 insertions, 23 deletions
diff --git a/crypto/deflate.c b/crypto/deflate.c index cbc7a33a9600..b5ccae29be74 100644 --- a/crypto/deflate.c +++ b/crypto/deflate.c | |||
@@ -48,7 +48,8 @@ static int deflate_comp_init(struct deflate_ctx *ctx) | |||
48 | int ret = 0; | 48 | int ret = 0; |
49 | struct z_stream_s *stream = &ctx->comp_stream; | 49 | struct z_stream_s *stream = &ctx->comp_stream; |
50 | 50 | ||
51 | stream->workspace = vzalloc(zlib_deflate_workspacesize()); | 51 | stream->workspace = vzalloc(zlib_deflate_workspacesize( |
52 | -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL)); | ||
52 | if (!stream->workspace) { | 53 | if (!stream->workspace) { |
53 | ret = -ENOMEM; | 54 | ret = -ENOMEM; |
54 | goto out; | 55 | goto out; |
diff --git a/crypto/zlib.c b/crypto/zlib.c index 739b8fca4cea..d11d761a5e41 100644 --- a/crypto/zlib.c +++ b/crypto/zlib.c | |||
@@ -85,6 +85,7 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params, | |||
85 | struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); | 85 | struct zlib_ctx *ctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); |
86 | struct z_stream_s *stream = &ctx->comp_stream; | 86 | struct z_stream_s *stream = &ctx->comp_stream; |
87 | struct nlattr *tb[ZLIB_COMP_MAX + 1]; | 87 | struct nlattr *tb[ZLIB_COMP_MAX + 1]; |
88 | int window_bits, mem_level; | ||
88 | size_t workspacesize; | 89 | size_t workspacesize; |
89 | int ret; | 90 | int ret; |
90 | 91 | ||
@@ -94,7 +95,14 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params, | |||
94 | 95 | ||
95 | zlib_comp_exit(ctx); | 96 | zlib_comp_exit(ctx); |
96 | 97 | ||
97 | workspacesize = zlib_deflate_workspacesize(); | 98 | window_bits = tb[ZLIB_COMP_WINDOWBITS] |
99 | ? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS]) | ||
100 | : MAX_WBITS; | ||
101 | mem_level = tb[ZLIB_COMP_MEMLEVEL] | ||
102 | ? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL]) | ||
103 | : DEF_MEM_LEVEL; | ||
104 | |||
105 | workspacesize = zlib_deflate_workspacesize(window_bits, mem_level); | ||
98 | stream->workspace = vzalloc(workspacesize); | 106 | stream->workspace = vzalloc(workspacesize); |
99 | if (!stream->workspace) | 107 | if (!stream->workspace) |
100 | return -ENOMEM; | 108 | return -ENOMEM; |
@@ -106,12 +114,8 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params, | |||
106 | tb[ZLIB_COMP_METHOD] | 114 | tb[ZLIB_COMP_METHOD] |
107 | ? nla_get_u32(tb[ZLIB_COMP_METHOD]) | 115 | ? nla_get_u32(tb[ZLIB_COMP_METHOD]) |
108 | : Z_DEFLATED, | 116 | : Z_DEFLATED, |
109 | tb[ZLIB_COMP_WINDOWBITS] | 117 | window_bits, |
110 | ? nla_get_u32(tb[ZLIB_COMP_WINDOWBITS]) | 118 | mem_level, |
111 | : MAX_WBITS, | ||
112 | tb[ZLIB_COMP_MEMLEVEL] | ||
113 | ? nla_get_u32(tb[ZLIB_COMP_MEMLEVEL]) | ||
114 | : DEF_MEM_LEVEL, | ||
115 | tb[ZLIB_COMP_STRATEGY] | 119 | tb[ZLIB_COMP_STRATEGY] |
116 | ? nla_get_u32(tb[ZLIB_COMP_STRATEGY]) | 120 | ? nla_get_u32(tb[ZLIB_COMP_STRATEGY]) |
117 | : Z_DEFAULT_STRATEGY); | 121 | : Z_DEFAULT_STRATEGY); |
diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c index 43583309a65d..31e9407a0739 100644 --- a/drivers/net/ppp_deflate.c +++ b/drivers/net/ppp_deflate.c | |||
@@ -129,7 +129,7 @@ static void *z_comp_alloc(unsigned char *options, int opt_len) | |||
129 | 129 | ||
130 | state->strm.next_in = NULL; | 130 | state->strm.next_in = NULL; |
131 | state->w_size = w_size; | 131 | state->w_size = w_size; |
132 | state->strm.workspace = vmalloc(zlib_deflate_workspacesize()); | 132 | state->strm.workspace = vmalloc(zlib_deflate_workspacesize(-w_size, 8)); |
133 | if (state->strm.workspace == NULL) | 133 | if (state->strm.workspace == NULL) |
134 | goto out_free; | 134 | goto out_free; |
135 | 135 | ||
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index f5ec2d44150d..faccd47c6c46 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c | |||
@@ -57,7 +57,8 @@ static struct list_head *zlib_alloc_workspace(void) | |||
57 | if (!workspace) | 57 | if (!workspace) |
58 | return ERR_PTR(-ENOMEM); | 58 | return ERR_PTR(-ENOMEM); |
59 | 59 | ||
60 | workspace->def_strm.workspace = vmalloc(zlib_deflate_workspacesize()); | 60 | workspace->def_strm.workspace = vmalloc(zlib_deflate_workspacesize( |
61 | MAX_WBITS, MAX_MEM_LEVEL)); | ||
61 | workspace->inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); | 62 | workspace->inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); |
62 | workspace->buf = kmalloc(PAGE_CACHE_SIZE, GFP_NOFS); | 63 | workspace->buf = kmalloc(PAGE_CACHE_SIZE, GFP_NOFS); |
63 | if (!workspace->def_strm.workspace || | 64 | if (!workspace->def_strm.workspace || |
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c index fd05a0b9431d..5a001020c542 100644 --- a/fs/jffs2/compr_zlib.c +++ b/fs/jffs2/compr_zlib.c | |||
@@ -40,12 +40,13 @@ static z_stream inf_strm, def_strm; | |||
40 | 40 | ||
41 | static int __init alloc_workspaces(void) | 41 | static int __init alloc_workspaces(void) |
42 | { | 42 | { |
43 | def_strm.workspace = vmalloc(zlib_deflate_workspacesize()); | 43 | def_strm.workspace = vmalloc(zlib_deflate_workspacesize(MAX_WBITS, |
44 | MAX_MEM_LEVEL)); | ||
44 | if (!def_strm.workspace) { | 45 | if (!def_strm.workspace) { |
45 | printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize()); | 46 | printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL)); |
46 | return -ENOMEM; | 47 | return -ENOMEM; |
47 | } | 48 | } |
48 | D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize())); | 49 | D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL))); |
49 | inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); | 50 | inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); |
50 | if (!inf_strm.workspace) { | 51 | if (!inf_strm.workspace) { |
51 | printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize()); | 52 | printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize()); |
diff --git a/fs/logfs/compr.c b/fs/logfs/compr.c index 44bbfd249abc..961f02b86d97 100644 --- a/fs/logfs/compr.c +++ b/fs/logfs/compr.c | |||
@@ -81,7 +81,7 @@ error: | |||
81 | 81 | ||
82 | int __init logfs_compr_init(void) | 82 | int __init logfs_compr_init(void) |
83 | { | 83 | { |
84 | size_t size = max(zlib_deflate_workspacesize(), | 84 | size_t size = max(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL), |
85 | zlib_inflate_workspacesize()); | 85 | zlib_inflate_workspacesize()); |
86 | stream.workspace = vmalloc(size); | 86 | stream.workspace = vmalloc(size); |
87 | if (!stream.workspace) | 87 | if (!stream.workspace) |
diff --git a/include/linux/zlib.h b/include/linux/zlib.h index 40c49cb3eb51..9c5a6b4de0a3 100644 --- a/include/linux/zlib.h +++ b/include/linux/zlib.h | |||
@@ -179,11 +179,16 @@ typedef z_stream *z_streamp; | |||
179 | 179 | ||
180 | /* basic functions */ | 180 | /* basic functions */ |
181 | 181 | ||
182 | extern int zlib_deflate_workspacesize (void); | 182 | extern int zlib_deflate_workspacesize (int windowBits, int memLevel); |
183 | /* | 183 | /* |
184 | Returns the number of bytes that needs to be allocated for a per- | 184 | Returns the number of bytes that needs to be allocated for a per- |
185 | stream workspace. A pointer to this number of bytes should be | 185 | stream workspace with the specified parameters. A pointer to this |
186 | returned in stream->workspace before calling zlib_deflateInit(). | 186 | number of bytes should be returned in stream->workspace before |
187 | you call zlib_deflateInit() or zlib_deflateInit2(). If you call | ||
188 | zlib_deflateInit(), specify windowBits = MAX_WBITS and memLevel = | ||
189 | MAX_MEM_LEVEL here. If you call zlib_deflateInit2(), the windowBits | ||
190 | and memLevel parameters passed to zlib_deflateInit2() must not | ||
191 | exceed those passed here. | ||
187 | */ | 192 | */ |
188 | 193 | ||
189 | /* | 194 | /* |
diff --git a/lib/zlib_deflate/deflate.c b/lib/zlib_deflate/deflate.c index 46a31e5f49c3..d63381e8e333 100644 --- a/lib/zlib_deflate/deflate.c +++ b/lib/zlib_deflate/deflate.c | |||
@@ -176,6 +176,7 @@ int zlib_deflateInit2( | |||
176 | deflate_state *s; | 176 | deflate_state *s; |
177 | int noheader = 0; | 177 | int noheader = 0; |
178 | deflate_workspace *mem; | 178 | deflate_workspace *mem; |
179 | char *next; | ||
179 | 180 | ||
180 | ush *overlay; | 181 | ush *overlay; |
181 | /* We overlay pending_buf and d_buf+l_buf. This works since the average | 182 | /* We overlay pending_buf and d_buf+l_buf. This works since the average |
@@ -199,6 +200,21 @@ int zlib_deflateInit2( | |||
199 | strategy < 0 || strategy > Z_HUFFMAN_ONLY) { | 200 | strategy < 0 || strategy > Z_HUFFMAN_ONLY) { |
200 | return Z_STREAM_ERROR; | 201 | return Z_STREAM_ERROR; |
201 | } | 202 | } |
203 | |||
204 | /* | ||
205 | * Direct the workspace's pointers to the chunks that were allocated | ||
206 | * along with the deflate_workspace struct. | ||
207 | */ | ||
208 | next = (char *) mem; | ||
209 | next += sizeof(*mem); | ||
210 | mem->window_memory = (Byte *) next; | ||
211 | next += zlib_deflate_window_memsize(windowBits); | ||
212 | mem->prev_memory = (Pos *) next; | ||
213 | next += zlib_deflate_prev_memsize(windowBits); | ||
214 | mem->head_memory = (Pos *) next; | ||
215 | next += zlib_deflate_head_memsize(memLevel); | ||
216 | mem->overlay_memory = next; | ||
217 | |||
202 | s = (deflate_state *) &(mem->deflate_memory); | 218 | s = (deflate_state *) &(mem->deflate_memory); |
203 | strm->state = (struct internal_state *)s; | 219 | strm->state = (struct internal_state *)s; |
204 | s->strm = strm; | 220 | s->strm = strm; |
@@ -1247,7 +1263,18 @@ static block_state deflate_slow( | |||
1247 | return flush == Z_FINISH ? finish_done : block_done; | 1263 | return flush == Z_FINISH ? finish_done : block_done; |
1248 | } | 1264 | } |
1249 | 1265 | ||
1250 | int zlib_deflate_workspacesize(void) | 1266 | int zlib_deflate_workspacesize(int windowBits, int memLevel) |
1251 | { | 1267 | { |
1252 | return sizeof(deflate_workspace); | 1268 | if (windowBits < 0) /* undocumented feature: suppress zlib header */ |
1269 | windowBits = -windowBits; | ||
1270 | |||
1271 | /* Since the return value is typically passed to vmalloc() unchecked... */ | ||
1272 | BUG_ON(memLevel < 1 || memLevel > MAX_MEM_LEVEL || windowBits < 9 || | ||
1273 | windowBits > 15); | ||
1274 | |||
1275 | return sizeof(deflate_workspace) | ||
1276 | + zlib_deflate_window_memsize(windowBits) | ||
1277 | + zlib_deflate_prev_memsize(windowBits) | ||
1278 | + zlib_deflate_head_memsize(memLevel) | ||
1279 | + zlib_deflate_overlay_memsize(memLevel); | ||
1253 | } | 1280 | } |
diff --git a/lib/zlib_deflate/defutil.h b/lib/zlib_deflate/defutil.h index 6b15a909ca3f..b640b6402e99 100644 --- a/lib/zlib_deflate/defutil.h +++ b/lib/zlib_deflate/defutil.h | |||
@@ -241,12 +241,21 @@ typedef struct deflate_state { | |||
241 | typedef struct deflate_workspace { | 241 | typedef struct deflate_workspace { |
242 | /* State memory for the deflator */ | 242 | /* State memory for the deflator */ |
243 | deflate_state deflate_memory; | 243 | deflate_state deflate_memory; |
244 | Byte window_memory[2 * (1 << MAX_WBITS)]; | 244 | Byte *window_memory; |
245 | Pos prev_memory[1 << MAX_WBITS]; | 245 | Pos *prev_memory; |
246 | Pos head_memory[1 << (MAX_MEM_LEVEL + 7)]; | 246 | Pos *head_memory; |
247 | char overlay_memory[(1 << (MAX_MEM_LEVEL + 6)) * (sizeof(ush)+2)]; | 247 | char *overlay_memory; |
248 | } deflate_workspace; | 248 | } deflate_workspace; |
249 | 249 | ||
250 | #define zlib_deflate_window_memsize(windowBits) \ | ||
251 | (2 * (1 << (windowBits)) * sizeof(Byte)) | ||
252 | #define zlib_deflate_prev_memsize(windowBits) \ | ||
253 | ((1 << (windowBits)) * sizeof(Pos)) | ||
254 | #define zlib_deflate_head_memsize(memLevel) \ | ||
255 | ((1 << ((memLevel)+7)) * sizeof(Pos)) | ||
256 | #define zlib_deflate_overlay_memsize(memLevel) \ | ||
257 | ((1 << ((memLevel)+6)) * (sizeof(ush)+2)) | ||
258 | |||
250 | /* Output a byte on the stream. | 259 | /* Output a byte on the stream. |
251 | * IN assertion: there is enough room in pending_buf. | 260 | * IN assertion: there is enough room in pending_buf. |
252 | */ | 261 | */ |