diff options
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.patch | 74 |
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; |