* [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 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