diff options
author | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2020-11-09 08:53:15 +0000 |
---|---|---|
committer | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2020-11-09 08:53:15 +0000 |
commit | e3b1c847a4237ad990cab71427927ced34b47507 (patch) | |
tree | 3ca311db88d94e89d783fa9b1a145bd8dbf164b1 /sys/compat/linux/linux_file.c | |
parent | 8b8af16875c788e63523dc574fb2e02b8728c651 (diff) | |
download | src-e3b1c847a4237ad990cab71427927ced34b47507.tar.gz src-e3b1c847a4237ad990cab71427927ced34b47507.zip |
Make it possible to mount a fuse filesystem, such as squashfuse,
from a Linux binary. Should come handy for AppImages.
Reviewed by: asomers
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D26959
Notes
Notes:
svn path=/head/; revision=367517
Diffstat (limited to 'sys/compat/linux/linux_file.c')
-rw-r--r-- | sys/compat/linux/linux_file.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index ebac7f916cd8..70cf0525f194 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -1181,13 +1181,15 @@ linux_pwritev(struct thread *td, struct linux_pwritev_args *uap) int linux_mount(struct thread *td, struct linux_mount_args *args) { - char fstypename[MFSNAMELEN]; - char *mntonname, *mntfromname; + struct mntarg *ma = NULL; + char *fstypename, *mntonname, *mntfromname, *data; int error, fsflags; + fstypename = malloc(MNAMELEN, M_TEMP, M_WAITOK); mntonname = malloc(MNAMELEN, M_TEMP, M_WAITOK); mntfromname = malloc(MNAMELEN, M_TEMP, M_WAITOK); - error = copyinstr(args->filesystemtype, fstypename, MFSNAMELEN - 1, + data = NULL; + error = copyinstr(args->filesystemtype, fstypename, MNAMELEN - 1, NULL); if (error != 0) goto out; @@ -1208,6 +1210,31 @@ linux_mount(struct thread *td, struct linux_mount_args *args) strcpy(fstypename, "linprocfs"); } else if (strcmp(fstypename, "vfat") == 0) { strcpy(fstypename, "msdosfs"); + } else if (strcmp(fstypename, "fuse") == 0) { + char *fuse_options, *fuse_option, *fuse_name; + + if (strcmp(mntfromname, "fuse") == 0) + strcpy(mntfromname, "/dev/fuse"); + + strcpy(fstypename, "fusefs"); + data = malloc(MNAMELEN, M_TEMP, M_WAITOK); + error = copyinstr(args->data, data, MNAMELEN - 1, NULL); + if (error != 0) + goto out; + + fuse_options = data; + while ((fuse_option = strsep(&fuse_options, ",")) != NULL) { + fuse_name = strsep(&fuse_option, "="); + if (fuse_name == NULL || fuse_option == NULL) + goto out; + ma = mount_arg(ma, fuse_name, fuse_option, -1); + } + + /* + * The FUSE server uses Linux errno values instead of FreeBSD + * ones; add a flag to tell fuse(4) to do errno translation. + */ + ma = mount_arg(ma, "linux_errnos", "1", -1); } fsflags = 0; @@ -1225,14 +1252,15 @@ linux_mount(struct thread *td, struct linux_mount_args *args) if (args->rwflag & LINUX_MS_REMOUNT) fsflags |= MNT_UPDATE; - error = kernel_vmount(fsflags, - "fstype", fstypename, - "fspath", mntonname, - "from", mntfromname, - NULL); + ma = mount_arg(ma, "fstype", fstypename, -1); + ma = mount_arg(ma, "fspath", mntonname, -1); + ma = mount_arg(ma, "from", mntfromname, -1); + error = kernel_mount(ma, fsflags); out: + free(fstypename, M_TEMP); free(mntonname, M_TEMP); free(mntfromname, M_TEMP); + free(data, M_TEMP); return (error); } |