diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/ubi/kapi.c | 40 | ||||
-rw-r--r-- | drivers/mtd/ubi/upd.c | 20 |
2 files changed, 51 insertions, 9 deletions
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index 88a72e9c8beb..277786ebaa2c 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -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 */ diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 74fdc40c8627..c1d7b880c795 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c @@ -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; |