diff -NurpP --minimal linux-2.6.13-rc7-vs2.1.0-pre4.1/fs/namei.c linux-2.6.13-rc7-vs2.1.0-pre5/fs/namei.c
--- linux-2.6.13-rc7-vs2.1.0-pre4.1/fs/namei.c	2005-08-25 05:58:01 +0200
+++ linux-2.6.13-rc7-vs2.1.0-pre5/fs/namei.c	2005-08-26 05:58:01 +0200
@@ -1381,8 +1381,10 @@ int may_open(struct nameidata *nd, int a
 	if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
 		return -EISDIR;
 
+#ifdef	CONFIG_VSERVER_COWBL
 	if (IS_COW_LINK(inode) && (flag & FMODE_WRITE))
 		return -EMLINK;
+#endif
 
 	error = permission(inode, acc_mode, nd);
 	if (error)
@@ -1472,6 +1474,11 @@ int open_namei(const char * pathname, in
 	struct dentry *dir;
 	int count = 0;
 
+#ifdef	CONFIG_VSERVER_COWBL
+	int rflag = flag;
+	int rmode = mode;
+restart:
+#endif
 	acc_mode = ACC_MODE(flag);
 
 	/* Allow the LSM permission hook to distinguish append 
@@ -1479,6 +1486,5 @@ int open_namei(const char * pathname, in
 	nd->intent.open.flags = flag;
 	nd->intent.open.create_mode = mode;
 
-restart:
 	/*
 	 * The simplest case - just a plain lookup.
 	 */
@@ -1576,6 +1583,8 @@ ok:
 			goto exit;
 		path_release(nd);
 		vxdprintk(VXD_CBIT(misc, 2), "restarting open_namei() ...");
+		flag = rflag;
+		mode = rmode;
 		goto restart;
 	}
 #endif
@@ -2448,23 +2457,25 @@ int cow_break_link(struct dentry *dentry
 {
 	int err = -EMLINK;
 	int ret, mode, pathlen;
-	struct nameidata old_nd, new_nd;
-	struct dentry *new_dentry;
+	struct nameidata old_nd, dir_nd;
+	struct dentry *old_dentry, *new_dentry;
 	struct vfsmount *old_mnt, *new_mnt;
 	struct file *old_file;
 	struct file *new_file;
 	char *to, *path, pad='\251';
 	loff_t size;
 
-	vxdprintk(VXD_CBIT(misc, 2), "break link �%s�", pathname);
+	vxdprintk(VXD_CBIT(misc, 2),
+		"cow_break_link(%p,�%s�)", dentry, pathname);
 	path = kmalloc(PATH_MAX, GFP_KERNEL);
 
 	ret = path_lookup(pathname, LOOKUP_FOLLOW, &old_nd);
 	vxdprintk(VXD_CBIT(misc, 2), "path_lookup(old): %d", ret);
+	old_dentry = old_nd.dentry;
 	old_mnt = old_nd.mnt;
-	mode = old_nd.dentry->d_inode->i_mode;
+	mode = old_dentry->d_inode->i_mode;
 
-	to = d_path(old_nd.dentry, old_nd.mnt, path, PATH_MAX-2);
+	to = d_path(old_dentry, old_mnt, path, PATH_MAX-2);
 	pathlen = strlen(to);
 	vxdprintk(VXD_CBIT(misc, 2), "old path �%s�", to);
 
@@ -2476,34 +2487,33 @@ retry:
 
 	vxdprintk(VXD_CBIT(misc, 2), "temp copy �%s�", to);
 	ret = path_lookup(to,
-		LOOKUP_PARENT | LOOKUP_OPEN | LOOKUP_CREATE, &new_nd);
-	vxdprintk(VXD_CBIT(misc, 2), "path_lookup(new): %d", ret);
+		LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE, &dir_nd);
 
 	/* this puppy downs the inode sem */
-	new_dentry = lookup_create(&new_nd, 0);
+	new_dentry = lookup_create(&dir_nd, 0);
 	vxdprintk(VXD_CBIT(misc, 2),
 		"lookup_create(new): %p", new_dentry);
 	if (!new_dentry) {
-		path_release(&new_nd);
+		path_release(&dir_nd);
 		goto retry;
 	}
 
-	ret = vfs_create(new_nd.dentry->d_inode, new_dentry, mode, &new_nd);
+	ret = vfs_create(dir_nd.dentry->d_inode, new_dentry, mode, &dir_nd);
 	vxdprintk(VXD_CBIT(misc, 2),
 		"vfs_create(new): %d", ret);
 	if (ret == -EEXIST) {
-		up(&new_nd.dentry->d_inode->i_sem);
+		up(&dir_nd.dentry->d_inode->i_sem);
 		dput(new_dentry);
-		path_release(&new_nd);
+		path_release(&dir_nd);
 		goto retry;
 	}
 
-	new_mnt = new_nd.mnt;
+	new_mnt = dir_nd.mnt;
 
-	dget(dentry);
+	dget(old_dentry);
 	mntget(old_mnt);
 	/* this one cleans up the dentry in case of failure */
-	old_file = dentry_open(dentry, old_mnt, O_RDONLY);
+	old_file = dentry_open(old_dentry, old_mnt, O_RDONLY);
 	vxdprintk(VXD_CBIT(misc, 2),
 		"dentry_open(old): %p", old_file);
 	if (!old_file)
@@ -2529,8 +2539,8 @@ retry:
 	if (ret < 0)
 		goto out_fput_both;
 
-	ret = vfs_rename(new_nd.dentry->d_inode, new_dentry,
-		new_nd.dentry->d_inode, dentry);
+	ret = vfs_rename(dir_nd.dentry->d_inode, new_dentry,
+		old_nd.dentry->d_parent->d_inode, old_dentry);
 	vxdprintk(VXD_CBIT(misc, 2), "vfs_rename: %d", ret);
 	if (!ret)
 		err = 0;
@@ -2548,10 +2558,10 @@ out_fput_old:
 	fput(old_file);
 
 out_rel_both:
-	up(&new_nd.dentry->d_inode->i_sem);
+	up(&dir_nd.dentry->d_inode->i_sem);
 	dput(new_dentry);
 
-	path_release(&new_nd);
+	path_release(&dir_nd);
 out_rel_old:
 	path_release(&old_nd);