diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-10-01 16:11:26 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-10-24 23:35:00 -0400 |
commit | 474279dc0f7745124fc76b474c8dc1294f8e87ce (patch) | |
tree | 2ad5e963e698e9524e0eabe466534f03ce324226 /fs/namespace.c | |
parent | 7eb5e8826911f2792179f99e77e75fbb7ef53a4a (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.c | 42 |
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 | */ |
555 | struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, | 554 | struct 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 | } | 569 | struct 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); |