Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fuse: don't require /dev/fuse fd to be kept open during mount

With the new mount API the sequence of syscalls would be:

fs_fd = fsopen("fuse", 0);
snprintf(opt, sizeof(opt), "%i", devfd);
fsconfig(fs_fd, FSCONFIG_SET_STRING, "fd", opt, 0);
/* ... */
fsconfig(fs_fd, FSCONFIG_CMD_CREATE, 0, 0, 0);

Current mount code just stores the value of devfd in the fs_context and
uses it in during FSCONFIG_CMD_CREATE, which is inelegant.

Instead grab a reference to the underlying fuse_dev, and use that during
the filesystem creation.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

+34 -27
+1 -3
fs/fuse/fuse_i.h
··· 606 606 } 607 607 608 608 struct fuse_fs_context { 609 - int fd; 610 - struct file *file; 609 + struct fuse_dev *fud; 611 610 unsigned int rootmode; 612 611 kuid_t user_id; 613 612 kgid_t group_id; 614 613 bool is_bdev:1; 615 - bool fd_present:1; 616 614 bool rootmode_present:1; 617 615 bool user_id_present:1; 618 616 bool group_id_present:1;
+33 -24
fs/fuse/inode.c
··· 803 803 {} 804 804 }; 805 805 806 + static int fuse_opt_fd(struct fs_context *fsc, int fd) 807 + { 808 + struct fuse_fs_context *ctx = fsc->fs_private; 809 + struct file *file __free(fput) = fget(fd); 810 + 811 + if (!file) 812 + return -EBADF; 813 + 814 + if (file->f_op != &fuse_dev_operations) 815 + return invalfc(fsc, "fd is not a fuse device"); 816 + /* 817 + * Require mount to happen from the same user namespace which 818 + * opened /dev/fuse to prevent potential attacks. 819 + */ 820 + if (file->f_cred->user_ns != fsc->user_ns) 821 + return invalfc(fsc, "wrong user namespace for fuse device"); 822 + 823 + ctx->fud = file->private_data; 824 + refcount_inc(&ctx->fud->ref); 825 + 826 + return 0; 827 + } 828 + 806 829 static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) 807 830 { 808 831 struct fs_parse_result result; ··· 865 842 return 0; 866 843 867 844 case OPT_FD: 868 - ctx->fd = result.uint_32; 869 - ctx->fd_present = true; 870 - break; 845 + return fuse_opt_fd(fsc, result.uint_32); 871 846 872 847 case OPT_ROOTMODE: 873 848 if (!fuse_valid_type(result.uint_32)) ··· 928 907 struct fuse_fs_context *ctx = fsc->fs_private; 929 908 930 909 if (ctx) { 910 + if (ctx->fud) 911 + fuse_dev_put(ctx->fud); 931 912 kfree(ctx->subtype); 932 913 kfree(ctx); 933 914 } ··· 1872 1849 1873 1850 int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) 1874 1851 { 1875 - struct fuse_dev *fud = ctx->file ? fuse_file_to_fud(ctx->file) : NULL; 1852 + struct fuse_dev *fud = ctx->fud; 1876 1853 struct fuse_mount *fm = get_fuse_mount_super(sb); 1877 1854 struct fuse_conn *fc = fm->fc; 1878 1855 struct inode *root; ··· 1973 1950 struct fuse_mount *fm; 1974 1951 int err; 1975 1952 1976 - if (!ctx->file || !ctx->rootmode_present || 1953 + if (!ctx->fud || !ctx->rootmode_present || 1977 1954 !ctx->user_id_present || !ctx->group_id_present) 1978 - return -EINVAL; 1979 - 1980 - /* 1981 - * Require mount to happen from the same user namespace which 1982 - * opened /dev/fuse to prevent potential attacks. 1983 - */ 1984 - if ((ctx->file->f_op != &fuse_dev_operations) || 1985 - (ctx->file->f_cred->user_ns != sb->s_user_ns)) 1986 1955 return -EINVAL; 1987 1956 1988 1957 err = fuse_fill_super_common(sb, ctx); ··· 1997 1982 1998 1983 static int fuse_test_super(struct super_block *sb, struct fs_context *fsc) 1999 1984 { 1985 + struct fuse_dev *fud = fsc->sget_key; 2000 1986 2001 - return fsc->sget_key == get_fuse_conn_super(sb); 1987 + return fuse_dev_fc_get(fud) == get_fuse_conn_super(sb); 2002 1988 } 2003 1989 2004 1990 static int fuse_get_tree(struct fs_context *fsc) 2005 1991 { 2006 1992 struct fuse_fs_context *ctx = fsc->fs_private; 2007 - struct fuse_dev *fud; 2008 1993 struct fuse_conn *fc; 2009 1994 struct fuse_mount *fm; 2010 1995 struct super_block *sb; ··· 2025 2010 2026 2011 fsc->s_fs_info = fm; 2027 2012 2028 - if (ctx->fd_present) 2029 - ctx->file = fget(ctx->fd); 2030 - 2031 2013 if (IS_ENABLED(CONFIG_BLOCK) && ctx->is_bdev) { 2032 2014 err = get_tree_bdev(fsc, fuse_fill_super); 2033 2015 goto out; ··· 2034 2022 * (found by device name), normal fuse mounts can't 2035 2023 */ 2036 2024 err = -EINVAL; 2037 - if (!ctx->file) 2025 + if (!ctx->fud) 2038 2026 goto out; 2039 2027 2040 2028 /* 2041 2029 * Allow creating a fuse mount with an already initialized fuse 2042 2030 * connection 2043 2031 */ 2044 - fud = __fuse_get_dev(ctx->file); 2045 - if (ctx->file->f_op == &fuse_dev_operations && fud) { 2046 - fsc->sget_key = fud->fc; 2032 + if (fuse_dev_fc_get(ctx->fud)) { 2033 + fsc->sget_key = ctx->fud; 2047 2034 sb = sget_fc(fsc, fuse_test_super, fuse_set_no_super); 2048 2035 err = PTR_ERR_OR_ZERO(sb); 2049 2036 if (!IS_ERR(sb)) ··· 2053 2042 out: 2054 2043 if (fsc->s_fs_info) 2055 2044 fuse_mount_destroy(fm); 2056 - if (ctx->file) 2057 - fput(ctx->file); 2058 2045 return err; 2059 2046 } 2060 2047