JFS: Free sbi memory in error path
[safe/jmp/linux-2.6] / fs / ubifs / super.c
index 7562464..4d2f215 100644 (file)
 #include <linux/parser.h>
 #include <linux/seq_file.h>
 #include <linux/mount.h>
+#include <linux/math64.h>
+#include <linux/writeback.h>
 #include "ubifs.h"
 
+/*
+ * Maximum amount of memory we may 'kmalloc()' without worrying that we are
+ * allocating too much.
+ */
+#define UBIFS_KMALLOC_OK (128*1024)
+
 /* Slab cache for UBIFS inodes */
 struct kmem_cache *ubifs_inode_slab;
 
@@ -275,7 +283,7 @@ static void ubifs_destroy_inode(struct inode *inode)
 /*
  * Note, Linux write-back code calls this without 'i_mutex'.
  */
-static int ubifs_write_inode(struct inode *inode, int wait)
+static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
 {
        int err = 0;
        struct ubifs_info *c = inode->i_sb->s_fs_info;
@@ -309,6 +317,8 @@ static int ubifs_write_inode(struct inode *inode, int wait)
                if (err)
                        ubifs_err("can't write inode %lu, error %d",
                                  inode->i_ino, err);
+               else
+                       err = dbg_check_inode_size(c, inode, ui->ui_size);
        }
 
        ui->dirty = 0;
@@ -352,6 +362,11 @@ static void ubifs_delete_inode(struct inode *inode)
 out:
        if (ui->dirty)
                ubifs_release_dirty_inode_budget(c, ui);
+       else {
+               /* We've deleted something - clean the "no space" flags */
+               c->nospace = c->nospace_rp = 0;
+               smp_wmb();
+       }
        clear_inode(inode);
 }
 
@@ -389,6 +404,7 @@ static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_namelen = UBIFS_MAX_NLEN;
        buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]);
        buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]);
+       ubifs_assert(buf->f_bfree <= c->block_cnt);
        return 0;
 }
 
@@ -401,26 +417,59 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt)
        else if (c->mount_opts.unmount_mode == 1)
                seq_printf(s, ",norm_unmount");
 
+       if (c->mount_opts.bulk_read == 2)
+               seq_printf(s, ",bulk_read");
+       else if (c->mount_opts.bulk_read == 1)
+               seq_printf(s, ",no_bulk_read");
+
+       if (c->mount_opts.chk_data_crc == 2)
+               seq_printf(s, ",chk_data_crc");
+       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=%s",
+                          ubifs_compr_name(c->mount_opts.compr_type));
+       }
+
        return 0;
 }
 
 static int ubifs_sync_fs(struct super_block *sb, int wait)
 {
+       int i, err;
        struct ubifs_info *c = sb->s_fs_info;
-       int i, ret = 0, err;
 
-       if (c->jheads)
-               for (i = 0; i < c->jhead_cnt; i++) {
-                       err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
-                       if (err && !ret)
-                               ret = err;
-               }
        /*
-        * We ought to call sync for c->ubi but it does not have one. If it had
-        * it would in turn call mtd->sync, however mtd operations are
-        * synchronous anyway, so we don't lose any sleep here.
+        * Zero @wait is just an advisory thing to help the file system shove
+        * lots of data into the queues, and there will be the second
+        * '->sync_fs()' call, with non-zero @wait.
         */
-       return ret;
+       if (!wait)
+               return 0;
+
+       /*
+        * Synchronize write buffers, because 'ubifs_run_commit()' does not
+        * do this if it waits for an already running commit.
+        */
+       for (i = 0; i < c->jhead_cnt; i++) {
+               err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
+               if (err)
+                       return err;
+       }
+
+       /*
+        * Strictly speaking, it is not necessary to commit the journal here,
+        * synchronizing write-buffers would be enough. But committing makes
+        * UBIFS free space predictions much more accurate, so we want to let
+        * the user be able to get more accurate results of 'statfs()' after
+        * they synchronize the file system.
+        */
+       err = ubifs_run_commit(c);
+       if (err)
+               return err;
+
+       return ubi_sync(c->vi.ubi_num);
 }
 
 /**
@@ -519,15 +568,8 @@ static int init_constants_early(struct ubifs_info *c)
        c->ranges[UBIFS_IDX_NODE].max_len = INT_MAX;
 
        /*
-        * Initialize dead and dark LEB space watermarks.
-        *
-        * Dead space is the space which cannot be used. Its watermark is
-        * equivalent to min. I/O unit or minimum node size if it is greater
-        * then min. I/O unit.
-        *
-        * Dark space is the space which might be used, or might not, depending
-        * on which node should be written to the LEB. Its watermark is
-        * equivalent to maximum UBIFS node size.
+        * Initialize dead and dark LEB space watermarks. See gc.c for comments
+        * about these values.
         */
        c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size);
        c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size);
@@ -538,6 +580,11 @@ static int init_constants_early(struct ubifs_info *c)
         * calculations when reporting free space.
         */
        c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ;
+
+       /* Buffer size for bulk-reads */
+       c->max_bu_buf_len = UBIFS_MAX_BULK_READ * UBIFS_MAX_DATA_NODE_SZ;
+       if (c->max_bu_buf_len > c->leb_size)
+               c->max_bu_buf_len = c->leb_size;
        return 0;
 }
 
@@ -562,7 +609,7 @@ static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad)
 }
 
 /*
- * init_constants_late - initialize UBIFS constants.
+ * init_constants_sb - initialize UBIFS constants.
  * @c: UBIFS file-system description object
  *
  * This is a helper function which initializes various UBIFS constants after
@@ -570,10 +617,10 @@ static int bud_wbuf_callback(struct ubifs_info *c, int lnum, int free, int pad)
  * makes sure they are all right. Returns zero in case of success and a
  * negative error code in case of failure.
  */
-static int init_constants_late(struct ubifs_info *c)
+static int init_constants_sb(struct ubifs_info *c)
 {
        int tmp, err;
-       uint64_t tmp64;
+       long long tmp64;
 
        c->main_bytes = (long long)c->main_lebs * c->leb_size;
        c->max_znode_sz = sizeof(struct ubifs_znode) +
@@ -600,9 +647,8 @@ static int init_constants_late(struct ubifs_info *c)
         * Make sure that the log is large enough to fit reference nodes for
         * all buds plus one reserved LEB.
         */
-       tmp64 = c->max_bud_bytes;
-       tmp = do_div(tmp64, c->leb_size);
-       c->max_bud_cnt = tmp64 + !!tmp;
+       tmp64 = c->max_bud_bytes + c->leb_size - 1;
+       c->max_bud_cnt = div_u64(tmp64, c->leb_size);
        tmp = (c->ref_node_alsz * c->max_bud_cnt + c->leb_size - 1);
        tmp /= c->leb_size;
        tmp += 1;
@@ -638,7 +684,7 @@ static int init_constants_late(struct ubifs_info *c)
         * Consequently, if the journal is too small, UBIFS will treat it as
         * always full.
         */
-       tmp64 = (uint64_t)(c->jhead_cnt + 1) * c->leb_size + 1;
+       tmp64 = (long long)(c->jhead_cnt + 1) * c->leb_size + 1;
        if (c->bg_bud_bytes < tmp64)
                c->bg_bud_bytes = tmp64;
        if (c->max_bud_bytes < tmp64 + c->leb_size)
@@ -648,7 +694,25 @@ static int init_constants_late(struct ubifs_info *c)
        if (err)
                return err;
 
+       /* Initialize effective LEB size used in budgeting calculations */
+       c->idx_leb_size = c->leb_size - c->max_idx_node_sz;
+       return 0;
+}
+
+/*
+ * init_constants_master - initialize UBIFS constants.
+ * @c: UBIFS file-system description object
+ *
+ * This is a helper function which initializes various UBIFS constants after
+ * the master node has been read. It also checks various UBIFS parameters and
+ * makes sure they are all right.
+ */
+static void init_constants_master(struct ubifs_info *c)
+{
+       long long tmp64;
+
        c->min_idx_lebs = ubifs_calc_min_idx_lebs(c);
+       c->report_rp_size = ubifs_reported_space(c, c->rp_size);
 
        /*
         * Calculate total amount of FS blocks. This number is not used
@@ -656,26 +720,25 @@ static int init_constants_late(struct ubifs_info *c)
         * necessary to report something for the 'statfs()' call.
         *
         * Subtract the LEB reserved for GC, the LEB which is reserved for
-        * deletions, and assume only one journal head is available.
+        * deletions, minimum LEBs for the index, and assume only one journal
+        * head is available.
         */
-       tmp64 = c->main_lebs - 2 - c->jhead_cnt + 1;
-       tmp64 *= (uint64_t)c->leb_size - c->leb_overhead;
+       tmp64 = c->main_lebs - 1 - 1 - MIN_INDEX_LEBS - c->jhead_cnt + 1;
+       tmp64 *= (long long)c->leb_size - c->leb_overhead;
        tmp64 = ubifs_reported_space(c, tmp64);
        c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT;
-
-       return 0;
 }
 
 /**
  * take_gc_lnum - reserve GC LEB.
  * @c: UBIFS file-system description object
  *
- * This function ensures that the LEB reserved for garbage collection is
- * unmapped and is marked as "taken" in lprops. We also have to set free space
- * to LEB size and dirty space to zero, because lprops may contain out-of-date
- * information if the file-system was un-mounted before it has been committed.
- * This function returns zero in case of success and a negative error code in
- * case of failure.
+ * This function ensures that the LEB reserved for garbage collection is marked
+ * as "taken" in lprops. We also have to set free space to LEB size and dirty
+ * space to zero, because lprops may contain out-of-date information if the
+ * file-system was un-mounted before it has been committed. This function
+ * returns zero in case of success and a negative error code in case of
+ * failure.
  */
 static int take_gc_lnum(struct ubifs_info *c)
 {
@@ -686,10 +749,6 @@ static int take_gc_lnum(struct ubifs_info *c)
                return -EINVAL;
        }
 
-       err = ubifs_leb_unmap(c, c->gc_lnum);
-       if (err)
-               return err;
-
        /* And we have to tell lprops that this LEB is taken */
        err = ubifs_change_one_lp(c, c->gc_lnum, c->leb_size, 0,
                                  LPROPS_TAKEN, 0, 0);
@@ -729,7 +788,7 @@ static int alloc_wbufs(struct ubifs_info *c)
         * does not need to be synchronized by timer.
         */
        c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM;
