* Let ubiformat umount / detach users
@ 2016-03-15 11:22 Sascha Hauer
2016-03-15 11:22 ` [PATCH 1/8] fs: umount based on device path and mount path Sascha Hauer
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
This is a rebase of the series Markus sent earlier on the recent
ubiformat changes.
Sascha
----------------------------------------------------------------
Markus Pargmann (3):
fs: umount based on device path and mount path
fs: Add for_each_fs_device_safe()
ubiformat: Cleanly umount and detach the ubi before formating
Sascha Hauer (5):
mtd: ubi: rename cdev.c to barebox.c
mtd: ubi: make ubi_detach_mtd_dev ubi internal
mtd: ubi: umount mounted volumes before detaching a ubi device
mtd: ubi: Add function to get ubi number from mtd device
commands: ubidetach: Allow mtd devices as argument
commands/ubi.c | 30 +++++++++++++++---
commands/ubiformat.c | 24 +++++++++++++--
commands/umount.c | 2 +-
drivers/mtd/ubi/Makefile | 2 +-
drivers/mtd/ubi/{cdev.c => barebox.c} | 57 +++++++++++++++++++++++++++++++++++
drivers/mtd/ubi/ubi.h | 1 +
fs/fs.c | 48 +++++++++++++++++++++++++++--
include/fs.h | 2 ++
include/mtd/ubi-user.h | 3 +-
9 files changed, 157 insertions(+), 12 deletions(-)
rename drivers/mtd/ubi/{cdev.c => barebox.c} (83%)
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/8] fs: umount based on device path and mount path
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
2016-03-15 11:22 ` [PATCH 2/8] fs: Add for_each_fs_device_safe() Sascha Hauer
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
From: Markus Pargmann <mpa@pengutronix.de>
umount on Linux can be used on a mount pathes and device pathes. This
patch adds this functionality to barebox.
Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
commands/umount.c | 2 +-
fs/fs.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
include/fs.h | 1 +
3 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/commands/umount.c b/commands/umount.c
index 84c84e4..fdf4da9 100644
--- a/commands/umount.c
+++ b/commands/umount.c
@@ -37,7 +37,7 @@ BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(umount)
.cmd = do_umount,
BAREBOX_CMD_DESC("umount a filesystem")
- BAREBOX_CMD_OPTS("MOUNTPOINT")
+ BAREBOX_CMD_OPTS("MOUNTPOINT/DEVICEPATH")
BAREBOX_CMD_GROUP(CMD_GRP_PART)
BAREBOX_CMD_HELP(cmd_umount_help)
BAREBOX_CMD_END
diff --git a/fs/fs.c b/fs/fs.c
index c4b3583..440adae 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1317,6 +1317,40 @@ err_free_path:
}
EXPORT_SYMBOL(mount);
+static int fsdev_umount(struct fs_device_d *fsdev)
+{
+ return unregister_device(&fsdev->dev);
+}
+
+/**
+ * umount_by_cdev Use a cdev struct to umount all mounted filesystems
+ * @param cdev cdev to the according device
+ * @return 0 on success or if cdev was not mounted, -errno otherwise
+ */
+int umount_by_cdev(struct cdev *cdev)
+{
+ struct fs_device_d *fs;
+ struct fs_device_d *fs_tmp;
+ int first_error = 0;
+
+ for_each_fs_device_safe(fs_tmp, fs) {
+ int ret;
+
+ if (fs->cdev == cdev) {
+ ret = fsdev_umount(fs);
+ if (ret) {
+ pr_err("Failed umounting %s, %d, continuing anyway\n",
+ fs->path, ret);
+ if (!first_error)
+ first_error = ret;
+ }
+ }
+ }
+
+ return first_error;
+}
+EXPORT_SYMBOL(umount_by_cdev);
+
int umount(const char *pathname)
{
struct fs_device_d *fsdev = NULL, *f;
@@ -1329,6 +1363,16 @@ int umount(const char *pathname)
}
}
+ if (!fsdev) {
+ struct cdev *cdev = cdev_open(p, O_RDWR);
+
+ if (cdev) {
+ free(p);
+ cdev_close(cdev);
+ return umount_by_cdev(cdev);
+ }
+ }
+
free(p);
if (f == fs_dev_root && !list_is_singular(&fs_device_list)) {
@@ -1341,9 +1385,7 @@ int umount(const char *pathname)
return -EFAULT;
}
- unregister_device(&fsdev->dev);
-
- return 0;
+ return fsdev_umount(fsdev);
}
EXPORT_SYMBOL(umount);
diff --git a/include/fs.h b/include/fs.h
index 9f4164e..7301942 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -143,6 +143,7 @@ int readlink(const char *path, char *buf, size_t bufsiz);
int mount (const char *device, const char *fsname, const char *path,
const char *fsoptions);
int umount(const char *pathname);
+int umount_by_cdev(struct cdev *cdev);
/* not-so-standard functions */
int erase(int fd, loff_t count, loff_t offset);
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/8] fs: Add for_each_fs_device_safe()
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
2016-03-15 11:22 ` [PATCH 1/8] fs: umount based on device path and mount path Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
2016-03-15 11:22 ` [PATCH 3/8] mtd: ubi: rename cdev.c to barebox.c Sascha Hauer
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
From: Markus Pargmann <mpa@pengutronix.de>
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 7301942..b9d1e6e 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -88,6 +88,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] 9+ messages in thread
* [PATCH 3/8] mtd: ubi: rename cdev.c to barebox.c
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
2016-03-15 11:22 ` [PATCH 1/8] fs: umount based on device path and mount path Sascha Hauer
2016-03-15 11:22 ` [PATCH 2/8] fs: Add for_each_fs_device_safe() Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
2016-03-15 11:22 ` [PATCH 4/8] mtd: ubi: make ubi_detach_mtd_dev ubi internal Sascha Hauer
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
cdev.c exists in the kernel UBI code, but barebox has completely
different content in this file. rename it to barebox.c to reduce the
number of merge conflicts. Also with the name barebox.c we now have
a place to put other barebox specific UBI code to.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/ubi/Makefile | 2 +-
drivers/mtd/ubi/barebox.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/mtd/ubi/cdev.c | 262 ----------------------------------------------
3 files changed, 263 insertions(+), 263 deletions(-)
create mode 100644 drivers/mtd/ubi/barebox.c
delete mode 100644 drivers/mtd/ubi/cdev.c
diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile
index 795b116..33ac390 100644
--- a/drivers/mtd/ubi/Makefile
+++ b/drivers/mtd/ubi/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_MTD_UBI) += ubi.o
-ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o
+ubi-y += vtbl.o vmt.o upd.o build.o barebox.o kapi.o eba.o io.o wl.o attach.o
ubi-y += misc.o debug.o
ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o
diff --git a/drivers/mtd/ubi/barebox.c b/drivers/mtd/ubi/barebox.c
new file mode 100644
index 0000000..fe71a8d
--- /dev/null
+++ b/drivers/mtd/ubi/barebox.c
@@ -0,0 +1,262 @@
+#include <common.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <ioctl.h>
+#include "ubi-barebox.h"
+#include "ubi.h"
+
+LIST_HEAD(ubi_volumes_list);
+
+struct ubi_volume_cdev_priv {
+ struct ubi_device *ubi;
+ struct ubi_volume *vol;
+ int written;
+};
+
+static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
+ loff_t offset, unsigned long flags)
+{
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+ struct ubi_volume *vol = priv->vol;
+ struct ubi_device *ubi = priv->ubi;
+ int err, lnum, off, len;
+ size_t count_save = size;
+ unsigned long long tmp;
+ loff_t offp = offset;
+ int usable_leb_size = vol->usable_leb_size;
+
+ ubi_debug("%s: %zd @ 0x%08llx", __func__, size, offset);
+
+ len = size > usable_leb_size ? usable_leb_size : size;
+
+ tmp = offp;
+ off = do_div(tmp, usable_leb_size);
+ lnum = tmp;
+ do {
+ if (off + len >= usable_leb_size)
+ len = usable_leb_size - off;
+
+ err = ubi_eba_read_leb(ubi, vol, lnum, buf, off, len, 0);
+ if (err) {
+ ubi_err("read error: %s", strerror(-err));
+ break;
+ }
+ off += len;
+ if (off == usable_leb_size) {
+ lnum += 1;
+ off -= usable_leb_size;
+ }
+
+ size -= len;
+ offp += len;
+
+ buf += len;
+ len = size > usable_leb_size ? usable_leb_size : size;
+ } while (size);
+
+ return count_save;
+}
+
+static ssize_t ubi_volume_cdev_write(struct cdev* cdev, const void *buf,
+ size_t size, loff_t offset, unsigned long flags)
+{
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+ struct ubi_volume *vol = priv->vol;
+ struct ubi_device *ubi = priv->ubi;
+ int err;
+
+ if (!priv->written) {
+ err = ubi_start_update(ubi, vol, vol->used_bytes);
+ if (err < 0) {
+ ubi_err("Cannot start volume update");
+ return err;
+ }
+ }
+
+ err = ubi_more_update_data(ubi, vol, buf, size);
+ if (err < 0) {
+ ubi_err("Couldnt or partially wrote data");
+ return err;
+ }
+
+ priv->written += size;
+
+ return size;
+}
+
+static int ubi_volume_cdev_open(struct cdev *cdev, unsigned long flags)
+{
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+
+ priv->written = 0;
+
+ return 0;
+}
+
+static int ubi_volume_cdev_close(struct cdev *cdev)
+{
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+ struct ubi_volume *vol = priv->vol;
+ struct ubi_device *ubi = priv->ubi;
+ int err;
+
+ if (priv->written) {
+ int remaining = vol->usable_leb_size -
+ (priv->written % vol->usable_leb_size);
+
+ if (remaining) {
+ void *buf = kmalloc(remaining, GFP_KERNEL);
+
+ if (!buf)
+ return -ENOMEM;
+
+ memset(buf, 0xff, remaining);
+
+ err = ubi_more_update_data(ubi, vol, buf, remaining);
+
+ kfree(buf);
+
+ if (err < 0) {
+ ubi_err("Couldnt or partially wrote data");
+ return err;
+ }
+ }
+
+ err = ubi_finish_update(ubi, vol);
+ if (err)
+ return err;
+
+ err = ubi_check_volume(ubi, vol->vol_id);
+ if (err < 0) {
+ ubi_err("ubi volume check failed: %s", strerror(err));
+ return err;
+ }
+
+ if (err) {
+ ubi_warn("volume %d on UBI device %d is corrupted",
+ vol->vol_id, ubi->ubi_num);
+ vol->corrupted = 1;
+ }
+
+ vol->checked = 1;
+ ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
+ }
+
+ return 0;
+}
+
+static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
+{
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+
+ /* We can only update ubi volumes sequentially */
+ if (priv->written)
+ return -EINVAL;
+
+ return ofs;
+}
+
+static struct file_operations ubi_volume_fops = {
+ .open = ubi_volume_cdev_open,
+ .close = ubi_volume_cdev_close,
+ .read = ubi_volume_cdev_read,
+ .write = ubi_volume_cdev_write,
+ .lseek = ubi_volume_cdev_lseek,
+};
+
+int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol)
+{
+ struct cdev *cdev = &vol->cdev;
+ struct ubi_volume_cdev_priv *priv;
+ int ret;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+
+ priv->vol = vol;
+ priv->ubi = ubi;
+
+ cdev->ops = &ubi_volume_fops;
+ cdev->name = asprintf("%s.%s", ubi->cdev.name, vol->name);
+ cdev->priv = priv;
+ cdev->size = vol->used_bytes;
+ cdev->dev = &vol->dev;
+ ubi_msg("registering %s as /dev/%s", vol->name, cdev->name);
+ ret = devfs_create(cdev);
+ if (ret) {
+ kfree(priv);
+ free(cdev->name);
+ }
+
+ list_add_tail(&vol->list, &ubi_volumes_list);
+
+ return 0;
+}
+
+void ubi_volume_cdev_remove(struct ubi_volume *vol)
+{
+ struct cdev *cdev = &vol->cdev;
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+
+ list_del(&vol->list);
+
+ devfs_remove(cdev);
+ unregister_device(&vol->dev);
+ kfree(cdev->name);
+ kfree(priv);
+}
+
+static int ubi_cdev_ioctl(struct cdev *cdev, int cmd, void *buf)
+{
+ struct ubi_volume_desc *desc;
+ struct ubi_device *ubi = cdev->priv;
+ struct ubi_mkvol_req *req = buf;
+
+ switch (cmd) {
+ case UBI_IOCRMVOL:
+ desc = ubi_open_volume_nm(ubi->ubi_num, req->name,
+ UBI_EXCLUSIVE);
+ if (IS_ERR(desc))
+ return PTR_ERR(desc);
+ ubi_remove_volume(desc, 0);
+ ubi_close_volume(desc);
+ break;
+ case UBI_IOCMKVOL:
+ if (!req->bytes)
+ req->bytes = (__s64)ubi->avail_pebs * ubi->leb_size;
+ return ubi_create_volume(ubi, req);
+ };
+
+ return 0;
+}
+
+static struct file_operations ubi_fops = {
+ .ioctl = ubi_cdev_ioctl,
+};
+
+int ubi_cdev_add(struct ubi_device *ubi)
+{
+ struct cdev *cdev = &ubi->cdev;
+ int ret;
+
+ cdev->ops = &ubi_fops;
+ cdev->name = asprintf("%s.ubi", ubi->mtd->cdev.name);
+ cdev->priv = ubi;
+ cdev->size = 0;
+
+ ubi_msg("registering /dev/%s", cdev->name);
+ ret = devfs_create(cdev);
+ if (ret)
+ kfree(cdev->name);
+
+ return ret;
+}
+
+void ubi_cdev_remove(struct ubi_device *ubi)
+{
+ struct cdev *cdev = &ubi->cdev;
+
+ ubi_msg("removing %s", cdev->name);
+
+ devfs_remove(cdev);
+ kfree(cdev->name);
+}
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
deleted file mode 100644
index fe71a8d..0000000
--- a/drivers/mtd/ubi/cdev.c
+++ /dev/null
@@ -1,262 +0,0 @@
-#include <common.h>
-#include <fcntl.h>
-#include <fs.h>
-#include <ioctl.h>
-#include "ubi-barebox.h"
-#include "ubi.h"
-
-LIST_HEAD(ubi_volumes_list);
-
-struct ubi_volume_cdev_priv {
- struct ubi_device *ubi;
- struct ubi_volume *vol;
- int written;
-};
-
-static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
- loff_t offset, unsigned long flags)
-{
- struct ubi_volume_cdev_priv *priv = cdev->priv;
- struct ubi_volume *vol = priv->vol;
- struct ubi_device *ubi = priv->ubi;
- int err, lnum, off, len;
- size_t count_save = size;
- unsigned long long tmp;
- loff_t offp = offset;
- int usable_leb_size = vol->usable_leb_size;
-
- ubi_debug("%s: %zd @ 0x%08llx", __func__, size, offset);
-
- len = size > usable_leb_size ? usable_leb_size : size;
-
- tmp = offp;
- off = do_div(tmp, usable_leb_size);
- lnum = tmp;
- do {
- if (off + len >= usable_leb_size)
- len = usable_leb_size - off;
-
- err = ubi_eba_read_leb(ubi, vol, lnum, buf, off, len, 0);
- if (err) {
- ubi_err("read error: %s", strerror(-err));
- break;
- }
- off += len;
- if (off == usable_leb_size) {
- lnum += 1;
- off -= usable_leb_size;
- }
-
- size -= len;
- offp += len;
-
- buf += len;
- len = size > usable_leb_size ? usable_leb_size : size;
- } while (size);
-
- return count_save;
-}
-
-static ssize_t ubi_volume_cdev_write(struct cdev* cdev, const void *buf,
- size_t size, loff_t offset, unsigned long flags)
-{
- struct ubi_volume_cdev_priv *priv = cdev->priv;
- struct ubi_volume *vol = priv->vol;
- struct ubi_device *ubi = priv->ubi;
- int err;
-
- if (!priv->written) {
- err = ubi_start_update(ubi, vol, vol->used_bytes);
- if (err < 0) {
- ubi_err("Cannot start volume update");
- return err;
- }
- }
-
- err = ubi_more_update_data(ubi, vol, buf, size);
- if (err < 0) {
- ubi_err("Couldnt or partially wrote data");
- return err;
- }
-
- priv->written += size;
-
- return size;
-}
-
-static int ubi_volume_cdev_open(struct cdev *cdev, unsigned long flags)
-{
- struct ubi_volume_cdev_priv *priv = cdev->priv;
-
- priv->written = 0;
-
- return 0;
-}
-
-static int ubi_volume_cdev_close(struct cdev *cdev)
-{
- struct ubi_volume_cdev_priv *priv = cdev->priv;
- struct ubi_volume *vol = priv->vol;
- struct ubi_device *ubi = priv->ubi;
- int err;
-
- if (priv->written) {
- int remaining = vol->usable_leb_size -
- (priv->written % vol->usable_leb_size);
-
- if (remaining) {
- void *buf = kmalloc(remaining, GFP_KERNEL);
-
- if (!buf)
- return -ENOMEM;
-
- memset(buf, 0xff, remaining);
-
- err = ubi_more_update_data(ubi, vol, buf, remaining);
-
- kfree(buf);
-
- if (err < 0) {
- ubi_err("Couldnt or partially wrote data");
- return err;
- }
- }
-
- err = ubi_finish_update(ubi, vol);
- if (err)
- return err;
-
- err = ubi_check_volume(ubi, vol->vol_id);
- if (err < 0) {
- ubi_err("ubi volume check failed: %s", strerror(err));
- return err;
- }
-
- if (err) {
- ubi_warn("volume %d on UBI device %d is corrupted",
- vol->vol_id, ubi->ubi_num);
- vol->corrupted = 1;
- }
-
- vol->checked = 1;
- ubi_volume_notify(ubi, vol, UBI_VOLUME_UPDATED);
- }
-
- return 0;
-}
-
-static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
-{
- struct ubi_volume_cdev_priv *priv = cdev->priv;
-
- /* We can only update ubi volumes sequentially */
- if (priv->written)
- return -EINVAL;
-
- return ofs;
-}
-
-static struct file_operations ubi_volume_fops = {
- .open = ubi_volume_cdev_open,
- .close = ubi_volume_cdev_close,
- .read = ubi_volume_cdev_read,
- .write = ubi_volume_cdev_write,
- .lseek = ubi_volume_cdev_lseek,
-};
-
-int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol)
-{
- struct cdev *cdev = &vol->cdev;
- struct ubi_volume_cdev_priv *priv;
- int ret;
-
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-
- priv->vol = vol;
- priv->ubi = ubi;
-
- cdev->ops = &ubi_volume_fops;
- cdev->name = asprintf("%s.%s", ubi->cdev.name, vol->name);
- cdev->priv = priv;
- cdev->size = vol->used_bytes;
- cdev->dev = &vol->dev;
- ubi_msg("registering %s as /dev/%s", vol->name, cdev->name);
- ret = devfs_create(cdev);
- if (ret) {
- kfree(priv);
- free(cdev->name);
- }
-
- list_add_tail(&vol->list, &ubi_volumes_list);
-
- return 0;
-}
-
-void ubi_volume_cdev_remove(struct ubi_volume *vol)
-{
- struct cdev *cdev = &vol->cdev;
- struct ubi_volume_cdev_priv *priv = cdev->priv;
-
- list_del(&vol->list);
-
- devfs_remove(cdev);
- unregister_device(&vol->dev);
- kfree(cdev->name);
- kfree(priv);
-}
-
-static int ubi_cdev_ioctl(struct cdev *cdev, int cmd, void *buf)
-{
- struct ubi_volume_desc *desc;
- struct ubi_device *ubi = cdev->priv;
- struct ubi_mkvol_req *req = buf;
-
- switch (cmd) {
- case UBI_IOCRMVOL:
- desc = ubi_open_volume_nm(ubi->ubi_num, req->name,
- UBI_EXCLUSIVE);
- if (IS_ERR(desc))
- return PTR_ERR(desc);
- ubi_remove_volume(desc, 0);
- ubi_close_volume(desc);
- break;
- case UBI_IOCMKVOL:
- if (!req->bytes)
- req->bytes = (__s64)ubi->avail_pebs * ubi->leb_size;
- return ubi_create_volume(ubi, req);
- };
-
- return 0;
-}
-
-static struct file_operations ubi_fops = {
- .ioctl = ubi_cdev_ioctl,
-};
-
-int ubi_cdev_add(struct ubi_device *ubi)
-{
- struct cdev *cdev = &ubi->cdev;
- int ret;
-
- cdev->ops = &ubi_fops;
- cdev->name = asprintf("%s.ubi", ubi->mtd->cdev.name);
- cdev->priv = ubi;
- cdev->size = 0;
-
- ubi_msg("registering /dev/%s", cdev->name);
- ret = devfs_create(cdev);
- if (ret)
- kfree(cdev->name);
-
- return ret;
-}
-
-void ubi_cdev_remove(struct ubi_device *ubi)
-{
- struct cdev *cdev = &ubi->cdev;
-
- ubi_msg("removing %s", cdev->name);
-
- devfs_remove(cdev);
- kfree(cdev->name);
-}
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/8] mtd: ubi: make ubi_detach_mtd_dev ubi internal
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
` (2 preceding siblings ...)
2016-03-15 11:22 ` [PATCH 3/8] mtd: ubi: rename cdev.c to barebox.c Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
2016-03-15 11:22 ` [PATCH 5/8] mtd: ubi: umount mounted volumes before detaching a ubi device Sascha Hauer
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
We want to extend the functionality of the ubi detach function,
but we don't want to change the original detach function to make
UBI updates easier. This adds a barebox specific detach function
which encapsulates the original UBI function. Also this makes the
original ubi detach function internal to ubi.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/ubi.c | 2 +-
drivers/mtd/ubi/barebox.c | 20 ++++++++++++++++++++
drivers/mtd/ubi/ubi.h | 1 +
include/mtd/ubi-user.h | 2 +-
4 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/commands/ubi.c b/commands/ubi.c
index 9463127..8e35787 100644
--- a/commands/ubi.c
+++ b/commands/ubi.c
@@ -128,7 +128,7 @@ static int do_ubidetach(int argc, char *argv[])
return COMMAND_ERROR_USAGE;
ubi_num = simple_strtoul(argv[1], NULL, 0);
- ret = ubi_detach_mtd_dev(ubi_num, 1);
+ ret = ubi_detach(ubi_num);
if (ret)
printf("failed to detach: %s\n", strerror(-ret));
diff --git a/drivers/mtd/ubi/barebox.c b/drivers/mtd/ubi/barebox.c
index fe71a8d..1643f7c 100644
--- a/drivers/mtd/ubi/barebox.c
+++ b/drivers/mtd/ubi/barebox.c
@@ -260,3 +260,23 @@ void ubi_cdev_remove(struct ubi_device *ubi)
devfs_remove(cdev);
kfree(cdev->name);
}
+
+/**
+ * ubi_detach - detach an UBI device
+ * @ubi_num: The UBI device number
+ *
+ * @return: 0 for success, negative error code otherwise
+ */
+int ubi_detach(int ubi_num)
+{
+ struct ubi_device *ubi;
+
+ if (ubi_num < 0 || ubi_num >= UBI_MAX_DEVICES)
+ return -EINVAL;
+
+ ubi = ubi_devices[ubi_num];
+ if (!ubi)
+ return -ENOENT;
+
+ return ubi_detach_mtd_dev(ubi_num, 1);
+}
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 03a36d2..a8ed0d7 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -809,6 +809,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
struct ubi_vid_hdr *vid_hdr);
/* build.c */
+int ubi_detach_mtd_dev(int ubi_num, int anyway);
struct ubi_device *ubi_get_device(int ubi_num);
void ubi_put_device(struct ubi_device *ubi);
struct ubi_device *ubi_get_by_major(int major);
diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h
index 2000ef2..2002548 100644
--- a/include/mtd/ubi-user.h
+++ b/include/mtd/ubi-user.h
@@ -406,6 +406,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_detach(int ubi_num);
#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] 9+ messages in thread
* [PATCH 5/8] mtd: ubi: umount mounted volumes before detaching a ubi device
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
` (3 preceding siblings ...)
2016-03-15 11:22 ` [PATCH 4/8] mtd: ubi: make ubi_detach_mtd_dev ubi internal Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
2016-03-15 11:22 ` [PATCH 6/8] mtd: ubi: Add function to get ubi number from mtd device Sascha Hauer
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/ubi/barebox.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/mtd/ubi/barebox.c b/drivers/mtd/ubi/barebox.c
index 1643f7c..f81705e 100644
--- a/drivers/mtd/ubi/barebox.c
+++ b/drivers/mtd/ubi/barebox.c
@@ -261,10 +261,25 @@ void ubi_cdev_remove(struct ubi_device *ubi)
kfree(cdev->name);
}
+static void ubi_umount_volumes(struct ubi_device *ubi)
+{
+ int i;
+
+ for (i = 0; i < ubi->vtbl_slots; i++) {
+ struct ubi_volume *vol = ubi->volumes[i];
+ if (!vol)
+ continue;
+ umount_by_cdev(&vol->cdev);
+ }
+}
+
/**
* ubi_detach - detach an UBI device
* @ubi_num: The UBI device number
*
+ * UBI volumes used by UBIFS will be unmounted before detaching the
+ * UBI device.
+ *
* @return: 0 for success, negative error code otherwise
*/
int ubi_detach(int ubi_num)
@@ -278,5 +293,7 @@ int ubi_detach(int ubi_num)
if (!ubi)
return -ENOENT;
+ ubi_umount_volumes(ubi);
+
return ubi_detach_mtd_dev(ubi_num, 1);
}
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 6/8] mtd: ubi: Add function to get ubi number from mtd device
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
` (4 preceding siblings ...)
2016-03-15 11:22 ` [PATCH 5/8] mtd: ubi: umount mounted volumes before detaching a ubi device Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
2016-03-15 11:22 ` [PATCH 7/8] commands: ubidetach: Allow mtd devices as argument Sascha Hauer
2016-03-15 11:22 ` [PATCH 8/8] ubiformat: Cleanly umount and detach the ubi before formating Sascha Hauer
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/ubi/barebox.c | 20 ++++++++++++++++++++
include/mtd/ubi-user.h | 1 +
2 files changed, 21 insertions(+)
diff --git a/drivers/mtd/ubi/barebox.c b/drivers/mtd/ubi/barebox.c
index f81705e..c26a245 100644
--- a/drivers/mtd/ubi/barebox.c
+++ b/drivers/mtd/ubi/barebox.c
@@ -297,3 +297,23 @@ int ubi_detach(int ubi_num)
return ubi_detach_mtd_dev(ubi_num, 1);
}
+
+/**
+ * ubi_num_get_by_mtd - find the ubi number to the given mtd
+ * @mtd: the mtd device
+ *
+ * @return: positive or zero for a UBI number, negative error code otherwise
+ */
+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)
+ return ubi->ubi_num;
+ }
+
+ return -ENOENT;
+}
diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h
index 2002548..8c02f96 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(int ubi_num);
+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] 9+ messages in thread
* [PATCH 7/8] commands: ubidetach: Allow mtd devices as argument
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
` (5 preceding siblings ...)
2016-03-15 11:22 ` [PATCH 6/8] mtd: ubi: Add function to get ubi number from mtd device Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
2016-03-15 11:22 ` [PATCH 8/8] ubiformat: Cleanly umount and detach the ubi before formating Sascha Hauer
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
Instead of only allow ubi numbers make it possible to
detach a mtd device.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/ubi.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/commands/ubi.c b/commands/ubi.c
index 8e35787..844d75d 100644
--- a/commands/ubi.c
+++ b/commands/ubi.c
@@ -122,14 +122,36 @@ BAREBOX_CMD_END
static int do_ubidetach(int argc, char *argv[])
{
- int ubi_num, ret;
+ int fd, ret;
+ struct mtd_info_user user;
if (argc != 2)
return COMMAND_ERROR_USAGE;
- ubi_num = simple_strtoul(argv[1], NULL, 0);
- ret = ubi_detach(ubi_num);
+ fd = open(argv[optind], O_RDWR);
+ if (fd < 0) {
+ int ubi_num = simple_strtoul(argv[1], NULL, 0);
+ ret = ubi_detach(ubi_num);
+ goto out;
+ }
+
+ ret = ioctl(fd, MEMGETINFO, &user);
+ if (!ret) {
+ int ubi_num = ubi_num_get_by_mtd(user.mtd);
+ if (ubi_num < 0) {
+ ret = ubi_num;
+ goto out;
+ }
+
+ ret = ubi_detach(ubi_num);
+ if (!ret)
+ goto out_close;
+ }
+
+out_close:
+ close(fd);
+out:
if (ret)
printf("failed to detach: %s\n", strerror(-ret));
@@ -139,7 +161,7 @@ static int do_ubidetach(int argc, char *argv[])
BAREBOX_CMD_START(ubidetach)
.cmd = do_ubidetach,
BAREBOX_CMD_DESC("detach an UBI device")
- BAREBOX_CMD_OPTS("UBINUM")
+ BAREBOX_CMD_OPTS("mtd device/UBINUM")
BAREBOX_CMD_GROUP(CMD_GRP_PART)
BAREBOX_CMD_END
--
2.7.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 8/8] ubiformat: Cleanly umount and detach the ubi before formating
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
` (6 preceding siblings ...)
2016-03-15 11:22 ` [PATCH 7/8] commands: ubidetach: Allow mtd devices as argument Sascha Hauer
@ 2016-03-15 11:22 ` Sascha Hauer
7 siblings, 0 replies; 9+ messages in thread
From: Sascha Hauer @ 2016-03-15 11:22 UTC (permalink / raw)
To: Barebox List
From: Markus Pargmann <mpa@pengutronix.de>
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>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
commands/ubiformat.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/commands/ubiformat.c b/commands/ubiformat.c
index 0172654..2ffdd0c 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>
@@ -562,6 +563,7 @@ int do_ubiformat(int argc, char *argv[])
struct ubigen_info ui;
struct ubi_scan_info *si;
struct mtd_info_user mtd_user;
+ int ubi_num;
err = parse_opt(argc, argv);
if (err)
@@ -622,8 +624,15 @@ 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! */
+ ubi_num = ubi_num_get_by_mtd(mtd_user.mtd);
+ if (ubi_num >= 0) {
+ err = ubi_detach(ubi_num);
+ if (err) {
+ sys_errmsg("Cannot detach %d\n", err);
+ goto out_close;
+ }
+ }
+
eb_cnt = mtd_div_by_eb(mtd->size, mtd);
@@ -759,6 +768,17 @@ int do_ubiformat(int argc, char *argv[])
}
libscan_ubi_scan_free(si);
+
+ /* Reattach the ubi device in case it was attached in the beginning */
+ if (ubi_num >= 0) {
+ err = ubi_attach_mtd_dev(mtd_user.mtd, ubi_num, 0, 20);
+ if (err) {
+ pr_err("Failed to reattach ubi device to ubi number %d, %d\n",
+ ubi_num, 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] 9+ messages in thread
end of thread, other threads:[~2016-03-15 11:23 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-15 11:22 Let ubiformat umount / detach users Sascha Hauer
2016-03-15 11:22 ` [PATCH 1/8] fs: umount based on device path and mount path Sascha Hauer
2016-03-15 11:22 ` [PATCH 2/8] fs: Add for_each_fs_device_safe() Sascha Hauer
2016-03-15 11:22 ` [PATCH 3/8] mtd: ubi: rename cdev.c to barebox.c Sascha Hauer
2016-03-15 11:22 ` [PATCH 4/8] mtd: ubi: make ubi_detach_mtd_dev ubi internal Sascha Hauer
2016-03-15 11:22 ` [PATCH 5/8] mtd: ubi: umount mounted volumes before detaching a ubi device Sascha Hauer
2016-03-15 11:22 ` [PATCH 6/8] mtd: ubi: Add function to get ubi number from mtd device Sascha Hauer
2016-03-15 11:22 ` [PATCH 7/8] commands: ubidetach: Allow mtd devices as argument Sascha Hauer
2016-03-15 11:22 ` [PATCH 8/8] ubiformat: Cleanly umount and detach the ubi before formating Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox