]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'work.autofs' into for-linus
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 16 Dec 2016 21:34:52 +0000 (16:34 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 16 Dec 2016 21:34:52 +0000 (16:34 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1  2 
fs/autofs4/dev-ioctl.c
fs/namei.c
fs/namespace.c
include/linux/mount.h

diff --combined fs/autofs4/dev-ioctl.c
index dfc6f49ee59771a12093d3a9e26f147cfb781637,afacdaa8dd5a203aecc052f9b782e58632dae653..6f48d670c9415ce610980e6288d118623cd237d1
@@@ -204,7 -204,7 +204,7 @@@ static int autofs_dev_ioctl_protosubver
  /* Find the topmost mount satisfying test() */
  static int find_autofs_mount(const char *pathname,
                             struct path *res,
 -                           int test(struct path *path, void *data),
 +                           int test(const struct path *path, void *data),
                             void *data)
  {
        struct path path;
        return err;
  }
  
 -static int test_by_dev(struct path *path, void *p)
 +static int test_by_dev(const struct path *path, void *p)
  {
        return path->dentry->d_sb->s_dev == *(dev_t *)p;
  }
  
 -static int test_by_type(struct path *path, void *p)
 +static int test_by_type(const struct path *path, void *p)
  {
        struct autofs_info *ino = autofs4_dentry_ino(path->dentry);
  
@@@ -468,7 -468,7 +468,7 @@@ static int autofs_dev_ioctl_requester(s
        ino = autofs4_dentry_ino(path.dentry);
        if (ino) {
                err = 0;
-               autofs4_expire_wait(path.dentry, 0);
+               autofs4_expire_wait(&path, 0);
                spin_lock(&sbi->fs_lock);
                param->requester.uid =
                        from_kuid_munged(current_user_ns(), ino->uid);
@@@ -575,7 -575,7 +575,7 @@@ static int autofs_dev_ioctl_ismountpoin
  
                devid = new_encode_dev(dev);
  
-               err = have_submounts(path.dentry);
+               err = path_has_submounts(&path);
  
                if (follow_down_one(&path))
                        magic = path.dentry->d_sb->s_magic;
diff --combined fs/namei.c
index 1c8f4386b03f752ea0740a4c89c111dc2694832c,81ac4736b596f4d15fa1df2871911e22f3ba6c19..47781b0d909d4e2f8d8a59e739d6244986ce2fae
@@@ -1200,7 -1200,7 +1200,7 @@@ static int follow_managed(struct path *
                if (managed & DCACHE_MANAGE_TRANSIT) {
                        BUG_ON(!path->dentry->d_op);
                        BUG_ON(!path->dentry->d_op->d_manage);
-                       ret = path->dentry->d_op->d_manage(path->dentry, false);
+                       ret = path->dentry->d_op->d_manage(path, false);
                        if (ret < 0)
                                break;
                }
@@@ -1263,10 -1263,10 +1263,10 @@@ int follow_down_one(struct path *path
  }
  EXPORT_SYMBOL(follow_down_one);
  
- static inline int managed_dentry_rcu(struct dentry *dentry)
+ static inline int managed_dentry_rcu(const struct path *path)
  {
-       return (dentry->d_flags & DCACHE_MANAGE_TRANSIT) ?
-               dentry->d_op->d_manage(dentry, true) : 0;
+       return (path->dentry->d_flags & DCACHE_MANAGE_TRANSIT) ?
+               path->dentry->d_op->d_manage(path, true) : 0;
  }
  
  /*
@@@ -1282,7 -1282,7 +1282,7 @@@ static bool __follow_mount_rcu(struct n
                 * Don't forget we might have a non-mountpoint managed dentry
                 * that wants to block transit.
                 */
-               switch (managed_dentry_rcu(path->dentry)) {
+               switch (managed_dentry_rcu(path)) {
                case -ECHILD:
                default:
                        return false;
@@@ -1392,8 -1392,7 +1392,7 @@@ int follow_down(struct path *path
                if (managed & DCACHE_MANAGE_TRANSIT) {
                        BUG_ON(!path->dentry->d_op);
                        BUG_ON(!path->dentry->d_op->d_manage);
-                       ret = path->dentry->d_op->d_manage(
-                               path->dentry, false);
+                       ret = path->dentry->d_op->d_manage(path, false);
                        if (ret < 0)
                                return ret == -EISDIR ? 0 : ret;
                }
@@@ -2895,7 -2894,7 +2894,7 @@@ bool may_open_dev(const struct path *pa
                !(path->mnt->mnt_sb->s_iflags & SB_I_NODEV);
  }
  
 -static int may_open(struct path *path, int acc_mode, int flag)
 +static int may_open(const struct path *path, int acc_mode, int flag)
  {
        struct dentry *dentry = path->dentry;
        struct inode *inode = dentry->d_inode;
  
  static int handle_truncate(struct file *filp)
  {
 -      struct path *path = &filp->f_path;
 +      const struct path *path = &filp->f_path;
        struct inode *inode = path->dentry->d_inode;
        int error = get_write_access(inode);
        if (error)
diff --combined fs/namespace.c
index 9ad88a45b3e3b8ae6c3c89f15a07b049c9485f1f,7a73383e836574059d3503a2509633504ca7ed6e..f7e28f8ea04d2a629ae7c5ead8b84ca71913cc8a
@@@ -678,7 -678,7 +678,7 @@@ out
   *
   * lookup_mnt takes a reference to the found vfsmount.
   */
 -struct vfsmount *lookup_mnt(struct path *path)
 +struct vfsmount *lookup_mnt(const struct path *path)
  {
        struct mount *child_mnt;
        struct vfsmount *m;
@@@ -1159,7 -1159,36 +1159,36 @@@ struct vfsmount *mntget(struct vfsmoun
  }
  EXPORT_SYMBOL(mntget);
  
 -struct vfsmount *mnt_clone_internal(struct path *path)
+ /* path_is_mountpoint() - Check if path is a mount in the current
+  *                          namespace.
+  *
+  *  d_mountpoint() can only be used reliably to establish if a dentry is
+  *  not mounted in any namespace and that common case is handled inline.
+  *  d_mountpoint() isn't aware of the possibility there may be multiple
+  *  mounts using a given dentry in a different namespace. This function
+  *  checks if the passed in path is a mountpoint rather than the dentry
+  *  alone.
+  */
+ bool path_is_mountpoint(const struct path *path)
+ {
+       unsigned seq;
+       bool res;
+       if (!d_mountpoint(path->dentry))
+               return false;
+       rcu_read_lock();
+       do {
+               seq = read_seqbegin(&mount_lock);
+               res = __path_is_mountpoint(path);
+       } while (read_seqretry(&mount_lock, seq));
+       rcu_read_unlock();
+       return res;
+ }
+ EXPORT_SYMBOL(path_is_mountpoint);
 +struct vfsmount *mnt_clone_internal(const struct path *path)
  {
        struct mount *p;
        p = clone_mnt(real_mount(path->mnt), path->dentry, CL_PRIVATE);
@@@ -1758,7 -1787,7 +1787,7 @@@ out
  
  /* Caller should check returned pointer for errors */
  
 -struct vfsmount *collect_mounts(struct path *path)
 +struct vfsmount *collect_mounts(const struct path *path)
  {
        struct mount *tree;
        namespace_lock();
@@@ -1791,7 -1820,7 +1820,7 @@@ void drop_collected_mounts(struct vfsmo
   *
   * Release with mntput().
   */
 -struct vfsmount *clone_private_mount(struct path *path)
 +struct vfsmount *clone_private_mount(const struct path *path)
  {
        struct mount *old_mnt = real_mount(path->mnt);
        struct mount *new_mnt;
@@@ -2997,7 -3026,7 +3026,7 @@@ bool is_path_reachable(struct mount *mn
        return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry);
  }
  
 -bool path_is_under(struct path *path1, struct path *path2)
 +bool path_is_under(const struct path *path1, const struct path *path2)
  {
        bool res;
        read_seqlock_excl(&mount_lock);
diff --combined include/linux/mount.h
index cf2b5784b6496c36aca56d82cfba37736c5a06cd,5b6dd004bfdcb347f326636c16e96d1776c7243a..c6f55158d5e5aa086d284a454008f65b790fcfe6
@@@ -79,12 -79,12 +79,12 @@@ extern void mnt_drop_write(struct vfsmo
  extern void mnt_drop_write_file(struct file *file);
  extern void mntput(struct vfsmount *mnt);
  extern struct vfsmount *mntget(struct vfsmount *mnt);
 -extern struct vfsmount *mnt_clone_internal(struct path *path);
 +extern struct vfsmount *mnt_clone_internal(const struct path *path);
  extern int __mnt_is_readonly(struct vfsmount *mnt);
  extern bool mnt_may_suid(struct vfsmount *mnt);
  
  struct path;
 -extern struct vfsmount *clone_private_mount(struct path *path);
 +extern struct vfsmount *clone_private_mount(const struct path *path);
  
  struct file_system_type;
  extern struct vfsmount *vfs_kern_mount(struct file_system_type *type,
@@@ -98,4 -98,6 +98,6 @@@ extern dev_t name_to_dev_t(const char *
  
  extern unsigned int sysctl_mount_max;
  
+ extern bool path_is_mountpoint(const struct path *path);
  #endif /* _LINUX_MOUNT_H */