]> Git Repo - linux.git/commitdiff
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <[email protected]>
Wed, 10 Jun 2020 23:09:11 +0000 (16:09 -0700)
committerLinus Torvalds <[email protected]>
Wed, 10 Jun 2020 23:09:11 +0000 (16:09 -0700)
Pull vfs fixes from Al Viro:
 "A couple of trivial patches that fell through the cracks last cycle"

* 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fs: fix indentation in deactivate_super()
  vfs: Remove duplicated d_mountpoint check in __is_local_mountpoint

1  2 
fs/namespace.c
fs/super.c

diff --combined fs/namespace.c
index 7cd642409165738e59c97e9942fee19ad42d52fc,e6aed405611da3cccd359bdc545092d26765a393..f30ed401cc6d7a824ad5b19b21459cdfd3f0435f
@@@ -648,21 -648,6 +648,21 @@@ struct vfsmount *lookup_mnt(const struc
        return m;
  }
  
 +static inline void lock_ns_list(struct mnt_namespace *ns)
 +{
 +      spin_lock(&ns->ns_lock);
 +}
 +
 +static inline void unlock_ns_list(struct mnt_namespace *ns)
 +{
 +      spin_unlock(&ns->ns_lock);
 +}
 +
 +static inline bool mnt_is_cursor(struct mount *mnt)
 +{
 +      return mnt->mnt.mnt_flags & MNT_CURSOR;
 +}
 +
  /*
   * __is_local_mountpoint - Test to see if dentry is a mountpoint in the
   *                         current mount namespace.
@@@ -684,21 -669,14 +684,18 @@@ bool __is_local_mountpoint(struct dentr
        struct mount *mnt;
        bool is_covered = false;
  
-       if (!d_mountpoint(dentry))
-               goto out;
        down_read(&namespace_sem);
 +      lock_ns_list(ns);
        list_for_each_entry(mnt, &ns->list, mnt_list) {
 +              if (mnt_is_cursor(mnt))
 +                      continue;
                is_covered = (mnt->mnt_mountpoint == dentry);
                if (is_covered)
                        break;
        }
 +      unlock_ns_list(ns);
        up_read(&namespace_sem);
- out:
        return is_covered;
  }
  
@@@ -1264,71 -1242,46 +1261,71 @@@ struct vfsmount *mnt_clone_internal(con
  }
  
  #ifdef CONFIG_PROC_FS
 +static struct mount *mnt_list_next(struct mnt_namespace *ns,
 +                                 struct list_head *p)
 +{
 +      struct mount *mnt, *ret = NULL;
 +
 +      lock_ns_list(ns);
 +      list_for_each_continue(p, &ns->list) {
 +              mnt = list_entry(p, typeof(*mnt), mnt_list);
 +              if (!mnt_is_cursor(mnt)) {
 +                      ret = mnt;
 +                      break;
 +              }
 +      }
 +      unlock_ns_list(ns);
 +
 +      return ret;
 +}
 +
  /* iterator; we want it to have access to namespace_sem, thus here... */
  static void *m_start(struct seq_file *m, loff_t *pos)
  {
        struct proc_mounts *p = m->private;
 +      struct list_head *prev;
  
        down_read(&namespace_sem);
 -      if (p->cached_event == p->ns->event) {
 -              void *v = p->cached_mount;
 -              if (*pos == p->cached_index)
 -                      return v;
 -              if (*pos == p->cached_index + 1) {
 -                      v = seq_list_next(v, &p->ns->list, &p->cached_index);
 -                      return p->cached_mount = v;
 -              }
 +      if (!*pos) {
 +              prev = &p->ns->list;
 +      } else {
 +              prev = &p->cursor.mnt_list;
 +
 +              /* Read after we'd reached the end? */
 +              if (list_empty(prev))
 +                      return NULL;
        }
  
 -      p->cached_event = p->ns->event;
 -      p->cached_mount = seq_list_start(&p->ns->list, *pos);
 -      p->cached_index = *pos;
 -      return p->cached_mount;
 +      return mnt_list_next(p->ns, prev);
  }
  
  static void *m_next(struct seq_file *m, void *v, loff_t *pos)
  {
        struct proc_mounts *p = m->private;
 +      struct mount *mnt = v;
  
 -      p->cached_mount = seq_list_next(v, &p->ns->list, pos);
 -      p->cached_index = *pos;
 -      return p->cached_mount;
 +      ++*pos;
 +      return mnt_list_next(p->ns, &mnt->mnt_list);
  }
  
  static void m_stop(struct seq_file *m, void *v)
  {
 +      struct proc_mounts *p = m->private;
 +      struct mount *mnt = v;
 +
 +      lock_ns_list(p->ns);
 +      if (mnt)
 +              list_move_tail(&p->cursor.mnt_list, &mnt->mnt_list);
 +      else
 +              list_del_init(&p->cursor.mnt_list);
 +      unlock_ns_list(p->ns);
        up_read(&namespace_sem);
  }
  
  static int m_show(struct seq_file *m, void *v)
  {
        struct proc_mounts *p = m->private;
 -      struct mount *r = list_entry(v, struct mount, mnt_list);
 +      struct mount *r = v;
        return p->show(m, &r->mnt);
  }
  
@@@ -1338,15 -1291,6 +1335,15 @@@ const struct seq_operations mounts_op 
        .stop   = m_stop,
        .show   = m_show,
  };
 +
 +void mnt_cursor_del(struct mnt_namespace *ns, struct mount *cursor)
 +{
 +      down_read(&namespace_sem);
 +      lock_ns_list(ns);
 +      list_del(&cursor->mnt_list);
 +      unlock_ns_list(ns);
 +      up_read(&namespace_sem);
 +}
  #endif  /* CONFIG_PROC_FS */
  
  /**
@@@ -1786,11 -1730,6 +1783,11 @@@ static struct mnt_namespace *to_mnt_ns(
        return container_of(ns, struct mnt_namespace, ns);
  }
  
 +struct ns_common *from_mnt_ns(struct mnt_namespace *mnt)
 +{
 +      return &mnt->ns;
 +}
 +
  static bool mnt_ns_loop(struct dentry *dentry)
  {
        /* Could bind mounting the mount namespace inode cause a
@@@ -1937,9 -1876,6 +1934,9 @@@ struct vfsmount *clone_private_mount(co
        if (IS_ERR(new_mnt))
                return ERR_CAST(new_mnt);
  
 +      /* Longterm mount to be removed by kern_unmount*() */
 +      new_mnt->mnt_ns = MNT_NS_INTERNAL;
 +
        return &new_mnt->mnt;
  }
  EXPORT_SYMBOL_GPL(clone_private_mount);
