From ecb3aaa23b09c41f2ac8364f5ca72779467762e3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 27 Sep 2013 22:47:10 +0200 Subject: fs: cleanup backingstore handling All filesystem drivers which need a backingstore device do the same ignoring of '/dev/' in the backingstore followed by a cdev_open. Add a helper function for it and let the core handle the cdev. As a side effect this makes sure that fsdev->cdev is also set when a device is mounted without the leading '/dev/' which was previously ignored by the mount code. Signed-off-by: Sascha Hauer --- fs/cramfs/cramfs.c | 18 +++++++++++------- fs/ext4/ext_barebox.c | 14 ++++---------- fs/fat/fat.c | 17 ++++------------- fs/fs.c | 28 ++++++++++++++++++++-------- fs/ubifs/ubifs.c | 16 ++++++---------- 5 files changed, 45 insertions(+), 48 deletions(-) (limited to 'fs') diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index 99f6d49c2c..8218fcf2af 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -422,29 +422,33 @@ static int cramfs_probe(struct device_d *dev) { struct fs_device_d *fsdev; struct cramfs_priv *priv; + int ret; fsdev = dev_to_fs_device(dev); priv = xmalloc(sizeof(struct cramfs_priv)); dev->priv = priv; - if (strncmp(fsdev->backingstore, "/dev/", 5)) - return -ENODEV; + ret = fsdev_open_cdev(fsdev); + if (ret) + goto err_out; - priv->cdev = cdev_by_name(fsdev->backingstore + 5); - if (!priv->cdev) - return -ENODEV; + priv->cdev = fsdev->cdev; if (cramfs_read_super(priv)) { dev_info(dev, "no valid cramfs found\n"); - free(priv); - return -EINVAL; + ret = -EINVAL; } priv->curr_base = -1; cramfs_uncompress_init (); return 0; + +err_out: + free(priv); + + return ret; } static void cramfs_remove(struct device_d *dev) diff --git a/fs/ext4/ext_barebox.c b/fs/ext4/ext_barebox.c index adc8f758e0..69a7723b5c 100644 --- a/fs/ext4/ext_barebox.c +++ b/fs/ext4/ext_barebox.c @@ -225,7 +225,6 @@ static int ext_readlink(struct device_d *dev, const char *pathname, static int ext_probe(struct device_d *dev) { struct fs_device_d *fsdev = dev_to_fs_device(dev); - char *backingstore = fsdev->backingstore; int ret; struct ext_filesystem *fs; @@ -234,14 +233,11 @@ static int ext_probe(struct device_d *dev) dev->priv = fs; fs->dev = dev; - if (!strncmp(backingstore , "/dev/", 5)) - backingstore += 5; - - fs->cdev = cdev_open(backingstore, O_RDWR); - if (!fs->cdev) { - ret = -ENOENT; + ret = fsdev_open_cdev(fsdev); + if (ret) goto err_open; - } + + fs->cdev = fsdev->cdev; ret = ext4fs_mount(fs); if (ret) @@ -250,7 +246,6 @@ static int ext_probe(struct device_d *dev) return 0; err_mount: - cdev_close(fs->cdev); err_open: free(fs); @@ -262,7 +257,6 @@ static void ext_remove(struct device_d *dev) struct ext_filesystem *fs = dev->priv; ext4fs_umount(fs); - cdev_close(fs->cdev); free(fs); } diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 15879c4160..e65ef585a2 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -373,19 +373,15 @@ static int fat_probe(struct device_d *dev) { struct fs_device_d *fsdev = dev_to_fs_device(dev); struct fat_priv *priv = xzalloc(sizeof(struct fat_priv)); - char *backingstore = fsdev->backingstore; int ret; dev->priv = priv; - if (!strncmp(backingstore , "/dev/", 5)) - backingstore += 5; - - priv->cdev = cdev_open(backingstore, O_RDWR); - if (!priv->cdev) { - ret = -ENOENT; + ret = fsdev_open_cdev(fsdev); + if (ret) goto err_open; - } + + priv->cdev = fsdev->cdev; priv->fat.userdata = priv; ret = f_mount(&priv->fat); @@ -395,7 +391,6 @@ static int fat_probe(struct device_d *dev) return 0; err_mount: - cdev_close(priv->cdev); err_open: free(priv); @@ -404,10 +399,6 @@ err_open: static void fat_remove(struct device_d *dev) { - struct fat_priv *priv = dev->priv; - - cdev_close(priv->cdev); - free(dev->priv); } diff --git a/fs/fs.c b/fs/fs.c index d913a503f2..4618b4fdcc 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -1231,6 +1231,9 @@ static void fs_remove(struct device_d *dev) if (fsdev == fs_dev_root) fs_dev_root = NULL; + if (fsdev->cdev) + cdev_close(fsdev->cdev); + free(fsdev->backingstore); free(fsdev); } @@ -1279,6 +1282,23 @@ static const char *detect_fs(const char *filename) return NULL; } +int fsdev_open_cdev(struct fs_device_d *fsdev) +{ + const char *backingstore = fsdev->backingstore; + + if (!strncmp(backingstore , "/dev/", 5)) + backingstore += 5; + + fsdev->cdev = cdev_open(backingstore, O_RDWR); + if (!fsdev->cdev) + return -EINVAL; + + fsdev->dev.parent = fsdev->cdev->dev; + fsdev->parent_device = fsdev->cdev->dev; + + return 0; +} + /* * Mount a device to a directory. * We do this by registering a new device on which the filesystem @@ -1323,14 +1343,6 @@ int mount(const char *device, const char *fsname, const char *_path) fsdev->path = xstrdup(path); fsdev->dev.bus = &fs_bus; - if (!strncmp(device, "/dev/", 5)) - fsdev->cdev = cdev_by_name(device + 5); - - if (fsdev->cdev) { - fsdev->dev.parent = fsdev->cdev->dev; - fsdev->parent_device = fsdev->cdev->dev; - } - ret = register_device(&fsdev->dev); if (ret) goto err_register; diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c index 9df8dc5cbd..dfa6107458 100644 --- a/fs/ubifs/ubifs.c +++ b/fs/ubifs/ubifs.c @@ -553,25 +553,22 @@ static int ubifs_probe(struct device_d *dev) { struct fs_device_d *fsdev = dev_to_fs_device(dev); struct ubifs_priv *priv = xzalloc(sizeof(struct ubifs_priv)); - char *backingstore = fsdev->backingstore; int ret; dev->priv = priv; - if (!strncmp(backingstore , "/dev/", 5)) - backingstore += 5; - - priv->cdev = cdev_open(backingstore, O_RDONLY); - if (!priv->cdev) { - ret = -ENOENT; + ret = fsdev_open_cdev(fsdev); + if (ret) goto err_free; - } + + priv->cdev = fsdev->cdev; priv->ubi = ubi_open_volume_cdev(priv->cdev, UBI_READONLY); if (IS_ERR(priv->ubi)) { dev_err(dev, "failed to open ubi volume: %s\n", strerror(-PTR_ERR(priv->ubi))); - return PTR_ERR(priv->ubi); + ret = PTR_ERR(priv->ubi); + goto err_free; } priv->sb = ubifs_get_super(priv->ubi, 0); @@ -596,7 +593,6 @@ static void ubifs_remove(struct device_d *dev) ubifs_umount(c); ubi_close_volume(priv->ubi); - cdev_close(priv->cdev); free(c); free(sb); -- cgit v1.2.3 From 3b0a637921919bff1dfda6c1e204c6b30f6e8ca3 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 27 Sep 2013 23:00:45 +0200 Subject: fs: use bus_for_each_driver Instead of using for_each_driver and testing for the bus type. Signed-off-by: Sascha Hauer --- fs/fs.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/fs.c b/fs/fs.c index 4618b4fdcc..3434134e9d 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -1269,10 +1269,7 @@ static const char *detect_fs(const char *filename) if (type == filetype_unknown) return NULL; - for_each_driver(drv) { - if (drv->bus != &fs_bus) - continue; - + bus_for_each_driver(&fs_bus, drv) { fdrv = drv_to_fs_driver(drv); if (type == fdrv->type) -- cgit v1.2.3 From cd1622738337b5564cc4d2b8f99832fb50bdeb06 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 28 Sep 2013 00:02:39 +0200 Subject: fs: add cdev mount helpers Introduce helpers to iterate over cdevs and mount them to a known path. Signed-off-by: Sascha Hauer --- fs/fs.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ include/fs.h | 3 +++ 2 files changed, 83 insertions(+) (limited to 'fs') diff --git a/fs/fs.c b/fs/fs.c index 3434134e9d..ce7b425546 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -32,6 +32,7 @@ #include #include #include +#include void *read_file(const char *filename, size_t *size) { @@ -1670,3 +1671,82 @@ ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, loff_t offse return size; } EXPORT_SYMBOL(mem_write); + +/* + * cdev_get_mount_path - return the path a cdev is mounted on + * + * If a cdev is mounted return the path it's mounted on, NULL + * otherwise. + */ +const char *cdev_get_mount_path(struct cdev *cdev) +{ + struct fs_device_d *fsdev; + + for_each_fs_device(fsdev) { + if (fsdev->cdev && fsdev->cdev == cdev) + return fsdev->path; + } + + return NULL; +} + +/* + * cdev_mount_default - mount a cdev to the default path + * + * If a cdev is already mounted return the path it's mounted on, otherwise + * mount it to /mnt/ and return the path. Returns an error pointer + * on failure. + */ +const char *cdev_mount_default(struct cdev *cdev) +{ + const char *path; + char *newpath, *devpath; + int ret; + + /* + * If this cdev is already mounted somewhere use this path + * instead of mounting it again to avoid corruption on the + * filesystem. + */ + path = cdev_get_mount_path(cdev); + if (path) + return path; + + newpath = asprintf("/mnt/%s", cdev->name); + make_directory(newpath); + + devpath = asprintf("/dev/%s", cdev->name); + + ret = mount(devpath, NULL, newpath); + + free(devpath); + + if (ret) { + free(newpath); + return ERR_PTR(ret); + } + + return cdev_get_mount_path(cdev); +} + +/* + * mount_all - iterate over block devices and mount all devices we are able to + */ +void mount_all(void) +{ + struct device_d *dev; + struct block_device *bdev; + + if (!IS_ENABLED(CONFIG_BLOCK)) + return; + + for_each_device(dev) + device_detect(dev); + + for_each_block_device(bdev) { + struct cdev *cdev = &bdev->cdev; + + list_for_each_entry(cdev, &bdev->dev->cdevs, devices_list) + cdev_mount_default(cdev); + } +} diff --git a/include/fs.h b/include/fs.h index 5b4ad6f855..99f1689835 100644 --- a/include/fs.h +++ b/include/fs.h @@ -194,5 +194,8 @@ void automount_print(void); int unlink_recursive(const char *path, char **failedpath); int fsdev_open_cdev(struct fs_device_d *fsdev); +const char *cdev_get_mount_path(struct cdev *cdev); +const char *cdev_mount_default(struct cdev *cdev); +void mount_all(void); #endif /* __FS_H */ -- cgit v1.2.3