--- fs/namei.c.orig 2004-04-05 13:44:30.317084264 +0200 +++ fs/namei.c 2004-04-05 13:45:40.668389240 +0200 @@ -1694,24 +1694,13 @@ return error; } -/* - * Make sure that the actual truncation of the file will occur outside its - * directory's i_sem. Truncate can take a long time if there is a lot of - * writeout happening, and we don't want to prevent access to the directory - * while waiting on the I/O. - */ -asmlinkage long sys_unlink(const char __user * pathname) +int do_unlink(char *name) { int error = 0; - char * name; struct dentry *dentry; struct nameidata nd; struct inode *inode = NULL; - name = getname(pathname); - if(IS_ERR(name)) - return PTR_ERR(name); - error = path_lookup(name, LOOKUP_PARENT, &nd); if (error) goto exit; @@ -1736,8 +1725,6 @@ exit1: path_release(&nd); exit: - putname(name); - if (inode) iput(inode); /* truncate the inode here */ return error; @@ -1748,6 +1735,25 @@ goto exit2; } +/* + * Make sure that the actual truncation of the file will occur outside its + * directory's i_sem. Truncate can take a long time if there is a lot of + * writeout happening, and we don't want to prevent access to the directory + * while waiting on the I/O. + */ +asmlinkage long sys_unlink(const char __user * pathname) +{ + char * name; + + name = getname(pathname); + if(IS_ERR(name)) + return PTR_ERR(name); + + error = do_unlink(name); + putname(name); + return error; +} + int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { int error = may_create(dir, dentry, NULL); --- fs/exec.c.orig 2004-04-05 09:41:31.134456912 +0200 +++ fs/exec.c 2004-04-05 13:50:17.093366256 +0200 @@ -1387,9 +1387,14 @@ goto fail_unlock; format_corename(corename, core_pattern, signr); - file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); - if (IS_ERR(file)) - goto fail_unlock; + file = filp_open(corename, O_CREAT | O_EXCL | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); + if (IS_ERR(file)){ + if (do_unlink(corename)) + goto fail_unlock; + file = filp_open(corename, O_CREAT | O_EXCL | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); + if (IS_ERR(file)) + goto fail_unlock; + } inode = file->f_dentry->d_inode; if (inode->i_nlink > 1) goto close_fail; /* multiple links - don't dump */ --- include/linux/fs.h.orig 2004-04-05 09:42:52.205132296 +0200 +++ include/linux/fs.h 2004-04-05 13:50:46.119953544 +0200 @@ -1253,6 +1253,7 @@ extern int open_namei(const char *, int, int, struct nameidata *); extern int may_open(struct nameidata *, int, int); +extern int do_unlink(char *); extern int kernel_read(struct file *, unsigned long, char *, unsigned long); extern struct file * open_exec(const char *);