Commit c7105365 authored by Al Viro's avatar Al Viro

vfs: spread struct mount - __lookup_mnt() result

switch __lookup_mnt() to returning struct mount *; callers adjusted.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 7d6fec45
...@@ -15,6 +15,7 @@ struct super_block; ...@@ -15,6 +15,7 @@ struct super_block;
struct file_system_type; struct file_system_type;
struct linux_binprm; struct linux_binprm;
struct path; struct path;
struct mount;
/* /*
* block_dev.c * block_dev.c
...@@ -46,7 +47,6 @@ extern void __init chrdev_init(void); ...@@ -46,7 +47,6 @@ extern void __init chrdev_init(void);
extern int copy_mount_options(const void __user *, unsigned long *); extern int copy_mount_options(const void __user *, unsigned long *);
extern int copy_mount_string(const void __user *, char **); extern int copy_mount_string(const void __user *, char **);
extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
extern struct vfsmount *lookup_mnt(struct path *); extern struct vfsmount *lookup_mnt(struct path *);
extern int finish_automount(struct vfsmount *, struct path *); extern int finish_automount(struct vfsmount *, struct path *);
......
...@@ -13,3 +13,5 @@ static inline int mnt_has_parent(struct vfsmount *mnt) ...@@ -13,3 +13,5 @@ static inline int mnt_has_parent(struct vfsmount *mnt)
{ {
return mnt != mnt->mnt_parent; return mnt != mnt->mnt_parent;
} }
extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "internal.h" #include "internal.h"
#include "mount.h"
/* [Feb-1997 T. Schoebel-Theuer] /* [Feb-1997 T. Schoebel-Theuer]
* Fundamental changes in the pathname lookup mechanisms (namei) * Fundamental changes in the pathname lookup mechanisms (namei)
...@@ -884,7 +885,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, ...@@ -884,7 +885,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
struct inode **inode) struct inode **inode)
{ {
for (;;) { for (;;) {
struct vfsmount *mounted; struct mount *mounted;
/* /*
* Don't forget we might have a non-mountpoint managed dentry * Don't forget we might have a non-mountpoint managed dentry
* that wants to block transit. * that wants to block transit.
...@@ -898,8 +899,8 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, ...@@ -898,8 +899,8 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
mounted = __lookup_mnt(path->mnt, path->dentry, 1); mounted = __lookup_mnt(path->mnt, path->dentry, 1);
if (!mounted) if (!mounted)
break; break;
path->mnt = mounted; path->mnt = &mounted->mnt;
path->dentry = mounted->mnt_root; path->dentry = mounted->mnt.mnt_root;
nd->flags |= LOOKUP_JUMPED; nd->flags |= LOOKUP_JUMPED;
nd->seq = read_seqcount_begin(&path->dentry->d_seq); nd->seq = read_seqcount_begin(&path->dentry->d_seq);
/* /*
...@@ -915,12 +916,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, ...@@ -915,12 +916,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
static void follow_mount_rcu(struct nameidata *nd) static void follow_mount_rcu(struct nameidata *nd)
{ {
while (d_mountpoint(nd->path.dentry)) { while (d_mountpoint(nd->path.dentry)) {
struct vfsmount *mounted; struct mount *mounted;
mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1); mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1);
if (!mounted) if (!mounted)
break; break;
nd->path.mnt = mounted; nd->path.mnt = &mounted->mnt;
nd->path.dentry = mounted->mnt_root; nd->path.dentry = mounted->mnt.mnt_root;
nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
} }
} }
......
...@@ -464,20 +464,20 @@ static void free_vfsmnt(struct vfsmount *mnt) ...@@ -464,20 +464,20 @@ static void free_vfsmnt(struct vfsmount *mnt)
* @dir. If @dir is set return the first mount else return the last mount. * @dir. If @dir is set return the first mount else return the last mount.
* vfsmount_lock must be held for read or write. * vfsmount_lock must be held for read or write.
*/ */
struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
int dir) int dir)
{ {
struct list_head *head = mount_hashtable + hash(mnt, dentry); struct list_head *head = mount_hashtable + hash(mnt, dentry);
struct list_head *tmp = head; struct list_head *tmp = head;
struct vfsmount *p, *found = NULL; struct mount *p, *found = NULL;
for (;;) { for (;;) {
tmp = dir ? tmp->next : tmp->prev; tmp = dir ? tmp->next : tmp->prev;
p = NULL; p = NULL;
if (tmp == head) if (tmp == head)
break; break;
p = list_entry(tmp, struct vfsmount, mnt_hash); p = list_entry(tmp, struct mount, mnt.mnt_hash);
if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) { if (p->mnt.mnt_parent == mnt && p->mnt.mnt_mountpoint == dentry) {
found = p; found = p;
break; break;
} }
...@@ -491,13 +491,18 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, ...@@ -491,13 +491,18 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
*/ */
struct vfsmount *lookup_mnt(struct path *path) struct vfsmount *lookup_mnt(struct path *path)
{ {
struct vfsmount *child_mnt; struct mount *child_mnt;
br_read_lock(vfsmount_lock); br_read_lock(vfsmount_lock);
if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1))) child_mnt = __lookup_mnt(path->mnt, path->dentry, 1);
mntget(child_mnt); if (child_mnt) {
br_read_unlock(vfsmount_lock); mnt_add_count(child_mnt, 1);
return child_mnt; br_read_unlock(vfsmount_lock);
return &child_mnt->mnt;
} else {
br_read_unlock(vfsmount_lock);
return NULL;
}
} }
static inline int check_mnt(struct vfsmount *mnt) static inline int check_mnt(struct vfsmount *mnt)
......
...@@ -289,7 +289,8 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count) ...@@ -289,7 +289,8 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count)
*/ */
int propagate_mount_busy(struct vfsmount *mnt, int refcnt) int propagate_mount_busy(struct vfsmount *mnt, int refcnt)
{ {
struct vfsmount *m, *child; struct vfsmount *m;
struct mount *child;
struct vfsmount *parent = mnt->mnt_parent; struct vfsmount *parent = mnt->mnt_parent;
int ret = 0; int ret = 0;
...@@ -307,8 +308,8 @@ int propagate_mount_busy(struct vfsmount *mnt, int refcnt) ...@@ -307,8 +308,8 @@ int propagate_mount_busy(struct vfsmount *mnt, int refcnt)
for (m = propagation_next(parent, parent); m; for (m = propagation_next(parent, parent); m;
m = propagation_next(m, parent)) { m = propagation_next(m, parent)) {
child = __lookup_mnt(m, mnt->mnt_mountpoint, 0); child = __lookup_mnt(m, mnt->mnt_mountpoint, 0);
if (child && list_empty(&child->mnt_mounts) && if (child && list_empty(&child->mnt.mnt_mounts) &&
(ret = do_refcount_check(child, 1))) (ret = do_refcount_check(&child->mnt, 1)))
break; break;
} }
return ret; return ret;
...@@ -328,14 +329,14 @@ static void __propagate_umount(struct vfsmount *mnt) ...@@ -328,14 +329,14 @@ static void __propagate_umount(struct vfsmount *mnt)
for (m = propagation_next(parent, parent); m; for (m = propagation_next(parent, parent); m;
m = propagation_next(m, parent)) { m = propagation_next(m, parent)) {
struct vfsmount *child = __lookup_mnt(m, struct mount *child = __lookup_mnt(m,
mnt->mnt_mountpoint, 0); mnt->mnt_mountpoint, 0);
/* /*
* umount the child only if the child has no * umount the child only if the child has no
* other children * other children
*/ */
if (child && list_empty(&child->mnt_mounts)) if (child && list_empty(&child->mnt.mnt_mounts))
list_move_tail(&child->mnt_hash, &mnt->mnt_hash); list_move_tail(&child->mnt.mnt_hash, &mnt->mnt_hash);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment