mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/5] fs: Add for_each_fs_device_safe()
@ 2016-03-08 10:56 Markus Pargmann
  2016-03-08 10:56 ` [PATCH 2/5] ubi: Add getter ubi_volume_get_cdev() Markus Pargmann
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Markus Pargmann @ 2016-03-08 10:56 UTC (permalink / raw)
  To: barebox

We need to be able to umount specific filesystems while iterating all of
them. This helper gives us a safe macro to do so.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 include/fs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/fs.h b/include/fs.h
index ee7e48b0f968..3157a482d71a 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -87,6 +87,7 @@ struct fs_driver_d {
 
 extern struct list_head fs_device_list;
 #define for_each_fs_device(f) list_for_each_entry(f, &fs_device_list, list)
+#define for_each_fs_device_safe(tmp, f) list_for_each_entry_safe(f, tmp, &fs_device_list, list)
 extern struct bus_type fs_bus;
 
 struct fs_device_d {
-- 
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 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

end of thread, other threads:[~2016-03-09  7:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [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
2016-03-09  7:55   ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox