Hi i have seen error in lustre while setting permission on fs root from a client. problem is permission are not getting propagated to other clients. this is because of do_lookup() call path which does not revalidate fs root dentry in follow_mount() attached patch adds revalidation call in follow_mount. Thanks, Pravin
Signed-off-by: pravin shelar <pravin.shelar@xxxxxxx> Index: linux-2.6-latest/fs/namei.c =================================================================== --- linux-2.6-latest.orig/fs/namei.c +++ linux-2.6-latest/fs/namei.c @@ -691,9 +691,11 @@ int follow_up(struct vfsmount **mnt, str /* no need for dcache_lock, as serialization is taken care in * namespace.c */ -static int __follow_mount(struct path *path) +static int __follow_mount(struct nameidata *nd, struct path *path) { int res = 0; + struct dentry *dentry; + while (d_mountpoint(path->dentry)) { struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry); if (!mounted) @@ -703,6 +705,18 @@ static int __follow_mount(struct path *p mntput(path->mnt); path->mnt = mounted; path->dentry = dget(mounted->mnt_root); + dentry = path->dentry; + + if (dentry->d_op && dentry->d_op->d_revalidate){ + dentry = do_revalidate(dentry, nd); + if (!dentry) + return -EINVAL; + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + } + + path->dentry = dentry; + res = 1; } return res; @@ -788,6 +802,7 @@ static int do_lookup(struct nameidata *n { struct vfsmount *mnt = nd->path.mnt; struct dentry *dentry = __d_lookup(nd->path.dentry, name); + int rc; if (!dentry) goto need_lookup; @@ -796,7 +811,9 @@ static int do_lookup(struct nameidata *n done: path->mnt = mnt; path->dentry = dentry; - __follow_mount(path); + rc = __follow_mount(nd, path); + if (rc < 0) + return rc; return 0; need_lookup: @@ -1747,11 +1764,15 @@ do_last: if (flag & O_EXCL) goto exit_dput; - if (__follow_mount(&path)) { - error = -ELOOP; - if (flag & O_NOFOLLOW) + error = __follow_mount(&nd, &path); + if (error == 1) { + if (flag & O_NOFOLLOW) { + error = -ELOOP; goto exit_dput; + } } + if (error < 0) + goto exit_dput; error = -ENOENT; if (!path.dentry->d_inode)