]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Squashfs: extend decompressor framework to handle compression options
authorPhillip Lougher <phillip@lougher.demon.co.uk>
Mon, 28 Feb 2011 01:45:42 +0000 (01:45 +0000)
committerPhillip Lougher <phillip@lougher.demon.co.uk>
Mon, 28 Feb 2011 18:21:59 +0000 (18:21 +0000)
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>
fs/squashfs/decompressor.c
fs/squashfs/decompressor.h
fs/squashfs/lzo_wrapper.c
fs/squashfs/squashfs.h
fs/squashfs/squashfs_fs.h
fs/squashfs/super.c
fs/squashfs/xz_wrapper.c
fs/squashfs/zlib_wrapper.c

index a5940e54c4ddedba7a9f8ae7b2a9a8401669b19b..e921bd213738fdfe1d15b50150c1060986d3e0ec 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <linux/types.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/buffer_head.h>
 
 #include "squashfs_fs.h"
@@ -74,3 +75,36 @@ const struct squashfs_decompressor *squashfs_lookup_decompressor(int id)
 
        return decompressor[i];
 }
+
+
+void *squashfs_decompressor_init(struct super_block *sb, unsigned short flags)
+{
+       struct squashfs_sb_info *msblk = sb->s_fs_info;
+       void *strm, *buffer = NULL;
+       int length = 0;
+
+       /*
+        * Read decompressor specific options from file system if present
+        */
+       if (SQUASHFS_COMP_OPTS(flags)) {
+               buffer = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
+               if (buffer == NULL)
+                       return ERR_PTR(-ENOMEM);
+
+               length = squashfs_read_data(sb, &buffer,
+                       sizeof(struct squashfs_super_block), 0, NULL,
+                       PAGE_CACHE_SIZE, 1);
+
+               if (length < 0) {
+                       strm = ERR_PTR(length);
+                       goto finished;
+               }
+       }
+
+       strm = msblk->decompressor->init(msblk, buffer, length);
+
+finished:
+       kfree(buffer);
+
+       return strm;
+}
index 3b305a70f7aa22a17e687495aab097c27cd18722..099745ad5691ed1e129afba411eb56e821a4be27 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 struct squashfs_decompressor {
-       void    *(*init)(struct squashfs_sb_info *);
+       void    *(*init)(struct squashfs_sb_info *, void *, int);
        void    (*free)(void *);
        int     (*decompress)(struct squashfs_sb_info *, void **,
                struct buffer_head **, int, int, int, int, int);
@@ -33,11 +33,6 @@ struct squashfs_decompressor {
        int     supported;
 };
 
-static inline void *squashfs_decompressor_init(struct squashfs_sb_info *msblk)
-{
-       return msblk->decompressor->init(msblk);
-}
-
 static inline void squashfs_decompressor_free(struct squashfs_sb_info *msblk,
        void *s)
 {
index 7da759e34c525e8bb12efd2ae496b0776349c3b0..00f4dfc5f0884cb6d77920130883521b04635784 100644 (file)
@@ -37,7 +37,7 @@ struct squashfs_lzo {
        void    *output;
 };
 
-static void *lzo_init(struct squashfs_sb_info *msblk)
+static void *lzo_init(struct squashfs_sb_info *msblk, void *buff, int len)
 {
        int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
 
@@ -58,7 +58,7 @@ failed2:
 failed:
        ERROR("Failed to allocate lzo workspace\n");
        kfree(stream);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
 
index ba729d808876de53b7168bdcd69bf738d3fb6b41..1f2e608b87858ffdd39911bd09155e4bbc845cac 100644 (file)
@@ -48,6 +48,7 @@ extern int squashfs_read_table(struct super_block *, void *, u64, int);
 
 /* decompressor.c */
 extern const struct squashfs_decompressor *squashfs_lookup_decompressor(int);
+extern void *squashfs_decompressor_init(struct super_block *, unsigned short);
 
 /* export.c */
 extern __le64 *squashfs_read_inode_lookup_table(struct super_block *, u64,
index 39533feffd6d3a3e02d8a5ceeb5f37c93587c656..4582c568ef4d115df3491af9f7c46216e5acb7bf 100644 (file)
@@ -57,6 +57,7 @@
 #define SQUASHFS_ALWAYS_FRAG           5
 #define SQUASHFS_DUPLICATE             6
 #define SQUASHFS_EXPORT                        7
+#define SQUASHFS_COMP_OPT              10
 
 #define SQUASHFS_BIT(flag, bit)                ((flag >> bit) & 1)
 
@@ -81,6 +82,9 @@
 #define SQUASHFS_EXPORTABLE(flags)             SQUASHFS_BIT(flags, \
                                                SQUASHFS_EXPORT)
 
+#define SQUASHFS_COMP_OPTS(flags)              SQUASHFS_BIT(flags, \
+                                               SQUASHFS_COMP_OPT)
+
 /* Max number of types and file types */
 #define SQUASHFS_DIR_TYPE              1
 #define SQUASHFS_REG_TYPE              2
index 20700b9f2b4cdf6a7e4d921e741839c1bb8427d7..95467db71a8e556228b93bf3f3abd0449555b114 100644 (file)
@@ -199,10 +199,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
 
        err = -ENOMEM;
 
-       msblk->stream = squashfs_decompressor_init(msblk);
-       if (msblk->stream == NULL)
-               goto failed_mount;
-
        msblk->block_cache = squashfs_cache_init("metadata",
                        SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
        if (msblk->block_cache == NULL)
@@ -215,6 +211,13 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
                goto failed_mount;
        }
 
+       msblk->stream = squashfs_decompressor_init(sb, flags);
+       if (IS_ERR(msblk->stream)) {
+               err = PTR_ERR(msblk->stream);
+               msblk->stream = NULL;
+               goto failed_mount;
+       }
+
        /* Allocate and read id index table */
        msblk->id_table = squashfs_read_id_index_table(sb,
                le64_to_cpu(sblk->id_table_start), le16_to_cpu(sblk->no_ids));
index c4eb400182564c13728fc88f95edf6db294eb2ac..397adea72eb96189e1eac5598ea0a70f63109cc4 100644 (file)
@@ -38,7 +38,8 @@ struct squashfs_xz {
        struct xz_buf buf;
 };
 
-static void *squashfs_xz_init(struct squashfs_sb_info *msblk)
+static void *squashfs_xz_init(struct squashfs_sb_info *msblk, void *buff,
+       int len)
 {
        int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE);
 
@@ -55,7 +56,7 @@ static void *squashfs_xz_init(struct squashfs_sb_info *msblk)
 failed:
        ERROR("Failed to allocate xz workspace\n");
        kfree(stream);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
 
index 4661ae2b1cec8040adcadc4018deb63735309f92..195b0d035e9b47a0c23520406e68820cdc0eb5a4 100644 (file)
@@ -32,7 +32,7 @@
 #include "squashfs.h"
 #include "decompressor.h"
 
-static void *zlib_init(struct squashfs_sb_info *dummy)
+static void *zlib_init(struct squashfs_sb_info *dummy, void *buff, int len)
 {
        z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
        if (stream == NULL)
@@ -47,7 +47,7 @@ static void *zlib_init(struct squashfs_sb_info *dummy)
 failed:
        ERROR("Failed to allocate zlib workspace\n");
        kfree(stream);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }