mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
split __lookup_mnt() in two functions
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 <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -77,7 +77,8 @@ static inline int is_mounted(struct vfsmount *mnt)
|
|||||||
return !IS_ERR_OR_NULL(real_mount(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)
|
static inline void get_mnt_ns(struct mnt_namespace *ns)
|
||||||
{
|
{
|
||||||
|
@@ -1111,7 +1111,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
|
|||||||
if (!d_mountpoint(path->dentry))
|
if (!d_mountpoint(path->dentry))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mounted = __lookup_mnt(path->mnt, path->dentry, 1);
|
mounted = __lookup_mnt(path->mnt, path->dentry);
|
||||||
if (!mounted)
|
if (!mounted)
|
||||||
break;
|
break;
|
||||||
path->mnt = &mounted->mnt;
|
path->mnt = &mounted->mnt;
|
||||||
@@ -1132,7 +1132,7 @@ static void follow_mount_rcu(struct nameidata *nd)
|
|||||||
{
|
{
|
||||||
while (d_mountpoint(nd->path.dentry)) {
|
while (d_mountpoint(nd->path.dentry)) {
|
||||||
struct mount *mounted;
|
struct mount *mounted;
|
||||||
mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1);
|
mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry);
|
||||||
if (!mounted)
|
if (!mounted)
|
||||||
break;
|
break;
|
||||||
nd->path.mnt = &mounted->mnt;
|
nd->path.mnt = &mounted->mnt;
|
||||||
|
@@ -548,29 +548,33 @@ static void free_vfsmnt(struct mount *mnt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* find the first or last mount at @dentry on vfsmount @mnt depending on
|
* find the first mount at @dentry on vfsmount @mnt.
|
||||||
* @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 mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
|
struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
|
||||||
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 mount *p;
|
||||||
struct mount *p, *found = NULL;
|
|
||||||
|
|
||||||
for (;;) {
|
list_for_each_entry(p, head, mnt_hash)
|
||||||
tmp = dir ? tmp->next : tmp->prev;
|
if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry)
|
||||||
p = NULL;
|
return p;
|
||||||
if (tmp == head)
|
return NULL;
|
||||||
break;
|
}
|
||||||
p = list_entry(tmp, struct mount, mnt_hash);
|
|
||||||
if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry) {
|
/*
|
||||||
found = p;
|
* find the last mount at @dentry on vfsmount @mnt.
|
||||||
break;
|
* vfsmount_lock must be held for read or write.
|
||||||
}
|
*/
|
||||||
}
|
struct mount *__lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry)
|
||||||
return found;
|
{
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -594,7 +598,7 @@ struct vfsmount *lookup_mnt(struct path *path)
|
|||||||
struct mount *child_mnt;
|
struct mount *child_mnt;
|
||||||
|
|
||||||
br_read_lock(&vfsmount_lock);
|
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) {
|
if (child_mnt) {
|
||||||
mnt_add_count(child_mnt, 1);
|
mnt_add_count(child_mnt, 1);
|
||||||
br_read_unlock(&vfsmount_lock);
|
br_read_unlock(&vfsmount_lock);
|
||||||
|
@@ -310,7 +310,7 @@ int propagate_mount_busy(struct mount *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->mnt_mountpoint, 0);
|
child = __lookup_mnt_last(&m->mnt, mnt->mnt_mountpoint);
|
||||||
if (child && list_empty(&child->mnt_mounts) &&
|
if (child && list_empty(&child->mnt_mounts) &&
|
||||||
(ret = do_refcount_check(child, 1)))
|
(ret = do_refcount_check(child, 1)))
|
||||||
break;
|
break;
|
||||||
@@ -332,8 +332,8 @@ static void __propagate_umount(struct mount *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 mount *child = __lookup_mnt(&m->mnt,
|
struct mount *child = __lookup_mnt_last(&m->mnt,
|
||||||
mnt->mnt_mountpoint, 0);
|
mnt->mnt_mountpoint);
|
||||||
/*
|
/*
|
||||||
* umount the child only if the child has no
|
* umount the child only if the child has no
|
||||||
* other children
|
* other children
|
||||||
|
Reference in New Issue
Block a user