The function pointer cramfs_uncompress_block is added inside the
cramfs_sb_info struct, so each mountpoint has its own
cramfs_uncompress_block depends on compression type.

I did some test, and verified multiple cramfs images mounted
successfully regardless of compression(either ZLIB or LZO).

Here is the patch.

diff -Naur linux-2.6.23/fs/cramfs/inode.c 
linux-2.6.23_cramfs_lzo/fs/cramfs/inode.c
--- linux-2.6.23/fs/cramfs/inode.c      2007-10-09 13:31:38.000000000 -0700
+++ linux-2.6.23_cramfs_lzo/fs/cramfs/inode.c   2007-10-30 17:15:34.000000000 
-0700
@@ -274,7 +274,17 @@
                printk(KERN_ERR "cramfs: unsupported filesystem features\n");
                goto out;
        }
-
+       
+       /* check flag to see if LZO compression is used */
+       if (super.flags & CRAMFS_FLAG_LZO_COMPRESSION) {
+               sbi->cramfs_uncompress_block = &cramfs_uncompress_block_lzo;
+               printk("cramfs: LZO compression\n");
+       }
+       else {
+               sbi->cramfs_uncompress_block = &cramfs_uncompress_block_zlib;
+               printk("cramfs: ZLIB compression\n");
+       }
+       
        /* Check that the root inode is in a sane state */
        if (!S_ISDIR(super.root.mode)) {
                printk(KERN_ERR "cramfs: root is not a directory\n");
@@ -486,7 +496,7 @@
                        printk(KERN_ERR "cramfs: bad compressed blocksize 
%u\n", compr_len);
                else {
                        mutex_lock(&read_mutex);
-                       bytes_filled = cramfs_uncompress_block(pgdata,
+                       bytes_filled = ((struct cramfs_sb_info 
*)(sb->s_fs_info))->cramfs_uncompress_block(pgdata,
                                 PAGE_CACHE_SIZE,
                                 cramfs_read(sb, start_offset, compr_len),
                                 compr_len);
diff -Naur linux-2.6.23/fs/cramfs/uncompress.c 
linux-2.6.23_cramfs_lzo/fs/cramfs/uncompress.c
--- linux-2.6.23/fs/cramfs/uncompress.c 2007-10-09 13:31:38.000000000 -0700
+++ linux-2.6.23_cramfs_lzo/fs/cramfs/uncompress.c      2007-10-26 
14:19:01.000000000 -0700
@@ -20,12 +20,16 @@
 #include <linux/vmalloc.h>
 #include <linux/zlib.h>
 #include <linux/cramfs_fs.h>
+#include <linux/lzo.h>
 
 static z_stream stream;
 static int initialized;
 
-/* Returns length of decompressed data. */
-int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
+/* 
+ * uncompress with ZLIB
+ * Returns length of decompressed data. 
+ */
+int cramfs_uncompress_block_zlib(void *dst, int dstlen, void *src, int srclen)
 {
        int err;
 
@@ -48,7 +52,26 @@
        return stream.total_out;
 
 err:
-       printk("Error %d while decompressing!\n", err);
+       printk("ZLIB Error %d while decompressing!\n", err);
+       printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
+       return 0;
+}
+
+/* 
+ * uncompress with LZO
+ * Returns length of decompressed data. 
+ */
+int cramfs_uncompress_block_lzo(void *dst, int dstlen, void *src, int srclen)
+{
+       int err;
+
+       err = lzo1x_decompress_safe(src,srclen,dst,(unsigned int *)&dstlen);
+        if (err != LZO_E_OK)
+                goto err;
+        return dstlen;
+
+err:
+       printk("LZO Error %d while decompressing!\n", err);
        printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
        return 0;
 }
diff -Naur linux-2.6.23/fs/Kconfig linux-2.6.23_cramfs_lzo/fs/Kconfig
--- linux-2.6.23/fs/Kconfig     2007-10-09 13:31:38.000000000 -0700
+++ linux-2.6.23_cramfs_lzo/fs/Kconfig  2007-10-26 14:19:01.000000000 -0700
@@ -1348,6 +1348,7 @@
        tristate "Compressed ROM file system support (cramfs)"
        depends on BLOCK
        select ZLIB_INFLATE
+       select LZO_DECOMPRESS
        help
          Saying Y here includes support for CramFs (Compressed ROM File
          System).  CramFs is designed to be a simple, small, and compressed
diff -Naur linux-2.6.23/include/linux/cramfs_fs.h 
linux-2.6.23_cramfs_lzo/include/linux/cramfs_fs.h
--- linux-2.6.23/include/linux/cramfs_fs.h      2007-10-09 13:31:38.000000000 
-0700
+++ linux-2.6.23_cramfs_lzo/include/linux/cramfs_fs.h   2007-10-26 
14:19:01.000000000 -0700
@@ -73,6 +73,7 @@
 #define CRAMFS_FLAG_HOLES              0x00000100      /* support for holes */
 #define CRAMFS_FLAG_WRONG_SIGNATURE    0x00000200      /* reserved */
 #define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET        0x00000400      /* shifted root 
fs */
+#define CRAMFS_FLAG_LZO_COMPRESSION    0x00000800      /* LZO compression is 
used */
 
 /*
  * Valid values in super.flags.  Currently we refuse to mount
@@ -82,11 +83,16 @@
 #define CRAMFS_SUPPORTED_FLAGS ( 0x000000ff \
                                | CRAMFS_FLAG_HOLES \
                                | CRAMFS_FLAG_WRONG_SIGNATURE \
-                               | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
+                               | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET \
+                               | CRAMFS_FLAG_LZO_COMPRESSION )
+
+/* function pointer for uncompress function */
 
 /* Uncompression interfaces to the underlying zlib */
-int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
+int cramfs_uncompress_block_zlib(void *dst, int dstlen, void *src, int srclen);
 int cramfs_uncompress_init(void);
 void cramfs_uncompress_exit(void);
 
+/* Uncompression interfaces to the underlying lzo */
+int cramfs_uncompress_block_lzo(void *dst, int dstlen, void *src, int srclen);
 #endif
diff -Naur linux-2.6.23/include/linux/cramfs_fs_sb.h 
linux-2.6.23_cramfs_lzo/include/linux/cramfs_fs_sb.h
--- linux-2.6.23/include/linux/cramfs_fs_sb.h   2007-10-09 13:31:38.000000000 
-0700
+++ linux-2.6.23_cramfs_lzo/include/linux/cramfs_fs_sb.h        2007-10-30 
17:17:19.000000000 -0700
@@ -10,6 +10,8 @@
                        unsigned long blocks;
                        unsigned long files;
                        unsigned long flags;
+                       /* function pointer to uncompress block */
+                       int (* cramfs_uncompress_block) (void *dst, int dstlen, 
void *src, int srclen);
 };
 
 static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb)


On Mon, 2007-10-29 at 11:45 -0700, vince kim wrote:
> Thanks for your comment.
> I can't hardly imagine there would be a lot of cases to mount two
> different images with different compression, but if they did, then they
> would not work at the same time.
> 
> For modular decompression, it would be out of my scope to modularize lzo
> or zlib. I will think about anyway.
> 
> I used Evolution to submit patch, and it word-wrapped the patch.
> 
> This must be clean.
> 
> diff -Naur linux-2.6.23/fs/cramfs/inode.c 
> linux-2.6.23_cramfs_lzo/fs/cramfs/inode.c
> --- linux-2.6.23/fs/cramfs/inode.c    2007-10-09 13:31:38.000000000 -0700
> +++ linux-2.6.23_cramfs_lzo/fs/cramfs/inode.c 2007-10-26 14:35:59.000000000 
> -0700
> @@ -31,6 +31,8 @@
>  static const struct inode_operations cramfs_dir_inode_operations;
>  static const struct file_operations cramfs_directory_operations;
>  static const struct address_space_operations cramfs_aops;
> +/* function pointer to uncompress block */
> +static int (* cramfs_uncompress_block) (void *dst, int dstlen, void *src, 
> int srclen);
>  
>  static DEFINE_MUTEX(read_mutex);
>  
> @@ -274,7 +276,17 @@
>               printk(KERN_ERR "cramfs: unsupported filesystem features\n");
>               goto out;
>       }
> -
> +     
> +     /* check flag to see if LZO compression is used */
> +     if (super.flags & CRAMFS_FLAG_LZO_COMPRESSION) {
> +             cramfs_uncompress_block = &cramfs_uncompress_block_lzo;
> +             printk("cramfs: LZO compression\n");
> +     }
> +     else {
> +             cramfs_uncompress_block = &cramfs_uncompress_block_zlib;
> +             printk("cramfs: ZLIB compression\n");
> +     }
> +     
>       /* Check that the root inode is in a sane state */
>       if (!S_ISDIR(super.root.mode)) {
>               printk(KERN_ERR "cramfs: root is not a directory\n");
> diff -Naur linux-2.6.23/fs/cramfs/uncompress.c 
> linux-2.6.23_cramfs_lzo/fs/cramfs/uncompress.c
> --- linux-2.6.23/fs/cramfs/uncompress.c       2007-10-09 13:31:38.000000000 
> -0700
> +++ linux-2.6.23_cramfs_lzo/fs/cramfs/uncompress.c    2007-10-26 
> 14:19:01.000000000 -0700
> @@ -20,12 +20,16 @@
>  #include <linux/vmalloc.h>
>  #include <linux/zlib.h>
>  #include <linux/cramfs_fs.h>
> +#include <linux/lzo.h>
>  
>  static z_stream stream;
>  static int initialized;
>  
> -/* Returns length of decompressed data. */
> -int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
> +/* 
> + * uncompress with ZLIB
> + * Returns length of decompressed data. 
> + */
> +int cramfs_uncompress_block_zlib(void *dst, int dstlen, void *src, int 
> srclen)
>  {
>       int err;
>  
> @@ -48,7 +52,26 @@
>       return stream.total_out;
>  
>  err:
> -     printk("Error %d while decompressing!\n", err);
> +     printk("ZLIB Error %d while decompressing!\n", err);
> +     printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
> +     return 0;
> +}
> +
> +/* 
> + * uncompress with LZO
> + * Returns length of decompressed data. 
> + */
> +int cramfs_uncompress_block_lzo(void *dst, int dstlen, void *src, int srclen)
> +{
> +     int err;
> +
> +     err = lzo1x_decompress_safe(src,srclen,dst,(unsigned int *)&dstlen);
> +        if (err != LZO_E_OK)
> +                goto err;
> +        return dstlen;
> +
> +err:
> +     printk("LZO Error %d while decompressing!\n", err);
>       printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
>       return 0;
>  }
> diff -Naur linux-2.6.23/fs/Kconfig linux-2.6.23_cramfs_lzo/fs/Kconfig
> --- linux-2.6.23/fs/Kconfig   2007-10-09 13:31:38.000000000 -0700
> +++ linux-2.6.23_cramfs_lzo/fs/Kconfig        2007-10-26 14:19:01.000000000 
> -0700
> @@ -1348,6 +1348,7 @@
>       tristate "Compressed ROM file system support (cramfs)"
>       depends on BLOCK
>       select ZLIB_INFLATE
> +     select LZO_DECOMPRESS
>       help
>         Saying Y here includes support for CramFs (Compressed ROM File
>         System).  CramFs is designed to be a simple, small, and compressed
> diff -Naur linux-2.6.23/include/linux/cramfs_fs.h 
> linux-2.6.23_cramfs_lzo/include/linux/cramfs_fs.h
> --- linux-2.6.23/include/linux/cramfs_fs.h    2007-10-09 13:31:38.000000000 
> -0700
> +++ linux-2.6.23_cramfs_lzo/include/linux/cramfs_fs.h 2007-10-26 
> 14:19:01.000000000 -0700
> @@ -73,6 +73,7 @@
>  #define CRAMFS_FLAG_HOLES            0x00000100      /* support for holes */
>  #define CRAMFS_FLAG_WRONG_SIGNATURE  0x00000200      /* reserved */
>  #define CRAMFS_FLAG_SHIFTED_ROOT_OFFSET      0x00000400      /* shifted root 
> fs */
> +#define CRAMFS_FLAG_LZO_COMPRESSION  0x00000800      /* LZO compression is 
> used */
>  
>  /*
>   * Valid values in super.flags.  Currently we refuse to mount
> @@ -82,11 +83,16 @@
>  #define CRAMFS_SUPPORTED_FLAGS       ( 0x000000ff \
>                               | CRAMFS_FLAG_HOLES \
>                               | CRAMFS_FLAG_WRONG_SIGNATURE \
> -                             | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
> +                             | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET \
> +                             | CRAMFS_FLAG_LZO_COMPRESSION )
> +
> +/* function pointer for uncompress function */
>  
>  /* Uncompression interfaces to the underlying zlib */
> -int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
> +int cramfs_uncompress_block_zlib(void *dst, int dstlen, void *src, int 
> srclen);
>  int cramfs_uncompress_init(void);
>  void cramfs_uncompress_exit(void);
>  
> +/* Uncompression interfaces to the underlying lzo */
> +int cramfs_uncompress_block_lzo(void *dst, int dstlen, void *src, int 
> srclen);
>  #endif
> 
> 
>   
> 
> On Sat, 2007-10-27 at 13:09 +0400, Michael Tokarev wrote:
> > vince kim wrote:
> > > This is a kernel patch to add support LZO compression in cramfs. 
> > []
> > > --- linux-2.6.23/fs/cramfs/inode.c      2007-10-09 13:31:38.000000000 
> > > -0700
> > > +++ linux-2.6.23_cramfs_lzo/fs/cramfs/inode.c    2007-10-26 
> > > 14:35:59.000000000 -0700
> > > @@ -31,6 +31,8 @@
> > >  static const struct inode_operations cramfs_dir_inode_operations;
> > >  static const struct file_operations cramfs_directory_operations;
> > >  static const struct address_space_operations cramfs_aops; 
> > > +/* function pointer to uncompress block */
> > > +static int (* cramfs_uncompress_block) (void *dst, int dstlen, void 
> > > *src, int srclen);
> > 
> > Shouldn't this pointer be mountpoint-specific?  I mean,
> > if I've two cramfs images, one using zlib and another
> > using lzo, the two will not work at the same time.
> > 
> > []
> > > --- linux-2.6.23/fs/Kconfig     2007-10-09 13:31:38.000000000 -0700
> > > +++ linux-2.6.23_cramfs_lzo/fs/Kconfig  2007-10-26 14:19:01.000000000 
> > > -0700
> > > @@ -1348,6 +1348,7 @@
> > >         tristate "Compressed ROM file system support (cramfs)" 
> > >         depends on BLOCK
> > >         select ZLIB_INFLATE
> > > +       select LZO_DECOMPRESS
> > >         help
> > >           Saying Y here includes support for CramFs (Compressed ROM File
> > >           System).  CramFs is designed to be a simple, small, and 
> > > compressed 
> > 
> > Hmm.  How about using modular decompressor? I mean,
> > it isn't really necessary for a given config to handle
> > both lzo- and zlib-compressed cramfs images, only one
> > may be needed, so the other compression library becomes
> > a useless dependency.  This is especially important for
> > embedded environments where memory/disk space is limited.
> > Since you're using a pointer-to-function anyway, it can
> > be done fully dynamically, by requesting a module to de-
> > compress the thing at runtime.  Pretty much like it's
> > done f.e. in crypto/ipsec layer currently.
> > 
> > By the way, your patch is word-wrapped.
> > 
> > /mjt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to