Index: linus-2.6.7/fs/namei.c =================================================================== --- linus-2.6.7.orig/fs/namei.c 2005-03-05 20:24:52.000000000 +0200 +++ linus-2.6.7/fs/namei.c 2005-03-28 17:11:20.486991680 +0300 @@ -676,8 +676,11 @@ goto out_dput; if (inode->i_op->follow_link) { + int saved_flags = nd->flags; mntget(next.mnt); + nd->flags |= LOOKUP_LINK_NOTLAST; err = do_follow_link(next.dentry, nd); + nd->flags = saved_flags; dput(next.dentry); mntput(next.mnt); if (err) @@ -723,7 +726,9 @@ if (err < 0) break; } + nd->flags |= LOOKUP_LAST; err = do_lookup(nd, &this, &next); + nd->flags &= ~LOOKUP_LAST; if (err) break; follow_mount(&next.mnt, &next.dentry); @@ -769,10 +774,14 @@ */ if (nd->dentry && nd->dentry->d_sb && (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) { - err = -ESTALE; + nd->flags |= LOOKUP_LAST; + err = !nd->dentry->d_op->d_revalidate(nd->dentry, nd); + nd->flags &= ~LOOKUP_LAST; /* Note: we do not d_invalidate() */ - if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd)) + if (err) { + err = -ESTALE; break; + } } return_base: return 0; @@ -1344,7 +1353,9 @@ dir = nd->dentry; nd->flags &= ~LOOKUP_PARENT; down(&dir->d_inode->i_sem); + nd->flags |= LOOKUP_LAST; dentry = __lookup_hash(&nd->last, nd->dentry, nd); + nd->flags &= ~LOOKUP_LAST; do_last: error = PTR_ERR(dentry); @@ -1449,7 +1460,9 @@ } dir = nd->dentry; down(&dir->d_inode->i_sem); + nd->flags |= LOOKUP_LAST; dentry = __lookup_hash(&nd->last, nd->dentry, nd); + nd->flags &= ~LOOKUP_LAST; putname(nd->last.name); goto do_last; } Index: linus-2.6.7/include/linux/namei.h =================================================================== --- linus-2.6.7.orig/include/linux/namei.h 2005-03-05 20:24:52.000000000 +0200 +++ linus-2.6.7/include/linux/namei.h 2005-03-05 20:24:52.000000000 +0200 @@ -68,6 +68,9 @@ #define LOOKUP_CONTINUE 4 #define LOOKUP_PARENT 16 #define LOOKUP_NOALT 32 +#define LOOKUP_LAST 64 +#define LOOKUP_LINK_NOTLAST 128 + /* * Intent data */