UBIFS: introduce compression mount options
Artem Bityutskiy [Sat, 1 Nov 2008 12:57:49 +0000 (14:57 +0200)]
It is very handy to be able to change default UBIFS compressor
via mount options. Introduce -o compr=<name> mount option support.
Currently only "none", "lzo" and "zlib" compressors are supported.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>

Documentation/filesystems/ubifs.txt
fs/ubifs/compress.c
fs/ubifs/sb.c
fs/ubifs/super.c
fs/ubifs/ubifs.h

index dd84ea3..2d0db54 100644 (file)
@@ -95,6 +95,9 @@ no_chk_data_crc               skip checking of CRCs on data nodes in order to
                        of this option is that corruption of the contents
                        of a file can go unnoticed.
 chk_data_crc (*)       do not skip checking CRCs on data nodes
+compr=none              override defoult comressor and set it to "none"
+compr=lzo               override defoult comressor and set it to "lzo"
+compr=zlib              override defoult comressor and set it to "zlib"
 
 
 Quick usage instructions
index 6414d50..4afb3ea 100644 (file)
@@ -33,7 +33,7 @@
 /* Fake description object for the "none" compressor */
 static struct ubifs_compressor none_compr = {
        .compr_type = UBIFS_COMPR_NONE,
-       .name = "no compression",
+       .name = "none",
        .capi_name = "",
 };
 
@@ -43,13 +43,13 @@ static DEFINE_MUTEX(lzo_mutex);
 static struct ubifs_compressor lzo_compr = {
        .compr_type = UBIFS_COMPR_LZO,
        .comp_mutex = &lzo_mutex,
-       .name = "LZO",
+       .name = "lzo",
        .capi_name = "lzo",
 };
 #else
 static struct ubifs_compressor lzo_compr = {
        .compr_type = UBIFS_COMPR_LZO,
-       .name = "LZO",
+       .name = "lzo",
 };
 #endif
 
index 0f39235..c5da201 100644 (file)
@@ -179,8 +179,11 @@ static int create_default_filesystem(struct ubifs_info *c)
        sup->fanout        = cpu_to_le32(DEFAULT_FANOUT);
        sup->lsave_cnt     = cpu_to_le32(c->lsave_cnt);
        sup->fmt_version   = cpu_to_le32(UBIFS_FORMAT_VERSION);
-       sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO);
        sup->time_gran     = cpu_to_le32(DEFAULT_TIME_GRAN);
+       if (c->mount_opts.override_compr)
+               sup->default_compr = cpu_to_le16(c->mount_opts.compr_type);
+       else
+               sup->default_compr = cpu_to_le16(UBIFS_COMPR_LZO);
 
        generate_random_uuid(sup->uuid);
 
@@ -582,16 +585,15 @@ int ubifs_read_superblock(struct ubifs_info *c)
        c->jhead_cnt     = le32_to_cpu(sup->jhead_cnt) + NONDATA_JHEADS_CNT;
        c->fanout        = le32_to_cpu(sup->fanout);
        c->lsave_cnt     = le32_to_cpu(sup->lsave_cnt);
-       c->default_compr = le16_to_cpu(sup->default_compr);
        c->rp_size       = le64_to_cpu(sup->rp_size);
        c->rp_uid        = le32_to_cpu(sup->rp_uid);
        c->rp_gid        = le32_to_cpu(sup->rp_gid);
        sup_flags        = le32_to_cpu(sup->flags);
+       if (!c->mount_opts.override_compr)
+               c->default_compr = le16_to_cpu(sup->default_compr);
 
        c->vfs_sb->s_time_gran = le32_to_cpu(sup->time_gran);
-
        memcpy(&c->uuid, &sup->uuid, 16);
-
        c->big_lpt = !!(sup_flags & UBIFS_FLG_BIGLPT);
 
        /* Automatically increase file system size to the maximum size */
index 21b4103..fc81022 100644 (file)
@@ -417,6 +417,11 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt)
        else if (c->mount_opts.chk_data_crc == 1)
                seq_printf(s, ",no_chk_data_crc");
 
+       if (c->mount_opts.override_compr) {
+               seq_printf(s, ",compr=");
+               seq_printf(s, ubifs_compr_name(c->mount_opts.compr_type));
+       }
+
        return 0;
 }
 
@@ -878,6 +883,7 @@ static int check_volume_empty(struct ubifs_info *c)
  * Opt_no_bulk_read: disable bulk-reads
  * Opt_chk_data_crc: check CRCs when reading data nodes
  * Opt_no_chk_data_crc: do not check CRCs when reading data nodes
