Skip to content

Commit

Permalink
split __lookup_mnt() in two functions
Browse files Browse the repository at this point in the history
Instead of passing the direction as argument (and checking it on every
step through the hash chain), just have separate __lookup_mnt() and
__lookup_mnt_last().  And use the standard iterators...

Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Al Viro committed Oct 25, 2013
1 parent 7eb5e88 commit 474279d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 25 deletions.
3 changes: 2 additions & 1 deletion fs/mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ static inline int is_mounted(struct vfsmount *mnt)
return !IS_ERR_OR_NULL(real_mount(mnt));
}

extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *);
extern struct mount *__lookup_mnt_last(struct vfsmount *, struct dentry *);

static inline void get_mnt_ns(struct mnt_namespace *ns)
{
Expand Down
4 changes: 2 additions & 2 deletions fs/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
if (!d_mountpoint(path->dentry))
break;

mounted = __lookup_mnt(path->mnt, path->dentry, 1);
mounted = __lookup_mnt(path->mnt, path->dentry);
if (!mounted)
break;
path->mnt = &mounted->mnt;
Expand All @@ -1132,7 +1132,7 @@ static void follow_mount_rcu(struct nameidata *nd)
{
while (d_mountpoint(nd->path.dentry)) {
struct mount *mounted;
mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1);
mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
if (!mounted)
break;
nd->path.mnt = &mounted->mnt;
Expand Down
42 changes: 23 additions & 19 deletions fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,29 +548,33 @@ static void free_vfsmnt(struct mount *mnt)
}

/*
* find the first or last mount at @dentry on vfsmount @mnt depending on
* @dir. If @dir is set return the first mount else return the last mount.
* find the first mount at @dentry on vfsmount @mnt.
* vfsmount_lock must be held for read or write.
*/
struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
int dir)
struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
{
struct list_head *head = mount_hashtable + hash(mnt, dentry);
struct list_head *tmp = head;
struct mount *p, *found = NULL;
struct mount *p;

for (;;) {
tmp = dir ? tmp->next : tmp->prev;
p = NULL;
if (tmp == head)
break;
p = list_entry(tmp, struct mount, mnt_hash);
if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry) {
found = p;
break;
}
}
return found;
list_for_each_entry(p, head, mnt_hash)
if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry)
return p;
return NULL;
}

/*
* find the last mount at @dentry on vfsmount @mnt.
* vfsmount_lock must be held for read or write.
*/
struct mount *__lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry)
{
struct list_head *head = mount_hashtable + hash(mnt, dentry);
struct mount *p;

list_for_each_entry_reverse(p, head, mnt_hash)
if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry)
return p;
return NULL;
}

/*
Expand All @@ -594,7 +598,7 @@ struct vfsmount *lookup_mnt(struct path *path)
struct mount *child_mnt;

br_read_lock(&vfsmount_lock);
child_mnt = __lookup_mnt(path->mnt, path->dentry, 1);
child_mnt = __lookup_mnt(path->mnt, path->dentry);
if (child_mnt) {
mnt_add_count(child_mnt, 1);
br_read_unlock(&vfsmount_lock);
Expand Down
6 changes: 3 additions & 3 deletions fs/pnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ int propagate_mount_busy(struct mount *mnt, int refcnt)

for (m = propagation_next(parent, parent); m;
m = propagation_next(m, parent)) {
child = __lookup_mnt(&m->mnt, mnt->mnt_mountpoint, 0);
child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint);
if (child && list_empty(&child->mnt_mounts) &&
(ret = do_refcount_check(child, 1)))
break;
Expand All @@ -332,8 +332,8 @@ static void __propagate_umount(struct mount *mnt)
for (m = propagation_next(parent, parent); m;
m = propagation_next(m, parent)) {

struct mount *child = __lookup_mnt(&m->mnt,
mnt->mnt_mountpoint, 0);
struct mount *child = __lookup_mnt_last(&m->mnt,
mnt->mnt_mountpoint);
/*
* umount the child only if the child has no
* other children
Expand Down

0 comments on commit 474279d

Please sign in to comment.