Merge branch 'linux-next' of git://git.infradead.org/ubifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Mar 2011 17:50:27 +0000 (10:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 18 Mar 2011 17:50:27 +0000 (10:50 -0700)
* 'linux-next' of git://git.infradead.org/ubifs-2.6: (25 commits)
  UBIFS: clean-up commentaries
  UBIFS: save 128KiB or more RAM
  UBIFS: allocate orphans scan buffer on demand
  UBIFS: allocate lpt dump buffer on demand
  UBIFS: allocate ltab checking buffer on demand
  UBIFS: allocate scanning buffer on demand
  UBIFS: allocate dump buffer on demand
  UBIFS: do not check data crc by default
  UBIFS: simplify UBIFS Kconfig menu
  UBIFS: print max. index node size
  UBIFS: handle allocation failures in UBIFS write path
  UBIFS: use max_write_size during recovery
  UBIFS: use max_write_size for write-buffers
  UBIFS: introduce write-buffer size field
  UBI: incorporate LEB offset information
  UBIFS: incorporate maximum write size
  UBI: provide LEB offset information
  UBI: incorporate maximum write size
  UBIFS: fix LEB number in printk
  UBIFS: restrict world-writable debugfs files
  ...

1  2 
drivers/mtd/ubi/build.c
drivers/mtd/ubi/ubi.h
fs/ubifs/super.c

diff --combined drivers/mtd/ubi/build.c
index a801ea6b8b6d5cff1fb0208a2dd1c20e28c0ebf3,f38e8de818112790ebc1bd5627a71c0e6b63854a..65626c1c446d7ccd90abadaad7ceea5438c566a9
@@@ -690,11 -690,25 +690,25 @@@ static int io_init(struct ubi_device *u
        ubi_assert(ubi->hdrs_min_io_size <= ubi->min_io_size);
        ubi_assert(ubi->min_io_size % ubi->hdrs_min_io_size == 0);
  
+       ubi->max_write_size = ubi->mtd->writebufsize;
+       /*
+        * Maximum write size has to be greater or equivalent to min. I/O
+        * size, and be multiple of min. I/O size.
+        */
+       if (ubi->max_write_size < ubi->min_io_size ||
+           ubi->max_write_size % ubi->min_io_size ||
+           !is_power_of_2(ubi->max_write_size)) {
+               ubi_err("bad write buffer size %d for %d min. I/O unit",
+                       ubi->max_write_size, ubi->min_io_size);
+               return -EINVAL;
+       }
        /* Calculate default aligned sizes of EC and VID headers */
        ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size);
        ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size);
  
        dbg_msg("min_io_size      %d", ubi->min_io_size);
+       dbg_msg("max_write_size   %d", ubi->max_write_size);
        dbg_msg("hdrs_min_io_size %d", ubi->hdrs_min_io_size);
        dbg_msg("ec_hdr_alsize    %d", ubi->ec_hdr_alsize);
        dbg_msg("vid_hdr_alsize   %d", ubi->vid_hdr_alsize);
        }
  
        /* Similar for the data offset */
 -      ubi->leb_start = ubi->vid_hdr_offset + UBI_EC_HDR_SIZE;
 +      ubi->leb_start = ubi->vid_hdr_offset + UBI_VID_HDR_SIZE;
        ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size);
  
        dbg_msg("vid_hdr_offset   %d", ubi->vid_hdr_offset);
