#include <linux/types.h>
 #include <linux/mutex.h>
+#include <linux/slab.h>
 #include <linux/buffer_head.h>
 
 #include "squashfs_fs.h"
 
        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;
+}
 
  */
 
 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);
        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)
 {
 
        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);
 
 failed:
        ERROR("Failed to allocate lzo workspace\n");
        kfree(stream);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
 
 
 
 /* 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,
 
 #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)
 
 #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
 
 
        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)
                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));
 
        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);
 
 failed:
        ERROR("Failed to allocate xz workspace\n");
        kfree(stream);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }
 
 
 
 #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)
 failed:
        ERROR("Failed to allocate zlib workspace\n");
        kfree(stream);
-       return NULL;
+       return ERR_PTR(-ENOMEM);
 }