+ * Opt_override_compr: override default compressor
  * Opt_err: just end of array marker
  */
 enum {
@@ -887,6 +893,7 @@ enum {
        Opt_no_bulk_read,
        Opt_chk_data_crc,
        Opt_no_chk_data_crc,
+       Opt_override_compr,
        Opt_err,
 };
 
@@ -897,6 +904,7 @@ static const match_table_t tokens = {
        {Opt_no_bulk_read, "no_bulk_read"},
        {Opt_chk_data_crc, "chk_data_crc"},
        {Opt_no_chk_data_crc, "no_chk_data_crc"},
+       {Opt_override_compr, "compr=%s"},
        {Opt_err, NULL},
 };
 
@@ -950,6 +958,28 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
                        c->mount_opts.chk_data_crc = 1;
                        c->no_chk_data_crc = 1;
                        break;
+               case Opt_override_compr:
+               {
+                       char *name = match_strdup(&args[0]);
+
+                       if (!name)
+                               return -ENOMEM;
+                       if (!strcmp(name, "none"))
+                               c->mount_opts.compr_type = UBIFS_COMPR_NONE;
+                       else if (!strcmp(name, "lzo"))
+                               c->mount_opts.compr_type = UBIFS_COMPR_LZO;
+                       else if (!strcmp(name, "zlib"))
+                               c->mount_opts.compr_type = UBIFS_COMPR_ZLIB;
+                       else {
+                               ubifs_err("unknown compressor \"%s\"", name);
+                               kfree(name);
+                               return -EINVAL;
+                       }
+                       kfree(name);
+                       c->mount_opts.override_compr = 1;
+                       c->default_compr = c->mount_opts.compr_type;
+                       break;
+               }
                default:
                        ubifs_err("unrecognized mount option \"%s\" "
                                  "or missing value", p);
@@ -1100,13 +1130,13 @@ static int mount_ubifs(struct ubifs_info *c)
                goto out_free;
 
        /*
-        * Make sure the compressor which is set as the default on in the
-        * superblock was actually compiled in.
+        * Make sure the compressor which is set as default in the superblock
+        * or overriden by mount options is actually compiled in.
         */
        if (!ubifs_compr_present(c->default_compr)) {
-               ubifs_warn("'%s' compressor is set by superblock, but not "
-                          "compiled in", ubifs_compr_name(c->default_compr));
-               c->default_compr = UBIFS_COMPR_NONE;
+               ubifs_err("'compressor \"%s\" is not compiled in",
+                         ubifs_compr_name(c->default_compr));
+               goto out_free;
        }
 
        dbg_failure_mode_registration(c);
@@ -2023,8 +2053,8 @@ static int __init ubifs_init(void)
        /*
         * We use 2 bit wide bit-fields to store compression type, which should
         * be amended if more compressors are added. The bit-fields are:
-        * @compr_type in 'struct ubifs_inode' and @default_compr in
-        * 'struct ubifs_info'.
+        * @compr_type in 'struct ubifs_inode', @default_compr in
+        * 'struct ubifs_info' and @compr_type in 'struct ubifs_mount_opts'.
         */
        BUILD_BUG_ON(UBIFS_COMPR_TYPES_CNT > 4);
 
index 4d76aba..16840e0 100644 (file)
@@ -893,13 +893,21 @@ struct ubifs_orphan {
 /**
  * struct ubifs_mount_opts - UBIFS-specific mount options information.
  * @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast)
- * @bulk_read: enable bulk-reads
- * @chk_data_crc: check CRCs when reading data nodes
+ * @bulk_read: enable/disable bulk-reads (%0 default, %1 disabe, %2 enable)
+ * @chk_data_crc: enable/disable CRC data checking when reading data nodes
+ *                (%0 default, %1 disabe, %2 enable)
+ * @override_compr: override default compressor (%0 - do not override and use
+ *                  superblock compressor, %1 - override and use compressor
+ *                  specified in @compr_type)
+ * @compr_type: compressor type to override the superblock compressor with
+ *              (%UBIFS_COMPR_NONE, etc)
  */
 struct ubifs_mount_opts {
        unsigned int unmount_mode:2;
        unsigned int bulk_read:2;
        unsigned int chk_data_crc:2;
+       unsigned int override_compr:1;
+       unsigned int compr_type:2;
 };
 
 /**