Loading fs/internal.h +1 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ struct super_block; struct file_system_type; struct linux_binprm; struct path; struct mount; /* * block_dev.c Loading Loading @@ -46,7 +47,6 @@ extern void __init chrdev_init(void); extern int copy_mount_options(const void __user *, unsigned long *); extern int copy_mount_string(const void __user *, char **); extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int); extern struct vfsmount *lookup_mnt(struct path *); extern int finish_automount(struct vfsmount *, struct path *); Loading fs/mount.h +2 −0 Original line number Diff line number Diff line Loading @@ -13,3 +13,5 @@ static inline int mnt_has_parent(struct vfsmount *mnt) { return mnt != mnt->mnt_parent; } extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int); fs/namei.c +7 −6 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <asm/uaccess.h> #include "internal.h" #include "mount.h" /* [Feb-1997 T. Schoebel-Theuer] * Fundamental changes in the pathname lookup mechanisms (namei) Loading Loading @@ -884,7 +885,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, struct inode **inode) { for (;;) { struct vfsmount *mounted; struct mount *mounted; /* * Don't forget we might have a non-mountpoint managed dentry * that wants to block transit. Loading @@ -898,8 +899,8 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, mounted = __lookup_mnt(path->mnt, path->dentry, 1); if (!mounted) break; path->mnt = mounted; path->dentry = mounted->mnt_root; path->mnt = &mounted->mnt; path->dentry = mounted->mnt.mnt_root; nd->flags |= LOOKUP_JUMPED; nd->seq = read_seqcount_begin(&path->dentry->d_seq); /* Loading @@ -915,12 +916,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, static void follow_mount_rcu(struct nameidata *nd) { while (d_mountpoint(nd->path.dentry)) { struct vfsmount *mounted; struct mount *mounted; mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1); if (!mounted) break; nd->path.mnt = mounted; nd->path.dentry = mounted->mnt_root; nd->path.mnt = &mounted->mnt; nd->path.dentry = mounted->mnt.mnt_root; nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); } } Loading fs/namespace.c +14 −9 Original line number Diff line number Diff line Loading @@ -464,20 +464,20 @@ static void free_vfsmnt(struct 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. */ struct vfsmount *__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 *tmp = head; struct vfsmount *p, *found = NULL; struct mount *p, *found = NULL; for (;;) { tmp = dir ? tmp->next : tmp->prev; p = NULL; if (tmp == head) break; p = list_entry(tmp, struct vfsmount, mnt_hash); if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) { p = list_entry(tmp, struct mount, mnt.mnt_hash); if (p->mnt.mnt_parent == mnt && p->mnt.mnt_mountpoint == dentry) { found = p; break; } Loading @@ -491,13 +491,18 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, */ struct vfsmount *lookup_mnt(struct path *path) { struct vfsmount *child_mnt; struct mount *child_mnt; br_read_lock(vfsmount_lock); if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1))) mntget(child_mnt); child_mnt = __lookup_mnt(path->mnt, path->dentry, 1); if (child_mnt) { mnt_add_count(child_mnt, 1); br_read_unlock(vfsmount_lock); return child_mnt; return &child_mnt->mnt; } else { br_read_unlock(vfsmount_lock); return NULL; } } static inline int check_mnt(struct vfsmount *mnt) Loading fs/pnode.c +7 −6 Original line number Diff line number Diff line Loading @@ -289,7 +289,8 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count) */ int propagate_mount_busy(struct vfsmount *mnt, int refcnt) { struct vfsmount *m, *child; struct vfsmount *m; struct mount *child; struct vfsmount *parent = mnt->mnt_parent; int ret = 0; Loading @@ -307,8 +308,8 @@ int propagate_mount_busy(struct vfsmount *mnt, int refcnt) for (m = propagation_next(parent, parent); m; m = propagation_next(m, parent)) { child = __lookup_mnt(m, mnt->mnt_mountpoint, 0); if (child && list_empty(&child->mnt_mounts) && (ret = do_refcount_check(child, 1))) if (child && list_empty(&child->mnt.mnt_mounts) && (ret = do_refcount_check(&child->mnt, 1))) break; } return ret; Loading @@ -328,14 +329,14 @@ static void __propagate_umount(struct vfsmount *mnt) for (m = propagation_next(parent, parent); m; m = propagation_next(m, parent)) { struct vfsmount *child = __lookup_mnt(m, struct mount *child = __lookup_mnt(m, mnt->mnt_mountpoint, 0); /* * umount the child only if the child has no * other children */ if (child && list_empty(&child->mnt_mounts)) list_move_tail(&child->mnt_hash, &mnt->mnt_hash); if (child && list_empty(&child->mnt.mnt_mounts)) list_move_tail(&child->mnt.mnt_hash, &mnt->mnt_hash); } } Loading Loading
fs/internal.h +1 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ struct super_block; struct file_system_type; struct linux_binprm; struct path; struct mount; /* * block_dev.c Loading Loading @@ -46,7 +47,6 @@ extern void __init chrdev_init(void); extern int copy_mount_options(const void __user *, unsigned long *); extern int copy_mount_string(const void __user *, char **); extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int); extern struct vfsmount *lookup_mnt(struct path *); extern int finish_automount(struct vfsmount *, struct path *); Loading
fs/mount.h +2 −0 Original line number Diff line number Diff line Loading @@ -13,3 +13,5 @@ static inline int mnt_has_parent(struct vfsmount *mnt) { return mnt != mnt->mnt_parent; } extern struct mount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
fs/namei.c +7 −6 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <asm/uaccess.h> #include "internal.h" #include "mount.h" /* [Feb-1997 T. Schoebel-Theuer] * Fundamental changes in the pathname lookup mechanisms (namei) Loading Loading @@ -884,7 +885,7 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, struct inode **inode) { for (;;) { struct vfsmount *mounted; struct mount *mounted; /* * Don't forget we might have a non-mountpoint managed dentry * that wants to block transit. Loading @@ -898,8 +899,8 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, mounted = __lookup_mnt(path->mnt, path->dentry, 1); if (!mounted) break; path->mnt = mounted; path->dentry = mounted->mnt_root; path->mnt = &mounted->mnt; path->dentry = mounted->mnt.mnt_root; nd->flags |= LOOKUP_JUMPED; nd->seq = read_seqcount_begin(&path->dentry->d_seq); /* Loading @@ -915,12 +916,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, static void follow_mount_rcu(struct nameidata *nd) { while (d_mountpoint(nd->path.dentry)) { struct vfsmount *mounted; struct mount *mounted; mounted = __lookup_mnt(nd->path.mnt, nd->path.dentry, 1); if (!mounted) break; nd->path.mnt = mounted; nd->path.dentry = mounted->mnt_root; nd->path.mnt = &mounted->mnt; nd->path.dentry = mounted->mnt.mnt_root; nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); } } Loading
fs/namespace.c +14 −9 Original line number Diff line number Diff line Loading @@ -464,20 +464,20 @@ static void free_vfsmnt(struct 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. */ struct vfsmount *__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 *tmp = head; struct vfsmount *p, *found = NULL; struct mount *p, *found = NULL; for (;;) { tmp = dir ? tmp->next : tmp->prev; p = NULL; if (tmp == head) break; p = list_entry(tmp, struct vfsmount, mnt_hash); if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) { p = list_entry(tmp, struct mount, mnt.mnt_hash); if (p->mnt.mnt_parent == mnt && p->mnt.mnt_mountpoint == dentry) { found = p; break; } Loading @@ -491,13 +491,18 @@ struct vfsmount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry, */ struct vfsmount *lookup_mnt(struct path *path) { struct vfsmount *child_mnt; struct mount *child_mnt; br_read_lock(vfsmount_lock); if ((child_mnt = __lookup_mnt(path->mnt, path->dentry, 1))) mntget(child_mnt); child_mnt = __lookup_mnt(path->mnt, path->dentry, 1); if (child_mnt) { mnt_add_count(child_mnt, 1); br_read_unlock(vfsmount_lock); return child_mnt; return &child_mnt->mnt; } else { br_read_unlock(vfsmount_lock); return NULL; } } static inline int check_mnt(struct vfsmount *mnt) Loading
fs/pnode.c +7 −6 Original line number Diff line number Diff line Loading @@ -289,7 +289,8 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count) */ int propagate_mount_busy(struct vfsmount *mnt, int refcnt) { struct vfsmount *m, *child; struct vfsmount *m; struct mount *child; struct vfsmount *parent = mnt->mnt_parent; int ret = 0; Loading @@ -307,8 +308,8 @@ int propagate_mount_busy(struct vfsmount *mnt, int refcnt) for (m = propagation_next(parent, parent); m; m = propagation_next(m, parent)) { child = __lookup_mnt(m, mnt->mnt_mountpoint, 0); if (child && list_empty(&child->mnt_mounts) && (ret = do_refcount_check(child, 1))) if (child && list_empty(&child->mnt.mnt_mounts) && (ret = do_refcount_check(&child->mnt, 1))) break; } return ret; Loading @@ -328,14 +329,14 @@ static void __propagate_umount(struct vfsmount *mnt) for (m = propagation_next(parent, parent); m; m = propagation_next(m, parent)) { struct vfsmount *child = __lookup_mnt(m, struct mount *child = __lookup_mnt(m, mnt->mnt_mountpoint, 0); /* * umount the child only if the child has no * other children */ if (child && list_empty(&child->mnt_mounts)) list_move_tail(&child->mnt_hash, &mnt->mnt_hash); if (child && list_empty(&child->mnt.mnt_mounts)) list_move_tail(&child->mnt.mnt_hash, &mnt->mnt_hash); } } Loading