diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.28.3/fs/namei.c linux-2.6.22.9-vs2.3.0.28.4/fs/namei.c --- linux-2.6.22.9-vs2.3.0.28.3/fs/namei.c 2007-10-25 13:30:54 +0200 +++ linux-2.6.22.9-vs2.3.0.28.4/fs/namei.c 2007-10-25 15:45:41 +0200 @@ -2850,11 +2850,10 @@ retry: goto out_unlock_new; } - /* drop out early */ - if (d_unhashed(old_dentry)) { - res = ERR_PTR(-ENOENT); + /* drop out early, ENOENT signals redo */ + ret = -ENOENT; + if (d_unhashed(old_dentry)) goto out_unlock_new; - } new_mnt = dir_nd.mnt; dget(old_dentry); @@ -2921,12 +2920,24 @@ retry: out_unlock: mutex_unlock(&old_dentry->d_inode->i_sb->s_vfs_rename_mutex); + if (ret != ENOENT) + goto done; + /* redo dentry lookup */ + ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd); + if (ret) + goto done; + + new_dentry = old_nd.dentry; + vxdprintk(VXD_CBIT(misc, 2), + "path_lookup(redo): %p [»%.*s«:%d]", new_dentry, + new_dentry->d_name.len, new_dentry->d_name.name, + new_dentry->d_name.len); +done: if (!ret) { res = new_dentry; dget(new_dentry); - } - else + } else res = ERR_PTR(ret); out_fput_both: