int follow_down(struct vfsmount **mnt, struct dentry **dentry)
{
- return __follow_down(mnt,dentry);
-+ return __follow_down(mnt,dentry,NULL);
++ return __follow_down(mnt, dentry, NULL);
}
static inline void follow_dotdot(struct nameidata *nd)
break;
}
goto return_base;
-@@ -633,6 +687,27 @@
+@@ -633,6 +687,34 @@
* Check the cached dentry for staleness.
*/
dentry = nd->dentry;
+ break;
+ new = real_lookup(dentry->d_parent,
+ &dentry->d_name, 0, it);
-+ d_invalidate(dentry);
-+ dput(dentry);
+ if (IS_ERR(new)) {
+ err = PTR_ERR(new);
+ break;
+ }
++ d_invalidate(dentry);
++ dput(dentry);
+ nd->dentry = new;
+ }
+ if (!nd->dentry->d_inode)
+ goto no_inode;
++ if (lookup_flags & LOOKUP_DIRECTORY) {
++ err = -ENOTDIR;
++ if (!nd->dentry->d_inode->i_op ||
++ (!nd->dentry->d_inode->i_op->lookup &&
++ !nd->dentry->d_inode->i_op->lookup_it))
++ break;
++ }
+ } else
if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
err = -ESTALE;