@@@ -3263,7 -3199,6 +3260,7 @@@ static struct mnt_namespace *alloc_mnt_
        atomic_set(&new_ns->count, 1);
        INIT_LIST_HEAD(&new_ns->list);
        init_waitqueue_head(&new_ns->poll);
 +      spin_lock_init(&new_ns->ns_lock);
        new_ns->user_ns = get_user_ns(user_ns);
        new_ns->ucounts = ucounts;
        return new_ns;
@@@ -3657,7 -3592,7 +3654,7 @@@ EXPORT_SYMBOL(path_is_under)
   * file system may be mounted on put_old. After all, new_root is a mountpoint.
   *
   * Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem.
 - * See Documentation/filesystems/ramfs-rootfs-initramfs.txt for alternatives
 + * See Documentation/filesystems/ramfs-rootfs-initramfs.rst for alternatives
   * in this situation.
   *
   * Notes:
@@@ -3866,19 -3801,6 +3863,19 @@@ void kern_unmount(struct vfsmount *mnt
  }
  EXPORT_SYMBOL(kern_unmount);
  
 +void kern_unmount_array(struct vfsmount *mnt[], unsigned int num)
 +{
 +      unsigned int i;
 +
 +      for (i = 0; i < num; i++)
 +              if (mnt[i])
 +                      real_mount(mnt[i])->mnt_ns = NULL;
 +      synchronize_rcu_expedited();
 +      for (i = 0; i < num; i++)
 +              mntput(mnt[i]);
 +}
 +EXPORT_SYMBOL(kern_unmount_array);
 +
  bool our_mnt(struct vfsmount *mnt)
  {
        return check_mnt(real_mount(mnt));
@@@ -3917,14 -3839,10 +3914,14 @@@ static bool mnt_already_visible(struct 
        bool visible = false;
  
        down_read(&namespace_sem);
 +      lock_ns_list(ns);
        list_for_each_entry(mnt, &ns->list, mnt_list) {
                struct mount *child;
                int mnt_flags;
  
 +              if (mnt_is_cursor(mnt))
 +                      continue;
 +
                if (mnt->mnt.mnt_sb->s_type != sb->s_type)
                        continue;
  
        next:   ;
        }
  found:
 +      unlock_ns_list(ns);
        up_read(&namespace_sem);
        return visible;
  }
@@@ -4034,18 -3951,16 +4031,18 @@@ static void mntns_put(struct ns_common 
        put_mnt_ns(to_mnt_ns(ns));
  }
  
 -static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns)
 +static int mntns_install(struct nsset *nsset, struct ns_common *ns)
  {
 -      struct fs_struct *fs = current->fs;
 +      struct nsproxy *nsproxy = nsset->nsproxy;
 +      struct fs_struct *fs = nsset->fs;
        struct mnt_namespace *mnt_ns = to_mnt_ns(ns), *old_mnt_ns;
 +      struct user_namespace *user_ns = nsset->cred->user_ns;
        struct path root;
        int err;
  
        if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
 -          !ns_capable(current_user_ns(), CAP_SYS_CHROOT) ||
 -          !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
 +          !ns_capable(user_ns, CAP_SYS_CHROOT) ||
 +          !ns_capable(user_ns, CAP_SYS_ADMIN))
                return -EPERM;
  
        if (is_anon_ns(mnt_ns))
diff --combined fs/super.c
index bf3b7685b52a9d8e3d962880cecad989e636e736,7e3491b96e1d628398dd270ade872234ec925712..904459b351199597d512db5228fe6db322c991e6
@@@ -361,7 -361,7 +361,7 @@@ EXPORT_SYMBOL(deactivate_locked_super)
   */
  void deactivate_super(struct super_block *s)
  {
-         if (!atomic_add_unless(&s->s_active, -1, 1)) {
+       if (!atomic_add_unless(&s->s_active, -1, 1)) {
                down_write(&s->s_umount);
                deactivate_locked_super(s);
        }
@@@ -1302,8 -1302,8 +1302,8 @@@ int get_tree_bdev(struct fs_context *fc
        mutex_lock(&bdev->bd_fsfreeze_mutex);
        if (bdev->bd_fsfreeze_count > 0) {
                mutex_unlock(&bdev->bd_fsfreeze_mutex);
 -              blkdev_put(bdev, mode);
                warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev);
 +              blkdev_put(bdev, mode);
                return -EBUSY;
        }
  
@@@ -1598,10 -1598,12 +1598,10 @@@ int super_setup_bdi_name(struct super_b
        int err;
        va_list args;
  
 -      bdi = bdi_alloc(GFP_KERNEL);
 +      bdi = bdi_alloc(NUMA_NO_NODE);
        if (!bdi)
                return -ENOMEM;
  
 -      bdi->name = sb->s_type->name;
 -
        va_start(args, fmt);
        err = bdi_register_va(bdi, fmt, args);
        va_end(args);
This page took 0.076409 seconds and 4 git commands to generate.