From: Linus Torvalds Date: Wed, 25 Sep 2019 16:55:59 +0000 (-0700) Subject: Merge tag 'fuse-update-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi... X-Git-Tag: v5.4-rc1~48 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=7b1373dd6e86f3a222590ae404a400e699b32884;hp=-c;p=linux.git Merge tag 'fuse-update-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse Pull fuse updates from Miklos Szeredi: - Continue separating the transport (user/kernel communication) and the filesystem layers of fuse. Getting rid of most layering violations will allow for easier cleanup and optimization later on. - Prepare for the addition of the virtio-fs filesystem. The actual filesystem will be introduced by a separate pull request. - Convert to new mount API. - Various fixes, optimizations and cleanups. * tag 'fuse-update-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: (55 commits) fuse: Make fuse_args_to_req static fuse: fix memleak in cuse_channel_open fuse: fix beyond-end-of-page access in fuse_parse_cache() fuse: unexport fuse_put_request fuse: kmemcg account fs data fuse: on 64-bit store time in d_fsdata directly fuse: fix missing unlock_page in fuse_writepage() fuse: reserve byteswapped init opcodes fuse: allow skipping control interface and forced unmount fuse: dissociate DESTROY from fuseblk fuse: delete dentry if timeout is zero fuse: separate fuse device allocation and installation in fuse_conn fuse: add fuse_iqueue_ops callbacks fuse: extract fuse_fill_super_common() fuse: export fuse_dequeue_forget() function fuse: export fuse_get_unique() fuse: export fuse_send_init_request() fuse: export fuse_len_args() fuse: export fuse_end_request() fuse: fix request limit ... --- 7b1373dd6e86f3a222590ae404a400e699b32884 diff --combined fs/namespace.c index 93c043245c46,105f995543f6..b75d458f817d --- a/fs/namespace.c +++ b/fs/namespace.c @@@ -1643,18 -1643,13 +1643,18 @@@ static inline bool may_mount(void return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN); } +#ifdef CONFIG_MANDATORY_FILE_LOCKING static inline bool may_mandlock(void) { -#ifndef CONFIG_MANDATORY_FILE_LOCKING - return false; -#endif return capable(CAP_SYS_ADMIN); } +#else +static inline bool may_mandlock(void) +{ + pr_warn("VFS: \"mand\" mount option not supported"); + return false; +} +#endif /* * Now umount can handle mount points as well as block devices. @@@ -1680,6 -1675,8 +1680,6 @@@ int ksys_umount(char __user *name, int if (!(flags & UMOUNT_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; - lookup_flags |= LOOKUP_NO_EVAL; - retval = user_path_mountpoint_at(AT_FDCWD, name, lookup_flags, &path); if (retval) goto out; @@@ -2466,26 -2463,6 +2466,26 @@@ static void set_mount_attributes(struc unlock_mount_hash(); } +static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *mnt) +{ + struct super_block *sb = mnt->mnt_sb; + + if (!__mnt_is_readonly(mnt) && + (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) { + char *buf = (char *)__get_free_page(GFP_KERNEL); + char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM); + struct tm tm; + + time64_to_tm(sb->s_time_max, 0, &tm); + + pr_warn("Mounted %s file system at %s supports timestamps until %04ld (0x%llx)\n", + sb->s_type->name, mntpath, + tm.tm_year+1900, (unsigned long long)sb->s_time_max); + + free_page((unsigned long)buf); + } +} + /* * Handle reconfiguration of the mountpoint only without alteration of the * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND @@@ -2511,9 -2488,6 +2511,9 @@@ static int do_reconfigure_mnt(struct pa if (ret == 0) set_mount_attributes(mnt, mnt_flags); up_write(&sb->s_umount); + + mnt_warn_timestamp_expiry(path, &mnt->mnt); + return ret; } @@@ -2554,9 -2528,6 +2554,9 @@@ static int do_remount(struct path *path } up_write(&sb->s_umount); } + + mnt_warn_timestamp_expiry(path, &mnt->mnt); + put_fs_context(fc); return err; } @@@ -2765,13 -2736,8 +2765,13 @@@ static int do_new_mount_fc(struct fs_co return PTR_ERR(mnt); error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags); - if (error < 0) + if (error < 0) { mntput(mnt); + return error; + } + + mnt_warn_timestamp_expiry(mountpoint, mnt); + return error; } @@@ -2802,8 -2768,6 +2802,6 @@@ static int do_new_mount(struct path *pa put_filesystem(type); return -EINVAL; } - } else { - subtype = ""; } } @@@ -3080,7 -3044,7 +3078,7 @@@ long do_mount(const char *dev_name, con return -EINVAL; /* ... and get the mountpoint */ - retval = user_path(dir_name, &path); + retval = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path); if (retval) return retval; @@@ -3627,13 -3591,11 +3625,13 @@@ SYSCALL_DEFINE2(pivot_root, const char if (!may_mount()) return -EPERM; - error = user_path_dir(new_root, &new); + error = user_path_at(AT_FDCWD, new_root, + LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &new); if (error) goto out0; - error = user_path_dir(put_old, &old); + error = user_path_at(AT_FDCWD, put_old, + LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old); if (error) goto out1; diff --combined fs/super.c index 8020974b2a68,a6ceed7bcd89..f627b7c53d2b --- a/fs/super.c +++ b/fs/super.c @@@ -32,7 -32,6 +32,7 @@@ #include #include #include +#include #include #include #include @@@ -258,8 -257,6 +258,8 @@@ static struct super_block *alloc_super( s->s_maxbytes = MAX_NON_LFS; s->s_op = &default_op; s->s_time_gran = 1000000000; + s->s_time_min = TIME64_MIN; + s->s_time_max = TIME64_MAX; s->cleancache_poolid = CLEANCACHE_NO_POOL; s->s_shrink.seeks = DEFAULT_SEEKS; @@@ -293,7 -290,6 +293,7 @@@ static void __put_super(struct super_bl WARN_ON(s->s_inode_lru.node); WARN_ON(!list_empty(&s->s_mounts)); security_sb_free(s); + fscrypt_sb_free(s); put_user_ns(s->s_user_ns); kfree(s->s_subtype); call_rcu(&s->rcu, destroy_super_rcu); @@@ -1164,11 -1160,9 +1164,11 @@@ int vfs_get_super(struct fs_context *fc { int (*test)(struct super_block *, struct fs_context *); struct super_block *sb; + int err; switch (keying) { case vfs_get_single_super: + case vfs_get_single_reconf_super: test = test_single_super; break; case vfs_get_keyed_super: @@@ -1186,29 -1180,18 +1186,29 @@@ return PTR_ERR(sb); if (!sb->s_root) { - int err = fill_super(sb, fc); - if (err) { - deactivate_locked_super(sb); - return err; - } + err = fill_super(sb, fc); + if (err) + goto error; sb->s_flags |= SB_ACTIVE; + fc->root = dget(sb->s_root); + } else { + fc->root = dget(sb->s_root); + if (keying == vfs_get_single_reconf_super) { + err = reconfigure_super(fc); + if (err < 0) { + dput(fc->root); + fc->root = NULL; + goto error; + } + } } - BUG_ON(fc->root); - fc->root = dget(sb->s_root); return 0; + +error: + deactivate_locked_super(sb); + return err; } EXPORT_SYMBOL(vfs_get_super); @@@ -1228,14 -1211,6 +1228,14 @@@ int get_tree_single(struct fs_context * } EXPORT_SYMBOL(get_tree_single); +int get_tree_single_reconf(struct fs_context *fc, + int (*fill_super)(struct super_block *sb, + struct fs_context *fc)) +{ + return vfs_get_super(fc, vfs_get_single_reconf_super, fill_super); +} +EXPORT_SYMBOL(get_tree_single_reconf); + int get_tree_keyed(struct fs_context *fc, int (*fill_super)(struct super_block *sb, struct fs_context *fc), @@@ -1555,11 -1530,6 +1555,6 @@@ int vfs_get_tree(struct fs_context *fc sb = fc->root->d_sb; WARN_ON(!sb->s_bdi); - if (fc->subtype && !sb->s_subtype) { - sb->s_subtype = fc->subtype; - fc->subtype = NULL; - } - /* * Write barrier is for super_cache_count(). We place it before setting * SB_BORN as the data dependency between the two functions is the diff --combined include/linux/fs_context.h index 0424df7f6e6b,f6c86d58ea91..e5c14e2c53d3 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h @@@ -95,7 -95,6 +95,6 @@@ struct fs_context const struct cred *cred; /* The mounter's credentials */ struct fc_log *log; /* Logging buffer */ const char *source; /* The source name (eg. dev path) */ - const char *subtype; /* The subtype to set on the superblock */ void *security; /* Linux S&M options */ void *s_fs_info; /* Proposed s_fs_info */ unsigned int sb_flags; /* Proposed superblock flags (SB_*) */ @@@ -141,7 -140,6 +140,7 @@@ extern void put_fs_context(struct fs_co */ enum vfs_get_super_keying { vfs_get_single_super, /* Only one such superblock may exist */ + vfs_get_single_reconf_super, /* As above, but reconfigure if it exists */ vfs_get_keyed_super, /* Superblocks with different s_fs_info keys may exist */ vfs_get_independent_super, /* Multiple independent superblocks may exist */ }; @@@ -156,9 -154,6 +155,9 @@@ extern int get_tree_nodev(struct fs_con extern int get_tree_single(struct fs_context *fc, int (*fill_super)(struct super_block *sb, struct fs_context *fc)); +extern int get_tree_single_reconf(struct fs_context *fc, + int (*fill_super)(struct super_block *sb, + struct fs_context *fc)); extern int get_tree_keyed(struct fs_context *fc, int (*fill_super)(struct super_block *sb, struct fs_context *fc),