diff --git a/[refs] b/[refs] index f706edbc2e39..b5a02cbbbd8f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 463ffb2e9d39c2a3fd8c3c1d4a34e01f2078f972 +refs/heads/master: e13b210f6f7bdc44dfee0a9bbd633a32db0d6333 diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 23a1ad467976..935b08d8dcd8 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -612,26 +612,21 @@ static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) /* no need for dcache_lock, as serialization is taken care in * namespace.c */ -static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) +int follow_down(struct vfsmount **mnt, struct dentry **dentry) { struct vfsmount *mounted; mounted = lookup_mnt(*mnt, *dentry); if (mounted) { + dput(*dentry); mntput(*mnt); *mnt = mounted; - dput(*dentry); *dentry = dget(mounted->mnt_root); return 1; } return 0; } -int follow_down(struct vfsmount **mnt, struct dentry **dentry) -{ - return __follow_down(mnt,dentry); -} - static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry) { while(1) { @@ -1498,11 +1493,14 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) if (flag & O_EXCL) goto exit_dput; - if (d_mountpoint(path.dentry)) { + if (__follow_mount(&path)) { error = -ELOOP; - if (flag & O_NOFOLLOW) - goto exit_dput; - while (__follow_down(&path.mnt,&path.dentry) && d_mountpoint(path.dentry)); + if (flag & O_NOFOLLOW) { + dput(path.dentry); + mntput(path.mnt); + goto exit; + } + mntput(nd->mnt); nd->mnt = path.mnt; } error = -ENOENT;