* [PATCH 2/5] ubi: Add getter ubi_volume_get_cdev()
2016-03-08 10:56 [PATCH 1/5] fs: Add for_each_fs_device_safe() Markus Pargmann
@ 2016-03-08 10:56 ` Markus Pargmann
2016-03-08 10:56 ` [PATCH 3/5] ubi: Add helper to map a mtd device to a ubi number Markus Pargmann
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Markus Pargmann @ 2016-03-08 10:56 UTC (permalink / raw)
To: barebox
cdev is used in a future commit to find the mounted filesystems.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/mtd/ubi/kapi.c | 5 +++++
include/linux/mtd/ubi.h | 2 ++
2 files changed, 7 insertions(+)
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index 7fc1aa8d70cc..c2e58e865753 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -308,6 +308,11 @@ void ubi_close_volume(struct ubi_volume_desc *desc)
}
EXPORT_SYMBOL_GPL(ubi_close_volume);
+struct cdev *ubi_volume_get_cdev(struct ubi_volume_desc *vol)
+{
+ return &vol->vol->cdev;
+}
+
/**
* ubi_leb_read - read data.
* @desc: volume descriptor
diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index 0614681d731c..0725b04f9dfd 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -218,6 +218,8 @@ int ubi_is_mapped(struct ubi_volume_desc *desc, int lnum);
int ubi_sync(int ubi_num);
int ubi_flush(int ubi_num, int vol_id, int lnum);
+struct cdev *ubi_volume_get_cdev(struct ubi_volume_desc *vol);
+
/*
* This function is the same as the 'ubi_leb_read()' function, but it does not
* provide the checking capability.
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/5] ubi: Add helper to map a mtd device to a ubi number
2016-03-08 10:56 [PATCH 1/5] fs: Add for_each_fs_device_safe() Markus Pargmann
2016-03-08 10:56 ` [PATCH 2/5] ubi: Add getter ubi_volume_get_cdev() Markus Pargmann
@ 2016-03-08 10:56 ` Markus Pargmann
2016-03-08 10:56 ` [PATCH 4/5] ubi: Helper to iterate over all ubi volumes Markus Pargmann
2016-03-08 10:56 ` [PATCH 5/5] ubiformat: Cleanly umount and detach the ubi before formating Markus Pargmann
3 siblings, 0 replies; 6+ messages in thread
From: Markus Pargmann @ 2016-03-08 10:56 UTC (permalink / raw)
To: barebox
ubi_num_get_by_mtd() searches for attached ubi devices for the given mtd
and returns the number of the ubi device.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/mtd/ubi/build.c | 30 +++++++++++++++++++++---------
include/mtd/ubi-user.h | 1 +
2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 797022636dcb..4901dde9a10f 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -481,6 +481,23 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
return 0;
}
+int ubi_num_get_by_mtd(struct mtd_info *mtd)
+{
+ int i;
+ struct ubi_device *ubi;
+
+ for (i = 0; i < UBI_MAX_DEVICES; i++) {
+ ubi = ubi_devices[i];
+ if (ubi && mtd == ubi->mtd) {
+ ubi_debug("mtd%d is already attached to ubi%d",
+ mtd->index, i);
+ return ubi->ubi_num;
+ }
+ }
+
+ return -ENOENT;
+}
+
/**
* ubi_attach_mtd_dev - attach an MTD device.
* @mtd: MTD device description object
@@ -501,7 +518,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
int vid_hdr_offset, int max_beb_per1024)
{
struct ubi_device *ubi;
- int i, err, ref = 0;
+ int ubi_id, err, ref = 0;
if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT)
return -EINVAL;
@@ -515,14 +532,9 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
* Note, this function assumes that UBI devices creations and deletions
* are serialized, so it does not take the &ubi_devices_lock.
*/
- for (i = 0; i < UBI_MAX_DEVICES; i++) {
- ubi = ubi_devices[i];
- if (ubi && mtd == ubi->mtd) {
- ubi_debug("mtd%d is already attached to ubi%d",
- mtd->index, i);
- return -EEXIST;
- }
- }
+ ubi_id = ubi_num_get_by_mtd(mtd);
+ if (ubi_id >= 0)
+ return -EEXIST;
/*
* Make sure this MTD device is not emulated on top of an UBI volume
diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h
index 2000ef2fd00d..ab1a6630f5ee 100644
--- a/include/mtd/ubi-user.h
+++ b/include/mtd/ubi-user.h
@@ -407,5 +407,6 @@ struct ubi_set_vol_prop_req {
int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
int vid_hdr_offset, int max_beb_per1024);
int ubi_detach_mtd_dev(int ubi_num, int anyway);
+int ubi_num_get_by_mtd(struct mtd_info *mtd);
#endif /* __UBI_USER_H__ */
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 4/5] ubi: Helper to iterate over all ubi volumes
2016-03-08 10:56 [PATCH 1/5] fs: Add for_each_fs_device_safe() Markus Pargmann
2016-03-08 10:56 ` [PATCH 2/5] ubi: Add getter ubi_volume_get_cdev() Markus Pargmann
2016-03-08 10:56 ` [PATCH 3/5] ubi: Add helper to map a mtd device to a ubi number Markus Pargmann
@ 2016-03-08 10:56 ` Markus Pargmann
2016-03-08 10:56 ` [PATCH 5/5] ubiformat: Cleanly umount and detach the ubi before formating Markus Pargmann
3 siblings, 0 replies; 6+ messages in thread
From: Markus Pargmann @ 2016-03-08 10:56 UTC (permalink / raw)
To: barebox
To find all the ubi volume ids on a given UBI, we need a helper. The
added functions allow to use ubi_volume_for_each() to get each volume id
of a UBI.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
drivers/mtd/ubi/kapi.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/linux/mtd/ubi.h | 11 +++++++++++
2 files changed, 53 insertions(+)
diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c
index c2e58e865753..f3b0f0d85d84 100644
--- a/drivers/mtd/ubi/kapi.c
+++ b/drivers/mtd/ubi/kapi.c
@@ -308,6 +308,48 @@ void ubi_close_volume(struct ubi_volume_desc *desc)
}
EXPORT_SYMBOL_GPL(ubi_close_volume);
+int ubi_volume_first(int ubi_num, struct ubi_device **ubi, int *vol_id)
+{
+ int i;
+
+ /* We keep the device until the last call of ubi_volume_next
+ * or ubi_volume_abort */
+ *ubi = ubi_get_device(ubi_num);
+ if (!*ubi)
+ return -ENODEV;
+
+ for (i = 0; i < (*ubi)->vtbl_slots; ++i) {
+ if ((*ubi)->volumes[i]) {
+ *vol_id = i;
+ return 0;
+ }
+ }
+
+ ubi_put_device(*ubi);
+ return -ENOENT;
+}
+
+int ubi_volume_next(struct ubi_device *ubi, int *vol_id)
+{
+ int i;
+
+ for (i = *vol_id + 1; i < ubi->vtbl_slots; ++i) {
+ if (ubi->volumes[i]) {
+ *vol_id = i;
+ return 0;
+ }
+ }
+
+ ubi_put_device(ubi);
+
+ return -ENOENT;
+}
+
+void ubi_volume_abort(struct ubi_device *ubi)
+{
+ ubi_put_device(ubi);
+}
+
struct cdev *ubi_volume_get_cdev(struct ubi_volume_desc *vol)
{
return &vol->vol->cdev;
diff --git a/include/linux/mtd/ubi.h b/include/linux/mtd/ubi.h
index 0725b04f9dfd..344842e4ed97 100644
--- a/include/linux/mtd/ubi.h
+++ b/include/linux/mtd/ubi.h
@@ -220,6 +220,17 @@ int ubi_flush(int ubi_num, int vol_id, int lnum);
struct cdev *ubi_volume_get_cdev(struct ubi_volume_desc *vol);
+struct ubi_device;
+int ubi_volume_first(int ubi_num, struct ubi_device **ubi, int *vol_id);
+int ubi_volume_next(struct ubi_device *ubi, int *vol_id);
+void ubi_volume_abort(struct ubi_device *ubi);
+
+#define ubi_volume_for_each(ubi_num, ubi, vol_id, ret) \
+ for (ret = ubi_volume_first(ubi_num, &(ubi), &(vol_id)); \
+ !ret; \
+ ret = ubi_volume_next(ubi, &(vol_id)))
+
+
/*
* This function is the same as the 'ubi_leb_read()' function, but it does not
* provide the checking capability.
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5/5] ubiformat: Cleanly umount and detach the ubi before formating
2016-03-08 10:56 [PATCH 1/5] fs: Add for_each_fs_device_safe() Markus Pargmann
` (2 preceding siblings ...)
2016-03-08 10:56 ` [PATCH 4/5] ubi: Helper to iterate over all ubi volumes Markus Pargmann
@ 2016-03-08 10:56 ` Markus Pargmann
2016-03-09 7:55 ` Sascha Hauer
3 siblings, 1 reply; 6+ messages in thread
From: Markus Pargmann @ 2016-03-08 10:56 UTC (permalink / raw)
To: barebox
This was an open fixme for some time. ubiformat does not care about used
ubi volumes or attached ubis.
This patch adds functionality that umounts all filesystems that are
mounted from this nand device. After that the ubi is detached. Then the
normal ubiformat code reformats the ubi. If a ubi was detached
previously, the code tries to reattach the ubi. Filesystems are not
remounted.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
commands/ubiformat.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 85 insertions(+), 2 deletions(-)
diff --git a/commands/ubiformat.c b/commands/ubiformat.c
index f9c50b7936eb..d25c2815e066 100644
--- a/commands/ubiformat.c
+++ b/commands/ubiformat.c
@@ -42,6 +42,7 @@
#include <libbb.h>
#include <libfile.h>
#include <linux/mtd/mtd.h>
+#include <linux/mtd/ubi.h>
#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/log2.h>
@@ -549,12 +550,68 @@ out_free:
return -1;
}
+static int ubi_umount_all(const char *mtddev, struct mtd_info_user *ui,
+ int *ubi_detached_num)
+{
+ struct ubi_device_info ubi_info;
+ struct cdev *ubi_cdev;
+ struct fs_device_d *fsdev;
+ struct fs_device_d *fsdev_tmp;
+ struct ubi_device *ubi_dev;
+ int ret;
+ int ubi_num;
+ int vol_id;
+
+
+ ubi_num = ubi_num_get_by_mtd(ui->mtd);
+ if (ubi_num < 0) /* No attached ubi found */
+ return 0;
+
+ ubi_get_device_info(ubi_num, &ubi_info);
+
+ ubi_volume_for_each(ubi_num, ubi_dev, vol_id, ret) {
+ struct ubi_volume_desc *vol;
+
+ vol = ubi_open_volume(ubi_num, vol_id, UBI_READONLY);
+ if (IS_ERR(vol)) {
+ pr_err("Failed to open ubi volume %d %d, %ld. Continuing\n",
+ ubi_num, vol_id, PTR_ERR(vol));
+ continue;
+ }
+
+ for_each_fs_device_safe(fsdev_tmp, fsdev) {
+ ubi_cdev = ubi_volume_get_cdev(vol);
+
+ if (fsdev->cdev == ubi_volume_get_cdev(vol)) {
+ ret = umount(fsdev->path);
+ if (ret) {
+ pr_err("Failed umounting %s, %d, continuing anyway\n",
+ fsdev->path, ret);
+ }
+ }
+ }
+
+ ubi_close_volume(vol);
+ }
+
+ ret = ubi_detach_mtd_dev(ubi_info.ubi_num, 1);
+ if (ret) {
+ pr_err("Failed force-detaching ubi device. Can't continue\n");
+ return ret;
+ }
+ *ubi_detached_num = ubi_info.ubi_num;
+
+ return 0;
+}
+
int do_ubiformat(int argc, char *argv[])
{
int err, verbose;
struct mtd_dev_info mtd;
struct ubigen_info ui;
struct ubi_scan_info *si;
+ int ubi_detached = -1;
+ struct mtd_info_user mtd_info;
err = parse_opt(argc, argv);
if (err)
@@ -614,8 +671,23 @@ int do_ubiformat(int argc, char *argv[])
goto out_close;
}
- /* Make sure this MTD device is not attached to UBI */
- /* FIXME! Find a proper way to do this in barebox! */
+ err = ioctl(args.node_fd, MEMGETINFO, &mtd_info);
+ if (err) {
+ sys_errmsg("Failed to get user info %d\n", err);
+ goto out_close;
+ }
+
+ /*
+ * Umount all filesystems, detach and store the number of the detached
+ * ubi so we can later reattach
+ */
+ err = ubi_umount_all(args.node, &mtd_info, &ubi_detached);
+ if (err) {
+ sys_errmsg("Cannot umount all filesystems and detach %d\n",
+ err);
+ goto out_close;
+ }
+
if (!args.quiet) {
normsg_cont("%s (%s), size %lld bytes (%s)", mtd.node, mtd.type_str,
@@ -750,6 +822,17 @@ int do_ubiformat(int argc, char *argv[])
libscan_ubi_scan_free(si);
close(args.node_fd);
+
+ /* Reattach the ubi device in case it was attached in the beginning */
+ if (ubi_detached != -1) {
+ err = ubi_attach_mtd_dev(mtd_info.mtd, ubi_detached, 0, 20);
+ if (err) {
+ pr_err("Failed to reattach ubi device to ubi number %d, %d\n",
+ ubi_detached, err);
+ return err;
+ }
+ }
+
return 0;
out_free:
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 5/5] ubiformat: Cleanly umount and detach the ubi before formating
2016-03-08 10:56 ` [PATCH 5/5] ubiformat: Cleanly umount and detach the ubi before formating Markus Pargmann
@ 2016-03-09 7:55 ` Sascha Hauer
0 siblings, 0 replies; 6+ messages in thread
From: Sascha Hauer @ 2016-03-09 7:55 UTC (permalink / raw)
To: Markus Pargmann; +Cc: barebox
Hi Markus,
On Tue, Mar 08, 2016 at 11:56:09AM +0100, Markus Pargmann wrote:
> This was an open fixme for some time. ubiformat does not care about used
> ubi volumes or attached ubis.
>
> This patch adds functionality that umounts all filesystems that are
> mounted from this nand device. After that the ubi is detached. Then the
> normal ubiformat code reformats the ubi. If a ubi was detached
> previously, the code tries to reattach the ubi. Filesystems are not
> remounted.
Normally I would expect ubiformat to fail when the mtd is used by UBI.
Can we make the behaviour optional and by default fail if the mtd is
busy?
> +static int ubi_umount_all(const char *mtddev, struct mtd_info_user *ui,
> + int *ubi_detached_num)
> +{
> + struct ubi_device_info ubi_info;
> + struct cdev *ubi_cdev;
> + struct fs_device_d *fsdev;
> + struct fs_device_d *fsdev_tmp;
> + struct ubi_device *ubi_dev;
> + int ret;
> + int ubi_num;
> + int vol_id;
> +
> +
> + ubi_num = ubi_num_get_by_mtd(ui->mtd);
> + if (ubi_num < 0) /* No attached ubi found */
> + return 0;
> +
> + ubi_get_device_info(ubi_num, &ubi_info);
> +
> + ubi_volume_for_each(ubi_num, ubi_dev, vol_id, ret) {
> + struct ubi_volume_desc *vol;
> +
> + vol = ubi_open_volume(ubi_num, vol_id, UBI_READONLY);
> + if (IS_ERR(vol)) {
> + pr_err("Failed to open ubi volume %d %d, %ld. Continuing\n",
> + ubi_num, vol_id, PTR_ERR(vol));
> + continue;
> + }
> +
> + for_each_fs_device_safe(fsdev_tmp, fsdev) {
> + ubi_cdev = ubi_volume_get_cdev(vol);
> +
> + if (fsdev->cdev == ubi_volume_get_cdev(vol)) {
> + ret = umount(fsdev->path);
> + if (ret) {
> + pr_err("Failed umounting %s, %d, continuing anyway\n",
> + fsdev->path, ret);
> + }
Shouldn't this be an error?
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread