summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'vserver-sources/old/2.1.1_rc22/4413_vs2.1.1-rc22-cow-fix05.patch')
-rw-r--r--vserver-sources/old/2.1.1_rc22/4413_vs2.1.1-rc22-cow-fix05.patch74
1 files changed, 74 insertions, 0 deletions
diff --git a/vserver-sources/old/2.1.1_rc22/4413_vs2.1.1-rc22-cow-fix05.patch b/vserver-sources/old/2.1.1_rc22/4413_vs2.1.1-rc22-cow-fix05.patch
new file mode 100644
index 0000000..f4f041d
--- /dev/null
+++ b/vserver-sources/old/2.1.1_rc22/4413_vs2.1.1-rc22-cow-fix05.patch
@@ -0,0 +1,74 @@
+Index: linux-2.6.16/fs/namei.c
+===================================================================
+--- linux-2.6.16.orig/fs/namei.c
++++ linux-2.6.16/fs/namei.c
+@@ -2654,13 +2654,14 @@ int vfs_follow_link(struct nameidata *nd
+ int cow_break_link(struct dentry *dentry, const char *pathname)
+ {
+ int err = -EMLINK;
++ int retry = 16;
+ int ret, mode, pathlen;
+ 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';
++ char *to, *path;
+ loff_t size;
+
+ vxdprintk(VXD_CBIT(misc, 2),
+@@ -2679,9 +2680,7 @@ int cow_break_link(struct dentry *dentry
+
+ to[pathlen+1] = 0;
+ retry:
+- to[pathlen] = pad--;
+- if (pad <= '\240')
+- goto out_rel_old;
++ to[pathlen] = '\240' + retry;
+
+ vxdprintk(VXD_CBIT(misc, 2), "temp copy »%s«", to);
+ ret = path_lookup(to,
+@@ -2691,21 +2690,18 @@ retry:
+ new_dentry = lookup_create(&dir_nd, 0);
+ vxdprintk(VXD_CBIT(misc, 2),
+ "lookup_create(new): %p", new_dentry);
+- if (!new_dentry) {
+- path_release(&dir_nd);
+- goto retry;
+- }
++ if (!new_dentry)
++ goto out_rel_path;
+
+ 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) {
+-
+- mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
+- dput(new_dentry);
+- path_release(&dir_nd);
+- goto retry;
++ if (ret != -EEXIST) {
++ err = ret;
++ retry = 0;
+ }
++ if (ret)
++ goto out_rel_both;
+
+ new_mnt = dir_nd.mnt;
+
+@@ -2755,9 +2751,11 @@ out_fput_old:
+ out_rel_both:
+ mutex_unlock(&dir_nd.dentry->d_inode->i_mutex);
+ dput(new_dentry);
+-
++out_rel_path:
+ path_release(&dir_nd);
+-out_rel_old:
++ if (retry--)
++ goto retry;
++
+ path_release(&old_nd);
+ kfree(path);
+ return err;