-       c->jheads[GCHD].wbuf.timeout = 0;
+       c->jheads[GCHD].wbuf.no_timer = 1;
 
        return 0;
 }
@@ -840,21 +899,57 @@ static int check_volume_empty(struct ubifs_info *c)
  *
  * Opt_fast_unmount: do not run a journal commit before un-mounting
  * Opt_norm_unmount: run a journal commit before un-mounting
+ * Opt_bulk_read: enable bulk-reads
+ * 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 {
        Opt_fast_unmount,
        Opt_norm_unmount,
+       Opt_bulk_read,
+       Opt_no_bulk_read,
+       Opt_chk_data_crc,
+       Opt_no_chk_data_crc,
+       Opt_override_compr,
        Opt_err,
 };
 
-static match_table_t tokens = {
+static const match_table_t tokens = {
        {Opt_fast_unmount, "fast_unmount"},
        {Opt_norm_unmount, "norm_unmount"},
+       {Opt_bulk_read, "bulk_read"},
+       {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},
 };
 
 /**
+ * parse_standard_option - parse a standard mount option.
+ * @option: the option to parse
+ *
+ * Normally, standard mount options like "sync" are passed to file-systems as
+ * flags. However, when a "rootflags=" kernel boot parameter is used, they may
+ * be present in the options string. This function tries to deal with this
+ * situation and parse standard options. Returns 0 if the option was not
+ * recognized, and the corresponding integer flag if it was.
+ *
+ * UBIFS is only interested in the "sync" option, so do not check for anything
+ * else.
+ */
+static int parse_standard_option(const char *option)
+{
+       ubifs_msg("parse %s", option);
+       if (!strcmp(option, "sync"))
+               return MS_SYNCHRONOUS;
+       return 0;
+}
+
+/**
  * ubifs_parse_options - parse mount parameters.
  * @c: UBIFS file-system description object
  * @options: parameters to parse
@@ -880,18 +975,69 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
 
                token = match_token(p, tokens, args);
                switch (token) {
+               /*
+                * %Opt_fast_unmount and %Opt_norm_unmount options are ignored.
+                * We accept them in order to be backward-compatible. But this
+                * should be removed at some point.
+                */
                case Opt_fast_unmount:
                        c->mount_opts.unmount_mode = 2;
-                       c->fast_unmount = 1;
                        break;
                case Opt_norm_unmount:
                        c->mount_opts.unmount_mode = 1;
-                       c->fast_unmount = 0;
                        break;
+               case Opt_bulk_read:
+                       c->mount_opts.bulk_read = 2;
+                       c->bulk_read = 1;
+                       break;
+               case Opt_no_bulk_read:
+                       c->mount_opts.bulk_read = 1;
+                       c->bulk_read = 0;
+                       break;
+               case Opt_chk_data_crc:
+                       c->mount_opts.chk_data_crc = 2;
+                       c->no_chk_data_crc = 0;
+                       break;
+               case Opt_no_chk_data_crc:
+                       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);
-                       return -EINVAL;
+               {
+                       unsigned long flag;
+                       struct super_block *sb = c->vfs_sb;
+
+                       flag = parse_standard_option(p);
+                       if (!flag) {
+                               ubifs_err("unrecognized mount option \"%s\" "
+                                         "or missing value", p);
+                               return -EINVAL;
+                       }
+                       sb->s_flags |= flag;
+                       break;
+               }
                }
        }
 
@@ -929,6 +1075,53 @@ static void destroy_journal(struct ubifs_info *c)
 }
 
 /**
+ * bu_init - initialize bulk-read information.
+ * @c: UBIFS file-system description object
+ */
+static void bu_init(struct ubifs_info *c)
+{
+       ubifs_assert(c->bulk_read == 1);
+
+       if (c->bu.buf)
+               return; /* Already initialized */
+
+again:
+       c->bu.buf = kmalloc(c->max_bu_buf_len, GFP_KERNEL | __GFP_NOWARN);
+       if (!c->bu.buf) {
+               if (c->max_bu_buf_len > UBIFS_KMALLOC_OK) {
+                       c->max_bu_buf_len = UBIFS_KMALLOC_OK;
+                       goto again;
+               }
+
+               /* Just disable bulk-read */
+               ubifs_warn("Cannot allocate %d bytes of memory for bulk-read, "
+                          "disabling it", c->max_bu_buf_len);
+               c->mount_opts.bulk_read = 1;
+               c->bulk_read = 0;
+               return;
+       }
+}
+
+/**
+ * check_free_space - check if there is enough free space to mount.
+ * @c: UBIFS file-system description object
+ *
+ * This function makes sure UBIFS has enough free space to be mounted in
+ * read/write mode. UBIFS must always have some free space to allow deletions.
+ */
+static int check_free_space(struct ubifs_info *c)
+{
+       ubifs_assert(c->dark_wm > 0);
+       if (c->lst.total_free + c->lst.total_dirty < c->dark_wm) {
+               ubifs_err("insufficient free space to mount in read/write mode");
+               dbg_dump_budg(c);
+               dbg_dump_lprops(c);
+               return -ENOSPC;
+       }
+       return 0;
+}
+
+/**
  * mount_ubifs - mount UBIFS file-system.
  * @c: UBIFS file-system description object
  *
@@ -949,11 +1142,9 @@ static int mount_ubifs(struct ubifs_info *c)
        if (err)
                return err;
 
-#ifdef CONFIG_UBIFS_FS_DEBUG
-       c->dbg_buf = vmalloc(c->leb_size);
-       if (!c->dbg_buf)
-               return -ENOMEM;
-#endif
+       err = ubifs_debugging_init(c);
+       if (err)
+               return err;
 
        err = check_volume_empty(c);
        if (err)
@@ -996,45 +1187,50 @@ static int mount_ubifs(struct ubifs_info *c)
                        goto out_free;
        }
 
+       if (c->bulk_read == 1)
+               bu_init(c);
+
+       /*
+        * We have to check all CRCs, even for data nodes, when we mount the FS
+        * (specifically, when we are replaying).
+        */
+       c->always_chk_crc = 1;
+
        err = ubifs_read_superblock(c);
        if (err)
                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 overridden 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));
+               err = -ENOTSUPP;
+               goto out_free;
        }
 
-       dbg_failure_mode_registration(c);
-
-       err = init_constants_late(c);
+       err = init_constants_sb(c);
        if (err)
-               goto out_dereg;
+               goto out_free;
 
        sz = ALIGN(c->max_idx_node_sz, c->min_io_size);
        sz = ALIGN(sz + c->max_idx_node_sz, c->min_io_size);
        c->cbuf = kmalloc(sz, GFP_NOFS);
        if (!c->cbuf) {
                err = -ENOMEM;
-               goto out_dereg;
+               goto out_free;
        }
 
+       sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id);
        if (!mounted_read_only) {
                err = alloc_wbufs(c);
                if (err)
                        goto out_cbuf;
 
                /* Create background thread */
-               sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num,
-                       c->vi.vol_id);
-               c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
-               if (!c->bgt)
-                       c->bgt = ERR_PTR(-EINVAL);
+               c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name);
                if (IS_ERR(c->bgt)) {
                        err = PTR_ERR(c->bgt);
                        c->bgt = NULL;
@@ -1049,6 +1245,8 @@ static int mount_ubifs(struct ubifs_info *c)
        if (err)
                goto out_master;
 
+       init_constants_master(c);
+
        if ((c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY)) != 0) {
                ubifs_msg("recovery needed");
                c->need_recovery = 1;
@@ -1080,6 +1278,9 @@ static int mount_ubifs(struct ubifs_info *c)
        if (err)
                goto out_journal;
 
+       /* Calculate 'min_idx_lebs' after journal replay */
+       c->min_idx_lebs = ubifs_calc_min_idx_lebs(c);
+
        err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only);
        if (err)
                goto out_orphans;
@@ -1087,12 +1288,9 @@ static int mount_ubifs(struct ubifs_info *c)
        if (!mounted_read_only) {
                int lnum;
 
-               /* Check for enough free space */
-               if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) {
-                       ubifs_err("insufficient available space");
-                       err = -EINVAL;
+               err = check_free_space(c);
+               if (err)
                        goto out_orphans;
-               }
 
                /* Check for enough log space */
                lnum = c->lhead_lnum + 1;
@@ -1109,10 +1307,19 @@ static int mount_ubifs(struct ubifs_info *c)
                        if (err)
                                goto out_orphans;
                        err = ubifs_rcvry_gc_commit(c);
-               } else
+               } else {
                        err = take_gc_lnum(c);
-               if (err)
-                       goto out_orphans;
+                       if (err)
+                               goto out_orphans;
+
+                       /*
+                        * GC LEB may contain garbage if there was an unclean
+                        * reboot, and it should be un-mapped.
+                        */
+                       err = ubifs_leb_unmap(c, c->gc_lnum);
+                       if (err)
+                               return err;
+               }
 
                err = dbg_check_lprops(c);
                if (err)
@@ -1121,6 +1328,16 @@ static int mount_ubifs(struct ubifs_info *c)
                err = ubifs_recover_size(c);
                if (err)
                        goto out_orphans;
+       } else {
+               /*
+                * Even if we mount read-only, we have to set space in GC LEB
+                * to proper value because this affects UBIFS free space
+                * reporting. We do not want to have a situation when
+                * re-mounting from R/O to R/W changes amount of free space.
+                */
+               err = take_gc_lnum(c);
+               if (err)
+                       goto out_orphans;
        }
 
        spin_lock(&ubifs_infos_lock);
@@ -1133,40 +1350,50 @@ static int mount_ubifs(struct ubifs_info *c)
                else {
                        c->need_recovery = 0;
                        ubifs_msg("recovery completed");
+                       /*
+                        * GC LEB has to be empty and taken at this point. But
+                        * the journal head LEBs may also be accounted as
+                        * "empty taken" if they are empty.
+                        */
+                       ubifs_assert(c->lst.taken_empty_lebs > 0);
                }
-       }
+       } else
+               ubifs_assert(c->lst.taken_empty_lebs > 0);
 
        err = dbg_check_filesystem(c);
        if (err)
                goto out_infos;
 
+       err = dbg_debugfs_init_fs(c);
+       if (err)
+               goto out_infos;
+
+       c->always_chk_crc = 0;
+
        ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"",
                  c->vi.ubi_num, c->vi.vol_id, c->vi.name);
        if (mounted_read_only)
                ubifs_msg("mounted read-only");
        x = (long long)c->main_lebs * c->leb_size;
-       ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)",
-                 x, x >> 10, x >> 20, c->main_lebs);
+       ubifs_msg("file system size:   %lld bytes (%lld KiB, %lld MiB, %d "
+                 "LEBs)", x, x >> 10, x >> 20, c->main_lebs);
        x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes;
-       ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)",
-                 x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt);
+       ubifs_msg("journal size:       %lld bytes (%lld KiB, %lld MiB, %d "
+                 "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt);
+       ubifs_msg("media format:       w%d/r%d (latest is w%d/r%d)",
+                 c->fmt_version, c->ro_compat_version,
+                 UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION);
        ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr));
-       ubifs_msg("media format %d, latest format %d",
-                 c->fmt_version, UBIFS_FORMAT_VERSION);
+       ubifs_msg("reserved for root:  %llu bytes (%llu KiB)",
+               c->report_rp_size, c->report_rp_size >> 10);
 
        dbg_msg("compiled on:         " __DATE__ " at " __TIME__);
        dbg_msg("min. I/O unit size:  %d bytes", c->min_io_size);
        dbg_msg("LEB size:            %d bytes (%d KiB)",
-               c->leb_size, c->leb_size / 1024);
+               c->leb_size, c->leb_size >> 10);
        dbg_msg("data journal heads:  %d",
                c->jhead_cnt - NONDATA_JHEADS_CNT);
-       dbg_msg("UUID:                %02X%02X%02X%02X-%02X%02X"
-              "-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
-              c->uuid[0], c->uuid[1], c->uuid[2], c->uuid[3],
-              c->uuid[4], c->uuid[5], c->uuid[6], c->uuid[7],
-              c->uuid[8], c->uuid[9], c->uuid[10], c->uuid[11],
-              c->uuid[12], c->uuid[13], c->uuid[14], c->uuid[15]);
-       dbg_msg("fast unmount:        %d", c->fast_unmount);
+       dbg_msg("UUID:                %pUB", c->uuid);
        dbg_msg("big_lpt              %d", c->big_lpt);
        dbg_msg("log LEBs:            %d (%d - %d)",
                c->log_lebs, UBIFS_LOG_LNUM, c->log_last);
@@ -1183,8 +1410,20 @@ static int mount_ubifs(struct ubifs_info *c)
        dbg_msg("tree fanout:         %d", c->fanout);
        dbg_msg("reserved GC LEB:     %d", c->gc_lnum);
        dbg_msg("first main LEB:      %d", c->main_first);
+       dbg_msg("max. znode size      %d", c->max_znode_sz);
+       dbg_msg("max. index node size %d", c->max_idx_node_sz);
+       dbg_msg("node sizes:          data %zu, inode %zu, dentry %zu",
+               UBIFS_DATA_NODE_SZ, UBIFS_INO_NODE_SZ, UBIFS_DENT_NODE_SZ);
+       dbg_msg("node sizes:          trun %zu, sb %zu, master %zu",
+               UBIFS_TRUN_NODE_SZ, UBIFS_SB_NODE_SZ, UBIFS_MST_NODE_SZ);
+       dbg_msg("node sizes:          ref %zu, cmt. start %zu, orph %zu",
+               UBIFS_REF_NODE_SZ, UBIFS_CS_NODE_SZ, UBIFS_ORPH_NODE_SZ);
+       dbg_msg("max. node sizes:     data %zu, inode %zu dentry %zu",
+               UBIFS_MAX_DATA_NODE_SZ, UBIFS_MAX_INO_NODE_SZ,
+               UBIFS_MAX_DENT_NODE_SZ);
        dbg_msg("dead watermark:      %d", c->dead_wm);
        dbg_msg("dark watermark:      %d", c->dark_wm);
+       dbg_msg("LEB overhead:        %d", c->leb_overhead);
        x = (long long)c->main_lebs * c->dark_wm;
        dbg_msg("max. dark space:     %lld (%lld KiB, %lld MiB)",
                x, x >> 10, x >> 20);
@@ -1220,13 +1459,12 @@ out_wbufs:
        free_wbufs(c);
 out_cbuf:
        kfree(c->cbuf);
-out_dereg:
-       dbg_failure_mode_deregistration(c);
 out_free:
+       kfree(c->bu.buf);
        vfree(c->ileb_buf);
        vfree(c->sbuf);
        kfree(c->bottom_up_buf);
-       UBIFS_DBG(vfree(c->dbg_buf));
+       ubifs_debugging_exit(c);
        return err;
 }
 
@@ -1244,6 +1482,7 @@ static void ubifs_umount(struct ubifs_info *c)
        dbg_gen("un-mounting UBI device %d, volume %d", c->vi.ubi_num,
                c->vi.vol_id);
 
+       dbg_debugfs_exit_fs(c);
        spin_lock(&ubifs_infos_lock);
        list_del(&c->infos_list);
        spin_unlock(&ubifs_infos_lock);
@@ -1259,11 +1498,11 @@ static void ubifs_umount(struct ubifs_info *c)
        kfree(c->cbuf);
        kfree(c->rcvrd_mst_node);
        kfree(c->mst_node);
+       kfree(c->bu.buf);
+       vfree(c->ileb_buf);
        vfree(c->sbuf);
        kfree(c->bottom_up_buf);
