diff -NurpP --minimal linux-2.6.22.9-vs2.3.0.28.4.2/fs/namei.c linux-2.6.22.9-vs2.3.0.28.4.3/fs/namei.c --- linux-2.6.22.9-vs2.3.0.28.4.2/fs/namei.c 2007-10-25 18:04:41 +0200 +++ linux-2.6.22.9-vs2.3.0.28.4.3/fs/namei.c 2007-10-25 18:21:22 +0200 @@ -2775,10 +2775,10 @@ long do_cow_splice(struct file *in, stru struct dentry *cow_break_link(const char *pathname) { - int ret, redo, mode, pathlen; + int ret, mode, pathlen, redo = 0; struct nameidata old_nd, dir_nd; struct dentry *old_dentry, *new_dentry; - struct dentry *res, *dir; + struct dentry *dir, *res = NULL; struct vfsmount *old_mnt, *new_mnt; struct file *old_file; struct file *new_file; @@ -2933,11 +2933,28 @@ out_fput_old: out_unlock_new: mutex_unlock(&dir->d_inode->i_mutex); if (!ret) - goto out_rel_both; + goto out_redo; /* error path cleanup */ vfs_unlink(dir->d_inode, new_dentry, &dir_nd); dput(new_dentry); + +out_redo: + if (!redo) + goto out_rel_both; + /* lookup dentry once again */ + ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd); + if (ret) + goto out_rel_both; + + 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); + dget(new_dentry); + res = new_dentry; + out_rel_both: path_release(&dir_nd); out_rel_old: