From 85dffaacfa3c7eedc8fc8ea12da27a19720e2483 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 9 May 2017 07:38:34 +0200 Subject: fs: Create automount entries for the default mount pathes In barebox the default mount path for a cdev is /mnt/ which can be mounted with "mount " without specifying a target path explicitly. Simplify this further by creating automount entries for the default mount pathes which makes a manual mount completely unnecessary. Signed-off-by: Sascha Hauer --- include/driver.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/driver.h b/include/driver.h index 52e06f7d62..b743ed8b77 100644 --- a/include/driver.h +++ b/include/driver.h @@ -490,6 +490,14 @@ struct cdev *devfs_add_partition(const char *devname, loff_t offset, loff_t size, unsigned int flags, const char *name); int devfs_del_partition(const char *name); +#ifdef CONFIG_FS_AUTOMOUNT +void cdev_create_default_automount(struct cdev *cdev); +#else +static inline void cdev_create_default_automount(struct cdev *cdev) +{ +} +#endif + #define DEVFS_PARTITION_APPEND 0 /** -- cgit v1.2.3 From f6652e7404ba4f10923227c75da4db4c86b1275e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 17 May 2017 14:24:21 +0100 Subject: commands: allow _aliases[] to be const Commands with aliases define an array of alias strings such as: static const char *_aliases[] = { "", NULL}; Although the elements are of type `const char *`, the elements themselves are not `const`-qualified. If the array is declared as: static const char * const _aliases[] = { "", NULL}; then the compiler warns about const qualifiers being discarded. This is because the `aliases` member of `struct command` is declared as `const char *aliases;`. Change the declaration of the `aliases` member of `struct command` to `const char * const *aliases;` so that it can point to a `const` array of `const char *`. Also change the declaration of the `aliases` variable in `register_command()` to avoid unnecessary type casts. Signed-off-by: Ian Abbott Signed-off-by: Sascha Hauer --- common/command.c | 2 +- include/command.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/common/command.c b/common/command.c index 03c70834d1..d9cc4a6d48 100644 --- a/common/command.c +++ b/common/command.c @@ -104,7 +104,7 @@ int register_command(struct command *cmd) list_add_sort(&cmd->list, &command_list, compare); if (cmd->aliases) { - char **aliases = (char**)cmd->aliases; + const char * const *aliases = cmd->aliases; while(*aliases) { struct command *c = xzalloc(sizeof(struct command)); diff --git a/include/command.h b/include/command.h index 43ee454f22..0afc5c7550 100644 --- a/include/command.h +++ b/include/command.h @@ -40,7 +40,7 @@ struct string_list; */ struct command { const char *name; /* Command Name */ - const char **aliases; + const char * const *aliases; /* Implementation function */ int (*cmd)(int, char *[]); int (*complete)(struct string_list *sl, char *instr); -- cgit v1.2.3 From 46188f4174ff4f1e0f6da76cfcf06521b6350794 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Tue, 30 May 2017 16:09:43 +0200 Subject: cdev: make file operations const scripts/checkpatch.pl warns that struct file_operations should be const, but cdev->ops is not const, so without this patch we can choose between a warning from checkpatch and a warning from the compiler about discarding the const attribute when assigning the struct file_operations cdev->ops. Since there is no reason to modify the contents of cdev->ops after probing, make it const. Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer --- include/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/driver.h b/include/driver.h index b743ed8b77..1edc1575c8 100644 --- a/include/driver.h +++ b/include/driver.h @@ -440,7 +440,7 @@ struct file_operations { #define MAX_PARTUUID_STR sizeof("00112233-4455-6677-8899-AABBCCDDEEFF") struct cdev { - struct file_operations *ops; + const struct file_operations *ops; void *priv; struct device_d *dev; struct device_node *device_node; -- cgit v1.2.3 From f3cd5b1bbcb27108496eb572ae2ff7cd526ddc55 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 1 Jun 2017 12:37:29 +0200 Subject: fs: add cdev_create_loop and cdev_remove_loop for loop mount option Allow to create a loopback cdev from a file. Signed-off-by: Philipp Zabel Signed-off-by: Sascha Hauer Fixed up with: fs: Makefile: Add parseopt to all builds parseopt.h was included to fs.c with commit 9248b, but parseopt.o has a dependency to CONFIG_FS_NFS. Moved parseopt.o to the default build to eliminate build failures. Signed-off-by: Daniel Schultz Signed-off-by: Sascha Hauer --- fs/Makefile | 4 +-- fs/devfs-core.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/fs.c | 22 +++++++++++--- include/driver.h | 2 ++ include/fs.h | 1 + 5 files changed, 113 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/fs/Makefile b/fs/Makefile index f2bb702851..b3f929f506 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -4,11 +4,11 @@ obj-$(CONFIG_FS_RAMFS) += ramfs.o obj-y += devfs-core.o obj-$(CONFIG_FS_DEVFS) += devfs.o obj-$(CONFIG_FS_FAT) += fat/ -obj-y += fs.o +obj-y += fs.o parseopt.o obj-$(CONFIG_FS_UBIFS) += ubifs/ obj-$(CONFIG_FS_TFTP) += tftp.o obj-$(CONFIG_FS_OMAP4_USBBOOT) += omap4_usbbootfs.o -obj-$(CONFIG_FS_NFS) += nfs.o parseopt.o +obj-$(CONFIG_FS_NFS) += nfs.o obj-$(CONFIG_FS_BPKFS) += bpkfs.o obj-$(CONFIG_FS_UIMAGEFS) += uimagefs.o obj-$(CONFIG_FS_EFI) += efi.o diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 26fffbb6c2..3368d3ed68 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -20,11 +20,14 @@ #include #include #include +#include #include #include #include #include +#include #include +#include LIST_HEAD(cdev_list); @@ -409,3 +412,90 @@ int devfs_create_partitions(const char *devname, return 0; } + +struct loop_priv { + int fd; +}; + +static ssize_t loop_read(struct cdev *cdev, void *buf, size_t count, + loff_t offset, ulong flags) +{ + struct loop_priv *priv = cdev->priv; + loff_t ofs; + + ofs = lseek(priv->fd, offset, SEEK_SET); + if (ofs < 0) + return ofs; + + return read(priv->fd, buf, count); +} + +static ssize_t loop_write(struct cdev *cdev, const void *buf, size_t count, + loff_t offset, ulong flags) +{ + struct loop_priv *priv = cdev->priv; + loff_t ofs; + + ofs = lseek(priv->fd, offset, SEEK_SET); + if (ofs < 0) + return ofs; + + return write(priv->fd, buf, count); +} + +static const struct file_operations loop_ops = { + .read = loop_read, + .write = loop_write, + .memmap = generic_memmap_rw, + .lseek = dev_lseek_default, +}; + +struct cdev *cdev_create_loop(const char *path, ulong flags) +{ + struct cdev *new; + struct loop_priv *priv; + static int loopno; + loff_t ofs; + + priv = xzalloc(sizeof(*priv)); + + priv->fd = open(path, flags); + if (priv->fd < 0) { + free(priv); + return NULL; + } + + new = xzalloc(sizeof(*new)); + + new->ops = &loop_ops; + new->name = basprintf("loop%u", loopno++); + new->priv = priv; + + ofs = lseek(priv->fd, 0, SEEK_END); + if (ofs < 0) { + free(new); + free(priv); + return NULL; + } + lseek(priv->fd, 0, SEEK_SET); + + new->size = ofs; + new->offset = 0; + new->dev = NULL; + new->flags = 0; + + devfs_create(new); + + return new; +} + +void cdev_remove_loop(struct cdev *cdev) +{ + struct loop_priv *priv = cdev->priv; + + devfs_remove(cdev); + close(priv->fd); + free(priv); + free(cdev->name); + free(cdev); +} diff --git a/fs/fs.c b/fs/fs.c index 9a5887f580..6081596b85 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -36,6 +36,8 @@ #include #include +#include "parseopt.h" + char *mkmodestr(unsigned long mode, char *str) { static const char *l = "xwr"; @@ -1210,6 +1212,9 @@ static void fs_remove(struct device_d *dev) if (fsdev->cdev) cdev_close(fsdev->cdev); + if (fsdev->loop) + cdev_remove_loop(fsdev->cdev); + free(fsdev->backingstore); free(fsdev); } @@ -1236,13 +1241,18 @@ int register_fs_driver(struct fs_driver_d *fsdrv) } EXPORT_SYMBOL(register_fs_driver); -static const char *detect_fs(const char *filename) +static const char *detect_fs(const char *filename, const char *fsoptions) { enum filetype type; struct driver_d *drv; struct fs_driver_d *fdrv; + bool loop; - type = cdev_detect_type(filename); + parseopt_b(fsoptions, "loop", &loop); + if (loop) + type = file_name_detect_type(filename); + else + type = cdev_detect_type(filename); if (type == filetype_unknown) return NULL; @@ -1259,7 +1269,11 @@ static const char *detect_fs(const char *filename) int fsdev_open_cdev(struct fs_device_d *fsdev) { - fsdev->cdev = cdev_open(fsdev->backingstore, O_RDWR); + parseopt_b(fsdev->options, "loop", &fsdev->loop); + if (fsdev->loop) + fsdev->cdev = cdev_create_loop(fsdev->backingstore, O_RDWR); + else + fsdev->cdev = cdev_open(fsdev->backingstore, O_RDWR); if (!fsdev->cdev) return -EINVAL; @@ -1306,7 +1320,7 @@ int mount(const char *device, const char *fsname, const char *_path, } if (!fsname) - fsname = detect_fs(device); + fsname = detect_fs(device, fsoptions); if (!fsname) return -ENOENT; diff --git a/include/driver.h b/include/driver.h index 1edc1575c8..3d701f2439 100644 --- a/include/driver.h +++ b/include/driver.h @@ -473,6 +473,8 @@ struct cdev *lcdev_by_name(const char *filename); struct cdev *cdev_readlink(struct cdev *cdev); struct cdev *cdev_by_device_node(struct device_node *node); struct cdev *cdev_open(const char *name, unsigned long flags); +struct cdev *cdev_create_loop(const char *path, ulong flags); +void cdev_remove_loop(struct cdev *cdev); int cdev_do_open(struct cdev *, unsigned long flags); void cdev_close(struct cdev *cdev); int cdev_flush(struct cdev *cdev); diff --git a/include/fs.h b/include/fs.h index 6a592893a9..1b40ff55fe 100644 --- a/include/fs.h +++ b/include/fs.h @@ -92,6 +92,7 @@ struct fs_device_d { struct fs_driver_d *driver; struct cdev *cdev; + bool loop; char *path; struct device_d *parent_device; struct list_head list; -- cgit v1.2.3