aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-10-01 16:11:26 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-10-24 23:35:00 -0400
commit474279dc0f7745124fc76b474c8dc1294f8e87ce (patch)
tree2ad5e963e698e9524e0eabe466534f03ce324226 /fs/namespace.c
parent7eb5e8826911f2792179f99e77e75fbb7ef53a4a (diff)
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>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 5cbe8cefadb5..500202ce10db 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -548,29 +548,33 @@ static void free_vfsmnt(struct mount *mnt)
548} 548}
549 549
550/* 550/*
551 * find the first or last mount at @dentry on vfsmount @mnt depending on 551 * find the first mount at @dentry on vfsmount @mnt.
552 * @dir. If @dir is set return the first mount else return the last mount.
553 * vfsmount_lock must be held for read or write. 552 * vfsmount_lock must be held for read or write.
554 */ 553 */
555struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, 554struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
556 int dir)
557{ 555{
558 struct list_head *head = mount_hashtable + hash(mnt, dentry); 556 struct list_head *head = mount_hashtable + hash(mnt, dentry);
559 struct list_head *tmp = head; 557 struct mount *p;
560 struct mount *p, *found = NULL;
561 558
562 for (;;) { 559 list_for_each_entry(p, head, mnt_hash)
563 tmp = dir ? tmp->next : tmp->prev; 560 if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry)
564 p = NULL; 561 return p;
565 if (tmp == head) 562 return NULL;
566 break; 563}
567 p = list_entry(tmp, struct mount, mnt_hash); 564
568 if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry) { 565/*
569 found = p; 566 * find the last mount at @dentry on vfsmount @mnt.
570 break; 567 * vfsmount_lock must be held for read or write.
571 } 568 */
572 } 569struct mount *__lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry)
573 return found; 570{
571 struct list_head *head = mount_hashtable + hash(mnt, dentry);
572 struct mount *p;
573
574 list_for_each_entry_reverse(p, head, mnt_hash)
575 if (&p->mnt_parent->mnt == mnt && p->mnt_mountpoint == dentry)
576 return p;
577 return NULL;
574} 578}
575 579
576/* 580/*
@@ -594,7 +598,7 @@ struct vfsmount *lookup_mnt(struct path *path)
594 struct mount *child_mnt; 598 struct mount *child_mnt;
595 599
596 br_read_lock(&vfsmount_lock); 600 br_read_lock(&vfsmount_lock);
597 child_mnt = __lookup_mnt(path->mnt, path->dentry, 1); 601 child_mnt = __lookup_mnt(path->mnt, path->dentry);
598 if (child_mnt) { 602 if (child_mnt) {
599 mnt_add_count(child_mnt, 1); 603 mnt_add_count(child_mnt, 1);
600 br_read_unlock(&vfsmount_lock); 604 br_read_unlock(&vfsmount_lock);