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_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 @@ } 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 @@ } } + 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 @@ 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 11f4535..b9d1e6e 100644 --- a/include/fs.h +++ b/include/fs.h @@ -144,6 +144,7 @@ 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);