-       UBIFS_DBG(vfree(c->dbg_buf));
-       vfree(c->ileb_buf);
-       dbg_failure_mode_deregistration(c);
+       ubifs_debugging_exit(c);
 }
 
 /**
@@ -1278,18 +1517,23 @@ static int ubifs_remount_rw(struct ubifs_info *c)
 {
        int err, lnum;
 
-       if (c->ro_media)
-               return -EINVAL;
+       if (c->rw_incompat) {
+               ubifs_err("the file-system is not R/W-compatible");
+               ubifs_msg("on-flash format version is w%d/r%d, but software "
+                         "only supports up to version w%d/r%d", c->fmt_version,
+                         c->ro_compat_version, UBIFS_FORMAT_VERSION,
+                         UBIFS_RO_COMPAT_VERSION);
+               return -EROFS;
+       }
 
        mutex_lock(&c->umount_mutex);
+       dbg_save_space_info(c);
        c->remounting_rw = 1;
+       c->always_chk_crc = 1;
 
-       /* Check for enough free space */
-       if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) {
-               ubifs_err("insufficient available space");
-               err = -EINVAL;
+       err = check_free_space(c);
+       if (err)
                goto out;
-       }
 
        if (c->old_leb_cnt != c->leb_cnt) {
                struct ubifs_sb_node *sup;
@@ -1319,6 +1563,12 @@ static int ubifs_remount_rw(struct ubifs_info *c)
                err = ubifs_recover_inl_heads(c, c->sbuf);
                if (err)
                        goto out;
+       } else {
+               /* A readonly mount is not allowed to have orphans */
+               ubifs_assert(c->tot_orphans == 0);
+               err = ubifs_clear_orphans(c);
+               if (err)
+                       goto out;
        }
 
        if (!(c->mst_node->flags & cpu_to_le32(UBIFS_MST_DIRTY))) {
@@ -1345,21 +1595,21 @@ static int ubifs_remount_rw(struct ubifs_info *c)
        ubifs_create_buds_lists(c);
 
        /* Create background thread */
-       c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
-       if (!c->bgt)
-               c->bgt = ERR_PTR(-EINVAL);
+       c->bgt = kthread_create(ubifs_bg_thread, c, "%s", c->bgt_name);
        if (IS_ERR(c->bgt)) {
                err = PTR_ERR(c->bgt);
                c->bgt = NULL;
                ubifs_err("cannot spawn \"%s\", error %d",
                          c->bgt_name, err);
-               return err;
+               goto out;
        }
        wake_up_process(c->bgt);
 
        c->orph_buf = vmalloc(c->leb_size);
-       if (!c->orph_buf)
-               return -ENOMEM;
+       if (!c->orph_buf) {
+               err = -ENOMEM;
+               goto out;
+       }
 
        /* Check for enough log space */
        lnum = c->lhead_lnum + 1;
@@ -1374,7 +1624,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
        if (c->need_recovery)
                err = ubifs_rcvry_gc_commit(c);
        else
-               err = take_gc_lnum(c);
+               err = ubifs_leb_unmap(c, c->gc_lnum);
        if (err)
                goto out;
 
@@ -1386,8 +1636,10 @@ static int ubifs_remount_rw(struct ubifs_info *c)
        dbg_gen("re-mounted read-write");
        c->vfs_sb->s_flags &= ~MS_RDONLY;
        c->remounting_rw = 0;
+       c->always_chk_crc = 0;
+       err = dbg_check_space_info(c);
        mutex_unlock(&c->umount_mutex);
-       return 0;
+       return err;
 
 out:
        vfree(c->orph_buf);
@@ -1401,47 +1653,24 @@ out:
        c->ileb_buf = NULL;
        ubifs_lpt_free(c, 1);
        c->remounting_rw = 0;
+       c->always_chk_crc = 0;
        mutex_unlock(&c->umount_mutex);
        return err;
 }
 
 /**
- * commit_on_unmount - commit the journal when un-mounting.
- * @c: UBIFS file-system description object
- *
- * This function is called during un-mounting and it commits the journal unless
- * the "fast unmount" mode is enabled. It also avoids committing the journal if
- * it contains too few data.
- *
- * Sometimes recovery requires the journal to be committed at least once, and
- * this function takes care about this.
- */
-static void commit_on_unmount(struct ubifs_info *c)
-{
-       if (!c->fast_unmount) {
-               long long bud_bytes;
-
-               spin_lock(&c->buds_lock);
-               bud_bytes = c->bud_bytes;
-               spin_unlock(&c->buds_lock);
-               if (bud_bytes > c->leb_size)
-                       ubifs_run_commit(c);
-       }
-}
-
-/**
  * ubifs_remount_ro - re-mount in read-only mode.
  * @c: UBIFS file-system description object
  *
- * We rely on VFS to have stopped writing. Possibly the background thread could
- * be running a commit, however kthread_stop will wait in that case.
+ * We assume VFS has stopped writing. Possibly the background thread could be
+ * running a commit, however kthread_stop will wait in that case.
  */
 static void ubifs_remount_ro(struct ubifs_info *c)
 {
        int i, err;
 
        ubifs_assert(!c->need_recovery);
-       commit_on_unmount(c);
+       ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY));
 
        mutex_lock(&c->umount_mutex);
        if (c->bgt) {
@@ -1449,27 +1678,29 @@ static void ubifs_remount_ro(struct ubifs_info *c)
                c->bgt = NULL;
        }
 
