Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 474279dc authored by Al Viro's avatar Al Viro
Browse files

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 7eb5e882
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -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)
{
{
+2 −2
Original line number Original line Diff line number Diff line
@@ -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;
+23 −19
Original line number Original line Diff line number Diff line
@@ -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;
			break;
		}
}
}
	return found;

/*
 * 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;
}
}


/*
/*
@@ -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);
+3 −3
Original line number Original line Diff line number Diff line
@@ -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