[kernel] generic-2.6/2.6.30: refresh patches
[10.03/openwrt.git] / target / linux / generic-2.6 / patches-2.6.30 / 051-squashfs_pcomp.patch
1 --- a/fs/squashfs/Kconfig
2 +++ b/fs/squashfs/Kconfig
3 @@ -1,7 +1,8 @@
4  config SQUASHFS
5         tristate "SquashFS 4.0 - Squashed file system support"
6         depends on BLOCK
7 -       select ZLIB_INFLATE
8 +       select CRYPTO
9 +       select CRYPTO_ZLIB
10         help
11           Saying Y here includes support for SquashFS 4.0 (a Compressed
12           Read-Only File System).  Squashfs is a highly compressed read-only
13 --- a/fs/squashfs/block.c
14 +++ b/fs/squashfs/block.c
15 @@ -32,7 +32,8 @@
16  #include <linux/mutex.h>
17  #include <linux/string.h>
18  #include <linux/buffer_head.h>
19 -#include <linux/zlib.h>
20 +
21 +#include <crypto/compress.h>
22  
23  #include "squashfs_fs.h"
24  #include "squashfs_fs_sb.h"
25 @@ -153,7 +154,8 @@ int squashfs_read_data(struct super_bloc
26         }
27  
28         if (compressed) {
29 -               int zlib_err = 0, zlib_init = 0;
30 +               int res = 0, decomp_init = 0;
31 +               struct comp_request req;
32  
33                 /*
34                  * Uncompress block.
35 @@ -161,12 +163,13 @@ int squashfs_read_data(struct super_bloc
36  
37                 mutex_lock(&msblk->read_data_mutex);
38  
39 -               msblk->stream.avail_out = 0;
40 -               msblk->stream.avail_in = 0;
41 +               req.avail_out = 0;
42 +               req.avail_in = 0;
43  
44                 bytes = length;
45 +               length = 0;
46                 do {
47 -                       if (msblk->stream.avail_in == 0 && k < b) {
48 +                       if (req.avail_in == 0 && k < b) {
49                                 avail = min(bytes, msblk->devblksize - offset);
50                                 bytes -= avail;
51                                 wait_on_buffer(bh[k]);
52 @@ -179,45 +182,47 @@ int squashfs_read_data(struct super_bloc
53                                         continue;
54                                 }
55  
56 -                               msblk->stream.next_in = bh[k]->b_data + offset;
57 -                               msblk->stream.avail_in = avail;
58 +                               req.next_in = bh[k]->b_data + offset;
59 +                               req.avail_in = avail;
60                                 offset = 0;
61                         }
62  
63 -                       if (msblk->stream.avail_out == 0 && page < pages) {
64 -                               msblk->stream.next_out = buffer[page++];
65 -                               msblk->stream.avail_out = PAGE_CACHE_SIZE;
66 +                       if (req.avail_out == 0 && page < pages) {
67 +                               req.next_out = buffer[page++];
68 +                               req.avail_out = PAGE_CACHE_SIZE;
69                         }
70  
71 -                       if (!zlib_init) {
72 -                               zlib_err = zlib_inflateInit(&msblk->stream);
73 -                               if (zlib_err != Z_OK) {
74 -                                       ERROR("zlib_inflateInit returned"
75 -                                               " unexpected result 0x%x,"
76 -                                               " srclength %d\n", zlib_err,
77 -                                               srclength);
78 +                       if (!decomp_init) {
79 +                               res = crypto_decompress_init(msblk->tfm);
80 +                               if (res) {
81 +                                       ERROR("crypto_decompress_init "
82 +                                               "returned %d, srclength %d\n",
83 +                                               res, srclength);
84                                         goto release_mutex;
85                                 }
86 -                               zlib_init = 1;
87 +                               decomp_init = 1;
88                         }
89  
90 -                       zlib_err = zlib_inflate(&msblk->stream, Z_SYNC_FLUSH);
91 +                       res = crypto_decompress_update(msblk->tfm, &req);
92 +                       if (res < 0) {
93 +                               ERROR("crypto_decompress_update returned %d, "
94 +                                       "data probably corrupt\n", res);
95 +                               goto release_mutex;
96 +                       }
97 +                       length += res;
98  
99 -                       if (msblk->stream.avail_in == 0 && k < b)
100 +                       if (req.avail_in == 0 && k < b)
101                                 put_bh(bh[k++]);
102 -               } while (zlib_err == Z_OK);
103 +               } while (bytes || res);
104  
105 -               if (zlib_err != Z_STREAM_END) {
106 -                       ERROR("zlib_inflate error, data probably corrupt\n");
107 +               res = crypto_decompress_final(msblk->tfm, &req);
108 +               if (res < 0) {
109 +                       ERROR("crypto_decompress_final returned %d, data "
110 +                               "probably corrupt\n", res);
111                         goto release_mutex;
112                 }
113 +               length += res;
114  
115 -               zlib_err = zlib_inflateEnd(&msblk->stream);
116 -               if (zlib_err != Z_OK) {
117 -                       ERROR("zlib_inflate error, data probably corrupt\n");
118 -                       goto release_mutex;
119 -               }
120 -               length = msblk->stream.total_out;
121                 mutex_unlock(&msblk->read_data_mutex);
122         } else {
123                 /*
124 --- a/fs/squashfs/squashfs_fs_sb.h
125 +++ b/fs/squashfs/squashfs_fs_sb.h
126 @@ -64,7 +64,7 @@ struct squashfs_sb_info {
127         struct mutex            read_data_mutex;
128         struct mutex            meta_index_mutex;
129         struct meta_index       *meta_index;
130 -       z_stream                stream;
131 +       struct crypto_pcomp     *tfm;
132         __le64                  *inode_lookup_table;
133         u64                     inode_table;
134         u64                     directory_table;
135 --- a/fs/squashfs/super.c
136 +++ b/fs/squashfs/super.c
137 @@ -37,11 +37,19 @@
138  #include <linux/zlib.h>
139  #include <linux/magic.h>
140  
141 +#include <crypto/compress.h>
142 +
143 +#include <net/netlink.h>
144 +
145  #include "squashfs_fs.h"
146  #include "squashfs_fs_sb.h"
147  #include "squashfs_fs_i.h"
148  #include "squashfs.h"
149  
150 +
151 +#define SQUASHFS_CRYPTO_ALG    "zlib"
152 +
153 +
154  static struct file_system_type squashfs_fs_type;
155  static struct super_operations squashfs_super_ops;
156  
157 @@ -75,6 +83,16 @@ static int squashfs_fill_super(struct su
158         unsigned short flags;
159         unsigned int fragments;
160         u64 lookup_table_start;
161 +       struct {
162 +               struct nlattr nla;
163 +               int val;
164 +       } params = {
165 +               .nla = {
166 +                       .nla_len        = nla_attr_size(sizeof(int)),
167 +                       .nla_type       = ZLIB_DECOMP_WINDOWBITS,
168 +               },
169 +               .val                    = DEF_WBITS,
170 +       };
171         int err;
172  
173         TRACE("Entered squashfs_fill_superblock\n");
174 @@ -86,16 +104,25 @@ static int squashfs_fill_super(struct su
175         }
176         msblk = sb->s_fs_info;
177  
178 -       msblk->stream.workspace = kmalloc(zlib_inflate_workspacesize(),
179 -               GFP_KERNEL);
180 -       if (msblk->stream.workspace == NULL) {
181 -               ERROR("Failed to allocate zlib workspace\n");
182 +       msblk->tfm = crypto_alloc_pcomp(SQUASHFS_CRYPTO_ALG, 0,
183 +                                       CRYPTO_ALG_ASYNC);
184 +       if (IS_ERR(msblk->tfm)) {
185 +               ERROR("Failed to load %s crypto module\n",
186 +                     SQUASHFS_CRYPTO_ALG);
187 +               err = PTR_ERR(msblk->tfm);
188 +               goto failed_pcomp;
189 +       }
190 +
191 +       err = crypto_decompress_setup(msblk->tfm, &params, sizeof(params));
192 +       if (err) {
193 +               ERROR("Failed to set up decompression parameters\n");
194                 goto failure;
195         }
196  
197         sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
198         if (sblk == NULL) {
199                 ERROR("Failed to allocate squashfs_super_block\n");
200 +               err = -ENOMEM;
201                 goto failure;
202         }
203  
204 @@ -294,17 +321,18 @@ failed_mount:
205         kfree(msblk->inode_lookup_table);
206         kfree(msblk->fragment_index);
207         kfree(msblk->id_table);
208 -       kfree(msblk->stream.workspace);
209 +       crypto_free_pcomp(msblk->tfm);
210         kfree(sb->s_fs_info);
211         sb->s_fs_info = NULL;
212         kfree(sblk);
213         return err;
214  
215  failure:
216 -       kfree(msblk->stream.workspace);
217 +       crypto_free_pcomp(msblk->tfm);
218 +failed_pcomp:
219         kfree(sb->s_fs_info);
220         sb->s_fs_info = NULL;
221 -       return -ENOMEM;
222 +       return err;
223  }
224  
225  
226 @@ -346,7 +374,7 @@ static void squashfs_put_super(struct su
227                 kfree(sbi->id_table);
228                 kfree(sbi->fragment_index);
229                 kfree(sbi->meta_index);
230 -               kfree(sbi->stream.workspace);
231 +               crypto_free_pcomp(sbi->tfm);
232                 kfree(sb->s_fs_info);
233                 sb->s_fs_info = NULL;
234         }