+       dbg_save_space_info(c);
+
        for (i = 0; i < c->jhead_cnt; i++) {
                ubifs_wbuf_sync(&c->jheads[i].wbuf);
-               del_timer_sync(&c->jheads[i].wbuf.timer);
+               hrtimer_cancel(&c->jheads[i].wbuf.timer);
        }
 
-       if (!c->ro_media) {
-               c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
-               c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
-               c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum);
-               err = ubifs_write_master(c);
-               if (err)
-                       ubifs_ro_mode(c, err);
-       }
+       c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY);
+       c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS);
+       c->mst_node->gc_lnum = cpu_to_le32(c->gc_lnum);
+       err = ubifs_write_master(c);
+       if (err)
+               ubifs_ro_mode(c, err);
 
-       ubifs_destroy_idx_gc(c);
        free_wbufs(c);
        vfree(c->orph_buf);
        c->orph_buf = NULL;
        vfree(c->ileb_buf);
        c->ileb_buf = NULL;
        ubifs_lpt_free(c, 1);
+       err = dbg_check_space_info(c);
+       if (err)
+               ubifs_ro_mode(c, err);
        mutex_unlock(&c->umount_mutex);
 }
 
@@ -1480,6 +1711,7 @@ static void ubifs_put_super(struct super_block *sb)
 
        ubifs_msg("un-mount UBI device %d, volume %d", c->vi.ubi_num,
                  c->vi.vol_id);
+
        /*
         * The following asserts are only valid if there has not been a failure
         * of the media. For example, there will be dirty inodes if we failed
@@ -1509,10 +1741,8 @@ static void ubifs_put_super(struct super_block *sb)
 
                /* Synchronize write-buffers */
                if (c->jheads)
-                       for (i = 0; i < c->jhead_cnt; i++) {
+                       for (i = 0; i < c->jhead_cnt; i++)
                                ubifs_wbuf_sync(&c->jheads[i].wbuf);
-                               del_timer_sync(&c->jheads[i].wbuf.timer);
-                       }
 
                /*
                 * On fatal errors c->ro_media is set to 1, in which case we do
@@ -1560,17 +1790,36 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
                ubifs_err("invalid or unknown remount parameter");
                return err;
        }
+
        if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
+               if (c->ro_media) {
+                       ubifs_msg("cannot re-mount due to prior errors");
+                       return -EROFS;
+               }
                err = ubifs_remount_rw(c);
                if (err)
                        return err;
-       } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY))
+       } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
+               if (c->ro_media) {
+                       ubifs_msg("cannot re-mount due to prior errors");
+                       return -EROFS;
+               }
                ubifs_remount_ro(c);
+       }
 
+       if (c->bulk_read == 1)
+               bu_init(c);
+       else {
+               dbg_gen("disable bulk-read");
+               kfree(c->bu.buf);
+               c->bu.buf = NULL;
+       }
+
+       ubifs_assert(c->lst.taken_empty_lebs > 0);
        return 0;
 }
 
-struct super_operations ubifs_super_operations = {
+const struct super_operations ubifs_super_operations = {
        .alloc_inode   = ubifs_alloc_inode,
        .destroy_inode = ubifs_destroy_inode,
        .put_super     = ubifs_put_super,
@@ -1588,22 +1837,32 @@ struct super_operations ubifs_super_operations = {
  * @name: UBI volume name
  * @mode: UBI volume open mode
  *
- * There are several ways to specify UBI volumes when mounting UBIFS:
- * o ubiX_Y    - UBI device number X, volume Y;
- * o ubiY      - UBI device number 0, volume Y;
+ * The primary method of mounting UBIFS is by specifying the UBI volume
+ * character device node path. However, UBIFS may also be mounted withoug any
+ * character device node using one of the following methods:
+ *
+ * o ubiX_Y    - mount UBI device number X, volume Y;
+ * o ubiY      - mount UBI device number 0, volume Y;
  * o ubiX:NAME - mount UBI device X, volume with name NAME;
  * o ubi:NAME  - mount UBI device 0, volume with name NAME.
  *
  * Alternative '!' separator may be used instead of ':' (because some shells
  * like busybox may interpret ':' as an NFS host name separator). This function
- * returns ubi volume object in case of success and a negative error code in
- * case of failure.
+ * returns UBI volume description object in case of success and a negative
+ * error code in case of failure.
  */
 static struct ubi_volume_desc *open_ubi(const char *name, int mode)
 {
+       struct ubi_volume_desc *ubi;
        int dev, vol;
        char *endptr;
 
+       /* First, try to open using the device node path method */
+       ubi = ubi_open_volume_path(name, mode);
+       if (!IS_ERR(ubi))
+               return ubi;
+
+       /* Try the "nodev" method */
        if (name[0] != 'u' || name[1] != 'b' || name[2] != 'i')
                return ERR_PTR(-EINVAL);
 
@@ -1657,6 +1916,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
        mutex_init(&c->log_mutex);
        mutex_init(&c->mst_mutex);
        mutex_init(&c->umount_mutex);
+       mutex_init(&c->bu_mutex);
        init_waitqueue_head(&c->cmt_wq);
        c->buds = RB_ROOT;
        c->old_idx = RB_ROOT;
@@ -1675,6 +1935,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
        INIT_LIST_HEAD(&c->orph_list);
        INIT_LIST_HEAD(&c->orph_new);
 
+       c->vfs_sb = sb;
        c->highest_inum = UBIFS_FIRST_INO;
        c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM;
 
@@ -1696,23 +1957,26 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
         *
         * Read-ahead will be disabled because @c->bdi.ra_pages is 0.
         */
+       c->bdi.name = "ubifs",
        c->bdi.capabilities = BDI_CAP_MAP_COPY;
        c->bdi.unplug_io_fn = default_unplug_io_fn;
        err  = bdi_init(&c->bdi);
        if (err)
                goto out_close;
+       err = bdi_register(&c->bdi, NULL, "ubifs_%d_%d",
+                          c->vi.ubi_num, c->vi.vol_id);
+       if (err)
+               goto out_bdi;
 
        err = ubifs_parse_options(c, data, 0);
        if (err)
                goto out_bdi;
 
-       c->vfs_sb = sb;
-
+       sb->s_bdi = &c->bdi;
        sb->s_fs_info = c;
        sb->s_magic = UBIFS_SUPER_MAGIC;
        sb->s_blocksize = UBIFS_BLOCK_SIZE;
        sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT;
-       sb->s_dev = c->vi.cdev;
        sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c);
        if (c->max_inode_sz > MAX_LFS_FILESIZE)
                sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
