Add an ubi_open_volume_path(path, mode) function which works like
open_bdev_exclusive(path, mode, ...) where path is the special file
representing the UBI volume, typically /dev/ubi0_0.
Signed-off-by: Corentin Chary <[email protected]>
---
drivers/mtd/ubi/kapi.c | 40 ++++++++++++++++++++++++++++++++++++++++
include/linux/mtd/ubi.h | 2 ++
2 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 88a72e9..d711aa7 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 path.
+ * @ubi_num: UBI device number
+ * @pathname: volume path
+ * @mode: open mode
+ *
+ * This function is similar to 'ubi_open_volume()', but opens a volume by name.
+ */
+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/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index 6913b71..b31bd9e 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -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);
--
1.6.5.rc1
This is needed to use $ mount /dev/ubi0_0 /mnt/nand
You'll also need a recent libblkid with UBI and UBIFS
support.
Signed-off-by: Corentin Chary <[email protected]>
---
fs/ubifs/super.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 7e2b3d4..146289b 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1847,6 +1847,7 @@ const struct super_operations ubifs_super_operations = {
* o ubiY - 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.
+ * o PATH - For example /dev/ubi0_0
*
* Alternative '!' separator may be used instead of ':' (because some shells
* like busybox may interpret ':' as an NFS host name separator). This function
@@ -1855,9 +1856,15 @@ const struct super_operations ubifs_super_operations = {
*/
static struct ubi_volume_desc *open_ubi(const char *name, int mode)
{
+ struct ubi_volume_desc *ubi;
int dev, vol;
char *endptr;
+ /* path method */
+ ubi = ubi_open_volume_path(name, mode);
+ if (!IS_ERR(ubi))
+ return ubi;
+
if (name[0] != 'u' || name[1] != 'b' || name[2] != 'i')
return ERR_PTR(-EINVAL);
--
1.6.5.rc1