Merge git://git.infradead.org/ubifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 10 Dec 2009 17:31:45 +0000 (09:31 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 10 Dec 2009 17:31:45 +0000 (09:31 -0800)
* git://git.infradead.org/ubifs-2.6:
  UBIFS: fix return code in check_leaf
  UBI: flush wl before clearing update marker
  MAINTAINERS: change e-mail of Artem Bityutskiy
  UBIFS: remove manual O_SYNC handling
  UBIFS: support mounting of UBI volume character devices
  UBI: Add ubi_open_volume_path

MAINTAINERS
drivers/mtd/ubi/kapi.c
drivers/mtd/ubi/upd.c
fs/ubifs/debug.c
fs/ubifs/file.c
fs/ubifs/super.c
include/linux/mtd/ubi.h

index 746b706..d7f8668 100644 (file)
@@ -5335,7 +5335,7 @@ S:        Maintained
 F:     drivers/scsi/u14-34f.c
 
 UBI FILE SYSTEM (UBIFS)
-M:     Artem Bityutskiy <dedekind@infradead.org>
+M:     Artem Bityutskiy <dedekind1@gmail.com>
 M:     Adrian Hunter <adrian.hunter@nokia.com>
 L:     linux-mtd@lists.infradead.org
 T:     git git://git.infradead.org/ubifs-2.6.git
@@ -5386,7 +5386,7 @@ F:        drivers/cdrom/cdrom.c
 F:     include/linux/cdrom.h
 
 UNSORTED BLOCK IMAGES (UBI)
-M:     Artem Bityutskiy <dedekind@infradead.org>
+M:     Artem Bityutskiy <dedekind1@gmail.com>
 W:     http://www.linux-mtd.infradead.org/
 L:     linux-mtd@lists.infradead.org
 T:     git git://git.infradead.org/ubi-2.6.git
index 88a72e9..277786e 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/namei.h>
+#include <linux/fs.h>
 #include <asm/div64.h>
 #include "ubi.h"
 
@@ -280,6 +282,44 @@ struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
 EXPORT_SYMBOL_GPL(ubi_open_volume_nm);
 
 /**
+ * ubi_open_volume_path - open UBI volume by its character device node path.
+ * @pathname: volume character device node path
+ * @mode: open mode
+ *
+ * This function is similar to 'ubi_open_volume()', but opens a volume the path
+ * to its character device node.
+ */
+struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode)
+{
+       int error, ubi_num, vol_id;
+       struct ubi_volume_desc *ret;
+       struct inode *inode;
+       struct path path;
+
+       dbg_gen("open volume %s, mode %d", pathname, mode);
+
+       if (!pathname || !*pathname)
+               return ERR_PTR(-EINVAL);
+
+       error = kern_path(pathname, LOOKUP_FOLLOW, &path);
+       if (error)
+               return ERR_PTR(error);
+
+       inode = path.dentry->d_inode;
+       ubi_num = ubi_major2num(imajor(inode));
+       vol_id = iminor(inode) - 1;
+
+       if (vol_id >= 0 && ubi_num >= 0)
+               ret = ubi_open_volume(ubi_num, vol_id, mode);
+       else
+               ret = ERR_PTR(-ENODEV);
+
+       path_put(&path);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(ubi_open_volume_path);
+
+/**
  * ubi_close_volume - close UBI volume.
  * @desc: volume descriptor
  */
index 74fdc40..c1d7b88 100644 (file)
@@ -147,12 +147,14 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
        }
 
        if (bytes == 0) {
+               err = ubi_wl_flush(ubi);
+               if (err)
+                       return err;
+
                err = clear_update_marker(ubi, vol, 0);
                if (err)
                        return err;
-               err = ubi_wl_flush(ubi);
-               if (!err)
-                       vol->updating = 0;
+               vol->updating = 0;
        }
 
        vol->upd_buf = vmalloc(ubi->leb_size);
@@ -362,16 +364,16 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol,
 
        ubi_assert(vol->upd_received <= vol->upd_bytes);
        if (vol->upd_received == vol->upd_bytes) {
+               err = ubi_wl_flush(ubi);
+               if (err)
+                       return err;
                /* The update is finished, clear the update marker */
                err = clear_update_marker(ubi, vol, vol->upd_bytes);
                if (err)
                        return err;
-               err = ubi_wl_flush(ubi);
-               if (err == 0) {
-                       vol->updating = 0;
-                       err = to_write;
-                       vfree(vol->upd_buf);
-               }
+               vol->updating = 0;
+               err = to_write;
+               vfree(vol->upd_buf);
        }
 
        return err;
index dbc093a..8a771c5 100644 (file)
@@ -2014,7 +2014,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
                inum = key_inum_flash(c, &dent->key);
                fscki1 = read_add_inode(c, priv, inum);
                if (IS_ERR(fscki1)) {
-                       err = PTR_ERR(fscki);
+                       err = PTR_ERR(fscki1);
                        ubifs_err("error %d while processing entry node and "
                                  "trying to find parent inode node %lu",
                                  err, (unsigned long)inum);
index 1009adc..39849f8 100644 (file)
@@ -1389,7 +1389,6 @@ static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov,
                               unsigned long nr_segs, loff_t pos)
 {
        int err;
-       ssize_t ret;
        struct inode *inode = iocb->ki_filp->f_mapping->host;
        struct ubifs_info *c = inode->i_sb->s_fs_info;
 
@@ -1397,17 +1396,7 @@ static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov,
        if (err)
                return err;
 
-       ret = generic_file_aio_write(iocb, iov, nr_segs, pos);
-       if (ret < 0)
-               return ret;
-
-       if (ret > 0 && (IS_SYNC(inode) || iocb->ki_filp->f_flags & O_SYNC)) {
-               err = ubifs_sync_wbufs_by_inode(c, inode);
-               if (err)
-                       return err;
-       }
-
-       return ret;
+       return generic_file_aio_write(iocb, iov, nr_segs, pos);
 }
 
 static int ubifs_set_page_dirty(struct page *page)
index 333e181..943ad56 100644 (file)
@@ -1842,22 +1842,32 @@ const 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);
 
index 6913b71..b31bd9e 100644 (file)
@@ -174,6 +174,8 @@ void ubi_get_volume_info(struct ubi_volume_desc *desc,
 struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode);
 struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
                                           int mode);
+struct ubi_volume_desc *ubi_open_volume_path(const char *pathname, int mode);
+
 int ubi_register_volume_notifier(struct notifier_block *nb,
                                 int ignore_existing);
 int ubi_unregister_volume_notifier(struct notifier_block *nb);