Commit b7fc0ff09d24b372dc04b0c02b80659c0a66fdfe

Authored by Phillip Lougher
1 parent 100b33c8bd

Squashfs: extend decompressor framework to handle compression options

Extend decompressor framework to handle compression options stored in
the filesystem.  These options can be used by the relevant decompressor
at initialisation time to over-ride defaults.

The presence of compression options in the filesystem is indicated by
the COMP_OPT filesystem flag.  If present the data is read from the
filesystem and passed to the decompressor init function.  The decompressor
init function signature has been extended to take this data.

Also update the init function signature in the glib, lzo and xz
decompressor wrappers.

Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>

Showing 8 changed files with 54 additions and 16 deletions Side-by-side Diff

fs/squashfs/decompressor.c
... ... @@ -23,6 +23,7 @@
23 23  
24 24 #include <linux/types.h>
25 25 #include <linux/mutex.h>
  26 +#include <linux/slab.h>
26 27 #include <linux/buffer_head.h>
27 28  
28 29 #include "squashfs_fs.h"
... ... @@ -73,5 +74,38 @@
73 74 break;
74 75  
75 76 return decompressor[i];
  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;
76 110 }
fs/squashfs/decompressor.h
... ... @@ -24,7 +24,7 @@
24 24 */
25 25  
26 26 struct squashfs_decompressor {
27   - void *(*init)(struct squashfs_sb_info *);
  27 + void *(*init)(struct squashfs_sb_info *, void *, int);
28 28 void (*free)(void *);
29 29 int (*decompress)(struct squashfs_sb_info *, void **,
30 30 struct buffer_head **, int, int, int, int, int);
... ... @@ -32,11 +32,6 @@
32 32 char *name;
33 33 int supported;
34 34 };
35   -
36   -static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk)
37   -{
38   - return msblk->decompressor->init(msblk);
39   -}
40 35  
41 36 static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk,
42 37 void *s)
fs/squashfs/lzo_wrapper.c
... ... @@ -37,7 +37,7 @@
37 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 42 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
43 43  
... ... @@ -58,7 +58,7 @@
58 58 failed:
59 59 ERROR("Failed to allocate lzo workspace\n");
60 60 kfree(stream);
61   - return NULL;
  61 + return ERR_PTR(-ENOMEM);
62 62 }
63 63  
64 64  
fs/squashfs/squashfs.h
... ... @@ -48,6 +48,7 @@
48 48  
49 49 /* decompressor.c */
50 50 extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
  51 +extern void *squashfs_decompressor_init(struct super_block *, unsigned short);
51 52  
52 53 /* export.c */
53 54 extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64,
fs/squashfs/squashfs_fs.h
... ... @@ -57,6 +57,7 @@
57 57 #define SQUASHFS_ALWAYS_FRAG 5
58 58 #define SQUASHFS_DUPLICATE 6
59 59 #define SQUASHFS_EXPORT 7
  60 +#define SQUASHFS_COMP_OPT 10
60 61  
61 62 #define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
62 63  
... ... @@ -80,6 +81,9 @@
80 81  
81 82 #define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
82 83 SQUASHFS_EXPORT)
  84 +
  85 +#define SQUASHFS_COMP_OPTS(flags) SQUASHFS_BIT(flags, \
  86 + SQUASHFS_COMP_OPT)
83 87  
84 88 /* Max number of types and file types */
85 89 #define SQUASHFS_DIR_TYPE 1
... ... @@ -199,10 +199,6 @@
199 199  
200 200 err = -ENOMEM;
201 201  
202   - msblk->stream = squashfs_decompressor_init(msblk);
203   - if (msblk->stream == NULL)
204   - goto failed_mount;
205   -
206 202 msblk->block_cache = squashfs_cache_init("metadata",
207 203 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
208 204 if (msblk->block_cache == NULL)
... ... @@ -212,6 +208,13 @@
212 208 msblk->read_page = squashfs_cache_init("data", 1, msblk->block_size);
213 209 if (msblk->read_page == NULL) {
214 210 ERROR("Failed to allocate read_page block\n");
  211 + goto failed_mount;
  212 + }
  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;
215 218 goto failed_mount;
216 219 }
217 220  
fs/squashfs/xz_wrapper.c
... ... @@ -38,7 +38,8 @@
38 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 44 int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
44 45  
... ... @@ -55,7 +56,7 @@
55 56 failed:
56 57 ERROR("Failed to allocate xz workspace\n");
57 58 kfree(stream);
58   - return NULL;
  59 + return ERR_PTR(-ENOMEM);
59 60 }
60 61  
61 62  
fs/squashfs/zlib_wrapper.c
... ... @@ -32,7 +32,7 @@
32 32 #include "squashfs.h"
33 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 37 z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
38 38 if (stream == NULL)
... ... @@ -47,7 +47,7 @@
47 47 failed:
48 48 ERROR("Failed to allocate zlib workspace\n");
49 49 kfree(stream);
50   - return NULL;
  50 + return ERR_PTR(-ENOMEM);
51 51 }
52 52  
53 53