@@ -1737,7 +2001,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
                goto out_iput;
 
        mutex_unlock(&c->umount_mutex);
-
        return 0;
 
 out_iput:
@@ -1758,16 +2021,9 @@ out_free:
 static int sb_test(struct super_block *sb, void *data)
 {
        dev_t *dev = data;
+       struct ubifs_info *c = sb->s_fs_info;
 
-       return sb->s_dev == *dev;
-}
-
-static int sb_set(struct super_block *sb, void *data)
-{
-       dev_t *dev = data;
-
-       sb->s_dev = *dev;
-       return 0;
+       return c->vi.cdev == *dev;
 }
 
 static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
@@ -1795,7 +2051,7 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
 
        dbg_gen("opened ubi%d_%d", vi.ubi_num, vi.vol_id);
 
-       sb = sget(fs_type, &sb_test, &sb_set, &vi.cdev);
+       sb = sget(fs_type, &sb_test, &set_anon_super, &vi.cdev);
        if (IS_ERR(sb)) {
                err = PTR_ERR(sb);
                goto out_close;
@@ -1825,35 +2081,21 @@ static int ubifs_get_sb(struct file_system_type *fs_type, int flags,
        /* 'fill_super()' opens ubi again so we must close it here */
        ubi_close_volume(ubi);
 
-       return simple_set_mnt(mnt, sb);
+       simple_set_mnt(mnt, sb);
+       return 0;
 
 out_deact:
-       up_write(&sb->s_umount);
-       deactivate_super(sb);
+       deactivate_locked_super(sb);
 out_close:
        ubi_close_volume(ubi);
        return err;
 }
 
-static void ubifs_kill_sb(struct super_block *sb)
-{
-       struct ubifs_info *c = sb->s_fs_info;
-
-       /*
-        * We do 'commit_on_unmount()' here instead of 'ubifs_put_super()'
-        * in order to be outside BKL.
-        */
-       if (sb->s_root && !(sb->s_flags & MS_RDONLY))
-               commit_on_unmount(c);
-       /* The un-mount routine is actually done in put_super() */
-       generic_shutdown_super(sb);
-}
-
 static struct file_system_type ubifs_fs_type = {
        .name    = "ubifs",
        .owner   = THIS_MODULE,
        .get_sb  = ubifs_get_sb,
-       .kill_sb = ubifs_kill_sb
+       .kill_sb = kill_anon_super,
 };
 
 /*
@@ -1909,6 +2151,14 @@ static int __init ubifs_init(void)
        BUILD_BUG_ON(UBIFS_REF_NODE_SZ != 64);
 
        /*
+        * 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', @default_compr in
+        * 'struct ubifs_info' and @compr_type in 'struct ubifs_mount_opts'.
+        */
+       BUILD_BUG_ON(UBIFS_COMPR_TYPES_CNT > 4);
+
+       /*
         * We require that PAGE_CACHE_SIZE is greater-than-or-equal-to
         * UBIFS_BLOCK_SIZE. It is assumed that both are powers of 2.
         */
@@ -1937,11 +2187,17 @@ static int __init ubifs_init(void)
 
        err = ubifs_compressors_init();
        if (err)
+               goto out_shrinker;
+
+       err = dbg_debugfs_init();
+       if (err)
                goto out_compr;
 
        return 0;
 
 out_compr:
+       ubifs_compressors_exit();
+out_shrinker:
        unregister_shrinker(&ubifs_shrinker_info);
        kmem_cache_destroy(ubifs_inode_slab);
 out_reg:
@@ -1956,6 +2212,7 @@ static void __exit ubifs_exit(void)
        ubifs_assert(list_empty(&ubifs_infos));
        ubifs_assert(atomic_long_read(&ubifs_clean_zn_cnt) == 0);
 
+       dbg_debugfs_exit();
        ubifs_compressors_exit();
        unregister_shrinker(&ubifs_shrinker_info);
        kmem_cache_destroy(ubifs_inode_slab);