Commit fc1495bf authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.infradead.org/ubifs-2.6

* 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
parents 5476ffd2 b38882f5
...@@ -5335,7 +5335,7 @@ S: Maintained ...@@ -5335,7 +5335,7 @@ S: Maintained
F: drivers/scsi/u14-34f.c F: drivers/scsi/u14-34f.c
UBI FILE SYSTEM (UBIFS) UBI FILE SYSTEM (UBIFS)
M: Artem Bityutskiy <dedekind@infradead.org> M: Artem Bityutskiy <dedekind1@gmail.com>
M: Adrian Hunter <adrian.hunter@nokia.com> M: Adrian Hunter <adrian.hunter@nokia.com>
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/ubifs-2.6.git T: git git://git.infradead.org/ubifs-2.6.git
...@@ -5386,7 +5386,7 @@ F: drivers/cdrom/cdrom.c ...@@ -5386,7 +5386,7 @@ F: drivers/cdrom/cdrom.c
F: include/linux/cdrom.h F: include/linux/cdrom.h
UNSORTED BLOCK IMAGES (UBI) UNSORTED BLOCK IMAGES (UBI)
M: Artem Bityutskiy <dedekind@infradead.org> M: Artem Bityutskiy <dedekind1@gmail.com>
W: http://www.linux-mtd.infradead.org/ W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org L: linux-mtd@lists.infradead.org
T: git git://git.infradead.org/ubi-2.6.git T: git git://git.infradead.org/ubi-2.6.git
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/namei.h>
#include <linux/fs.h>
#include <asm/div64.h> #include <asm/div64.h>
#include "ubi.h" #include "ubi.h"
...@@ -279,6 +281,44 @@ struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, ...@@ -279,6 +281,44 @@ struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
} }
EXPORT_SYMBOL_GPL(ubi_open_volume_nm); 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. * ubi_close_volume - close UBI volume.
* @desc: volume descriptor * @desc: volume descriptor
......
...@@ -147,12 +147,14 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -147,12 +147,14 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
} }
if (bytes == 0) { if (bytes == 0) {
err = ubi_wl_flush(ubi);
if (err)
return err;
err = clear_update_marker(ubi, vol, 0); err = clear_update_marker(ubi, vol, 0);
if (err) if (err)
return err; return err;
err = ubi_wl_flush(ubi); vol->updating = 0;
if (!err)
vol->updating = 0;
} }
vol->upd_buf = vmalloc(ubi->leb_size); vol->upd_buf = vmalloc(ubi->leb_size);
...@@ -362,16 +364,16 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -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); ubi_assert(vol->upd_received <= vol->upd_bytes);
if (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 */ /* The update is finished, clear the update marker */
err = clear_update_marker(ubi, vol, vol->upd_bytes); err = clear_update_marker(ubi, vol, vol->upd_bytes);
if (err) if (err)
return err; return err;
err = ubi_wl_flush(ubi); vol->updating = 0;
if (err == 0) { err = to_write;
vol->updating = 0; vfree(vol->upd_buf);
err = to_write;
vfree(vol->upd_buf);
}
} }
return err; return err;
......
...@@ -2014,7 +2014,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr, ...@@ -2014,7 +2014,7 @@ static int check_leaf(struct ubifs_info *c, struct ubifs_zbranch *zbr,
inum = key_inum_flash(c, &dent->key); inum = key_inum_flash(c, &dent->key);
fscki1 = read_add_inode(c, priv, inum); fscki1 = read_add_inode(c, priv, inum);
if (IS_ERR(fscki1)) { if (IS_ERR(fscki1)) {
err = PTR_ERR(fscki); err = PTR_ERR(fscki1);
ubifs_err("error %d while processing entry node and " ubifs_err("error %d while processing entry node and "
"trying to find parent inode node %lu", "trying to find parent inode node %lu",
err, (unsigned long)inum); err, (unsigned long)inum);
......
...@@ -1389,7 +1389,6 @@ static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -1389,7 +1389,6 @@ static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos) unsigned long nr_segs, loff_t pos)
{ {
int err; int err;
ssize_t ret;
struct inode *inode = iocb->ki_filp->f_mapping->host; struct inode *inode = iocb->ki_filp->f_mapping->host;
struct ubifs_info *c = inode->i_sb->s_fs_info; 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, ...@@ -1397,17 +1396,7 @@ static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov,
if (err) if (err)
return err; return err;
ret = generic_file_aio_write(iocb, iov, nr_segs, pos); return 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;
} }
static int ubifs_set_page_dirty(struct page *page) static int ubifs_set_page_dirty(struct page *page)
......
...@@ -1842,22 +1842,32 @@ const struct super_operations ubifs_super_operations = { ...@@ -1842,22 +1842,32 @@ const struct super_operations ubifs_super_operations = {
* @name: UBI volume name * @name: UBI volume name
* @mode: UBI volume open mode * @mode: UBI volume open mode
* *
* There are several ways to specify UBI volumes when mounting UBIFS: * The primary method of mounting UBIFS is by specifying the UBI volume
* o ubiX_Y - UBI device number X, volume Y; * character device node path. However, UBIFS may also be mounted withoug any
* o ubiY - UBI device number 0, volume Y; * 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 ubiX:NAME - mount UBI device X, volume with name NAME;
* o ubi:NAME - mount UBI device 0, 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 * Alternative '!' separator may be used instead of ':' (because some shells
* like busybox may interpret ':' as an NFS host name separator). This function * 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 * returns UBI volume description object in case of success and a negative
* case of failure. * error code in case of failure.
*/ */
static struct ubi_volume_desc *open_ubi(const char *name, int mode) static struct ubi_volume_desc *open_ubi(const char *name, int mode)
{ {
struct ubi_volume_desc *ubi;
int dev, vol; int dev, vol;
char *endptr; 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') if (name[0] != 'u' || name[1] != 'b' || name[2] != 'i')
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
......
...@@ -174,6 +174,8 @@ void ubi_get_volume_info(struct ubi_volume_desc *desc, ...@@ -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(int ubi_num, int vol_id, int mode);
struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name, struct ubi_volume_desc *ubi_open_volume_nm(int ubi_num, const char *name,
int mode); 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 ubi_register_volume_notifier(struct notifier_block *nb,
int ignore_existing); int ignore_existing);
int ubi_unregister_volume_notifier(struct notifier_block *nb); int ubi_unregister_volume_notifier(struct notifier_block *nb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment