From: Mark Huang Date: Thu, 4 May 2006 14:32:21 +0000 (+0000) Subject: - apply http://lkml.org/lkml/2006/4/7/149 X-Git-Tag: before-fedora-2_6_18-1_2239_FC5-vs2_0_2_2-rc6-merge~49 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=48ed14b8d2050ff25be145ef132d089c5599ce33;p=linux-2.6.git - apply http://lkml.org/lkml/2006/4/7/149 Unlink files, symlinks, FIFOs, devices etc. (except directories) before writing them when extracting CPIOs. This stops weird behaviour like: 1) writing through symlinks created in earlier CPIOs. eg foo->bar in the first CPIO. Having foo as a non-link in a subsequent CPIO, results in bar being written and foo remaining as a symlink. 2) if the first version of file foo is larger than foo in a subsequent CPIO, we end up with a mix of the two. ie. neither the first or second version of /foo. 3) special files like devices, fifo etc. can't be overwritten in subsequent CPIOS. With this, the kernel will more closely replicate for i in *.cpio; do cpio --extract --unconditional < $i ; done This is a change but it's regarded as fixing broken functionality. Signed-off-by: Michael Neuling Signed-off-by: H. Peter Anvin --- diff --git a/init/initramfs.c b/init/initramfs.c index 6d70d82d5..be7f53c31 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -249,6 +249,7 @@ static int __init do_name(void) if (dry_run) return 0; if (S_ISREG(mode)) { + sys_unlink(collected); if (maybe_link() >= 0) { wfd = sys_open(collected, O_WRONLY|O_CREAT, mode); if (wfd >= 0) { @@ -263,6 +264,7 @@ static int __init do_name(void) sys_chmod(collected, mode); } else if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { + sys_unlink(collected); if (maybe_link() == 0) { sys_mknod(collected, mode, rdev); sys_chown(collected, uid, gid); @@ -291,6 +293,7 @@ static int __init do_copy(void) static int __init do_symlink(void) { collected[N_ALIGN(name_len) + body_len] = '\0'; + sys_unlink(collected); sys_symlink(collected + N_ALIGN(name_len), collected); sys_lchown(collected, uid, gid); state = SkipIt;