@@@ -923,8 -937,6 +937,8 @@@ int ubi_attach_mtd_dev(struct mtd_info 
        spin_lock_init(&ubi->volumes_lock);
  
        ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
 +      dbg_msg("sizeof(struct ubi_scan_leb) %zu", sizeof(struct ubi_scan_leb));
 +      dbg_msg("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
  
        err = io_init(ubi);
        if (err)
        if (!ubi->peb_buf2)
                goto out_free;
  
 -#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
 -      mutex_init(&ubi->dbg_buf_mutex);
 -      ubi->dbg_peb_buf = vmalloc(ubi->peb_size);
 -      if (!ubi->dbg_peb_buf)
 -              goto out_free;
 -#endif
 -
        err = attach_by_scanning(ubi);
        if (err) {
                dbg_err("failed to attach by scanning, error %d", err);
         * checks @ubi->thread_enabled. Otherwise we may fail to wake it up.
         */
        spin_lock(&ubi->wl_lock);
 -      if (!DBG_DISABLE_BGT)
 -              ubi->thread_enabled = 1;
 +      ubi->thread_enabled = 1;
        wake_up_process(ubi->bgt_thread);
        spin_unlock(&ubi->wl_lock);
  
@@@ -1003,6 -1023,9 +1017,6 @@@ out_detach
  out_free:
        vfree(ubi->peb_buf1);
        vfree(ubi->peb_buf2);
 -#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
 -      vfree(ubi->dbg_peb_buf);
 -#endif
        if (ref)
                put_device(&ubi->dev);
        else
@@@ -1073,6 -1096,9 +1087,6 @@@ int ubi_detach_mtd_dev(int ubi_num, in
        put_mtd_device(ubi->mtd);
        vfree(ubi->peb_buf1);
        vfree(ubi->peb_buf2);
 -#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
 -      vfree(ubi->dbg_peb_buf);
 -#endif
        ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
        put_device(&ubi->dev);
        return 0;
diff --combined drivers/mtd/ubi/ubi.h
index 49c864d175db103f585b508ea5a5f52ef09ed8e3,b78994330ebc8d4e6cdff9fbeae023e5ce10de26..f1be8b79663cbfc3a5d87828cf8b12c2cd7d4c28
@@@ -40,7 -40,6 +40,7 @@@
  #include <linux/notifier.h>
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/ubi.h>
 +#include <asm/pgtable.h>
  
  #include "ubi-media.h"
  #include "scan.h"
@@@ -382,12 -381,16 +382,14 @@@ struct ubi_wl_entry
   * @bad_allowed: whether the MTD device admits of bad physical eraseblocks or
   *               not
   * @nor_flash: non-zero if working on top of NOR flash
+  * @max_write_size: maximum amount of bytes the underlying flash can write at a
+  *                  time (MTD write buffer size)
   * @mtd: MTD device descriptor
   *
   * @peb_buf1: a buffer of PEB size used for different purposes
   * @peb_buf2: another buffer of PEB size used for different purposes
   * @buf_mutex: protects @peb_buf1 and @peb_buf2
   * @ckvol_mutex: serializes static volume checking when opening
 - * @dbg_peb_buf: buffer of PEB size used for debugging
 - * @dbg_buf_mutex: protects @dbg_peb_buf
   */
  struct ubi_device {
        struct cdev cdev;
        int vid_hdr_shift;
        unsigned int bad_allowed:1;
        unsigned int nor_flash:1;
+       int max_write_size;
        struct mtd_info *mtd;
  
        void *peb_buf1;
        void *peb_buf2;
        struct mutex buf_mutex;
        struct mutex ckvol_mutex;
 -#ifdef CONFIG_MTD_UBI_DEBUG_PARANOID
 -      void *dbg_peb_buf;
 -      struct mutex dbg_buf_mutex;
 -#endif
  };
  
  extern struct kmem_cache *ubi_wl_entry_slab;
diff --combined fs/ubifs/super.c
index 6e11c2975dcf504ae447d0132bb58297d24da428,1da5155a1bea5a532c02d85c33d097c5891d599e..e5dc1e120e8dfd9d4018ffc9ae961593f284a867
@@@ -272,20 -272,12 +272,20 @@@ static struct inode *ubifs_alloc_inode(
        return &ui->vfs_inode;
  };
  
 +static void ubifs_i_callback(struct rcu_head *head)
 +{
 +      struct inode *inode = container_of(head, struct inode, i_rcu);
 +      struct ubifs_inode *ui = ubifs_inode(inode);
 +      INIT_LIST_HEAD(&inode->i_dentry);
 +      kmem_cache_free(ubifs_inode_slab, ui);
 +}
 +
  static void ubifs_destroy_inode(struct inode *inode)
  {
        struct ubifs_inode *ui = ubifs_inode(inode);
  
        kfree(ui->data);
 -      kmem_cache_free(ubifs_inode_slab, inode);
 +      call_rcu(&inode->i_rcu, ubifs_i_callback);
  }
  
  /*
@@@ -512,9 -504,12 +512,12 @@@ static int init_constants_early(struct 
  
        c->leb_cnt = c->vi.size;
        c->leb_size = c->vi.usable_leb_size;
+       c->leb_start = c->di.leb_start;
        c->half_leb_size = c->leb_size / 2;
        c->min_io_size = c->di.min_io_size;
        c->min_io_shift = fls(c->min_io_size) - 1;
+       c->max_write_size = c->di.max_write_size;
+       c->max_write_shift = fls(c->max_write_size) - 1;
  
        if (c->leb_size < UBIFS_MIN_LEB_SZ) {
                ubifs_err("too small LEBs (%d bytes), min. is %d bytes",
                return -EINVAL;
        }
  
+       /*
+        * Maximum write size has to be greater or equivalent to min. I/O
+        * size, and be multiple of min. I/O size.
+        */
+       if (c->max_write_size < c->min_io_size ||
+           c->max_write_size % c->min_io_size ||
+           !is_power_of_2(c->max_write_size)) {
+               ubifs_err("bad write buffer size %d for %d min. I/O unit",
+                         c->max_write_size, c->min_io_size);
+               return -EINVAL;
+       }
        /*
         * UBIFS aligns all node to 8-byte boundary, so to make function in
         * io.c simpler, assume minimum I/O unit size to be 8 bytes if it is
        if (c->min_io_size < 8) {
                c->min_io_size = 8;
                c->min_io_shift = 3;
+               if (c->max_write_size < c->min_io_size) {
+                       c->max_write_size = c->min_io_size;
+                       c->max_write_shift = c->min_io_shift;
+               }
        }
  
        c->ref_node_alsz = ALIGN(UBIFS_REF_NODE_SZ, c->min_io_size);
@@@ -1202,11 -1213,14 +1221,14 @@@ static int mount_ubifs(struct ubifs_inf
        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;
+       if (!c->ro_mount) {
+               c->write_reserve_buf = kmalloc(COMPRESSED_DATA_NODE_BUF_SZ,
+                                              GFP_KERNEL);
+               if (!c->write_reserve_buf)
+                       goto out_free;
+       }
+       c->mounting = 1;
  
        err = ubifs_read_superblock(c);
        if (err)
        if (err)
                goto out_infos;
  
-       c->always_chk_crc = 0;
+       c->mounting = 0;
  
        ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"",
                  c->vi.ubi_num, c->vi.vol_id, c->vi.name);
  
        dbg_msg("compiled on:         " __DATE__ " at " __TIME__);
        dbg_msg("min. I/O unit size:  %d bytes", c->min_io_size);
+       dbg_msg("max. write size:     %d bytes", c->max_write_size);
        dbg_msg("LEB size:            %d bytes (%d KiB)",
                c->leb_size, c->leb_size >> 10);
        dbg_msg("data journal heads:  %d",
                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",
+       dbg_msg("max. node sizes:     data %zu, inode %zu dentry %zu, idx %d",
                UBIFS_MAX_DATA_NODE_SZ, UBIFS_MAX_INO_NODE_SZ,
-               UBIFS_MAX_DENT_NODE_SZ);
+               UBIFS_MAX_DENT_NODE_SZ, ubifs_idx_node_sz(c, c->fanout));
        dbg_msg("dead watermark:      %d", c->dead_wm);
        dbg_msg("dark watermark:      %d", c->dark_wm);
        dbg_msg("LEB overhead:        %d", c->leb_overhead);
@@@ -1474,6 -1489,7 +1497,7 @@@ out_wbufs
  out_cbuf:
        kfree(c->cbuf);
  out_free:
+       kfree(c->write_reserve_buf);
        kfree(c->bu.buf);
        vfree(c->ileb_buf);
        vfree(c->sbuf);
@@@ -1512,6 -1528,7 +1536,7 @@@ static void ubifs_umount(struct ubifs_i
        kfree(c->cbuf);
        kfree(c->rcvrd_mst_node);
        kfree(c->mst_node);
+       kfree(c->write_reserve_buf);
        kfree(c->bu.buf);
        vfree(c->ileb_buf);
        vfree(c->sbuf);
@@@ -1543,7 -1560,6 +1568,6 @@@ static int ubifs_remount_rw(struct ubif
        mutex_lock(&c->umount_mutex);
        dbg_save_space_info(c);
        c->remounting_rw = 1;
-       c->always_chk_crc = 1;
  
        err = check_free_space(c);
        if (err)
                goto out;
        }
  
+       c->write_reserve_buf = kmalloc(COMPRESSED_DATA_NODE_BUF_SZ, GFP_KERNEL);
+       if (!c->write_reserve_buf)
+               goto out;
        err = ubifs_lpt_init(c, 0, 1);
        if (err)
                goto out;
        dbg_gen("re-mounted read-write");
        c->ro_mount = 0;
        c->remounting_rw = 0;
-       c->always_chk_crc = 0;
        err = dbg_check_space_info(c);
        mutex_unlock(&c->umount_mutex);
        return err;
                c->bgt = NULL;
        }
        free_wbufs(c);
+       kfree(c->write_reserve_buf);
+       c->write_reserve_buf = NULL;
        vfree(c->ileb_buf);
        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;
  }
@@@ -1707,6 -1727,8 +1735,8 @@@ static void ubifs_remount_ro(struct ubi
        free_wbufs(c);
        vfree(c->orph_buf);
        c->orph_buf = NULL;
+       kfree(c->write_reserve_buf);
+       c->write_reserve_buf = NULL;
        vfree(c->ileb_buf);
        c->ileb_buf = NULL;
        ubifs_lpt_free(c, 1);
@@@ -1937,6 -1959,7 +1967,7 @@@ static int ubifs_fill_super(struct supe
        mutex_init(&c->mst_mutex);
        mutex_init(&c->umount_mutex);
        mutex_init(&c->bu_mutex);
+       mutex_init(&c->write_reserve_mutex);
        init_waitqueue_head(&c->cmt_wq);
        c->buds = RB_ROOT;
        c->old_idx = RB_ROOT;
        INIT_LIST_HEAD(&c->old_buds);
        INIT_LIST_HEAD(&c->orph_list);
        INIT_LIST_HEAD(&c->orph_new);
+       c->no_chk_data_crc = 1;
  
        c->vfs_sb = sb;
        c->highest_inum = UBIFS_FIRST_INO;