]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'fuse-update-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 25 Sep 2019 16:55:59 +0000 (09:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 25 Sep 2019 16:55:59 +0000 (09:55 -0700)
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
  ...

1  2 
fs/namespace.c
fs/super.c
include/linux/fs_context.h

diff --combined fs/namespace.c
index 93c043245c463eb77c4c48316e8ba8ae80f47830,105f995543f6aa1587389b394d0dbf56bdfed19a..b75d458f817de6bea3d15130351940847e0c5145
@@@ -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 8020974b2a685e196d0f7c9077f2c3334e46fbd3,a6ceed7bcd8956f4275b09e3ca18411f48915128..f627b7c53d2b7fefda7546daac7efac40f1a765f
@@@ -32,7 -32,6 +32,7 @@@
  #include <linux/backing-dev.h>
  #include <linux/rculist_bl.h>
  #include <linux/cleancache.h>
 +#include <linux/fscrypt.h>
  #include <linux/fsnotify.h>
  #include <linux/lockdep.h>
  #include <linux/user_namespace.h>
@@@ -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:
                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
index 0424df7f6e6b65b7d0d5a576fa75dddfe0459885,f6c86d58ea91303c363773d677efb3d8adb7d641..e5c14e2c53d351c5496d9be717178295171add9c
@@@ -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),