[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-cpio] [PATCH 2/2] newc copyout: translate inode numbers
From: |
Zdeněk Pavlas |
Subject: |
[Bug-cpio] [PATCH 2/2] newc copyout: translate inode numbers |
Date: |
Tue, 15 Nov 2011 13:58:54 +0100 |
Inode numbers are truncated when building cpio archives on systems
with 64bit ino_t. Copyin code uses these numbers when nlink > 1
to identify hardlink sets.
There is a 1 : 4Gi chance that hardlink sets A+B => I1 and C+D => I2
unpack as A+B+C+D => I2 instead. With 20k hardlinks and 10k inodes
the probability of collision is over 1%.
This patch works around the problem by renumbering hardlinked inodes
with a 1-based sequence. Hardlinks to the same inode are already
grouped so it's quite simple.
---
src/copyout.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/src/copyout.c b/src/copyout.c
index d8c19a0..a60352d 100644
--- a/src/copyout.c
+++ b/src/copyout.c
@@ -241,6 +241,8 @@ writeout_defered_file (struct cpio_file_stat *header, int
out_file_des)
never see the "last" link to the file, so at the end we just write
all of the leftover defered files into the archive. */
+static ino_t xlated_ino = 0;
+
static void
writeout_final_defers (int out_des)
{
@@ -248,6 +250,8 @@ writeout_final_defers (int out_des)
{
struct deferment *h, *d;
struct deferment **tail = &deferouts;
+
+ ++xlated_ino;
for (h = d = deferouts; (d = d->next) != NULL;)
{
if (d->header.c_ino == h->header.c_ino
@@ -334,7 +338,7 @@ write_out_new_ascii_header (const char *magic_string,
char *p;
p = stpcpy (ascii_header, magic_string);
- to_ascii_or_warn (p, file_hdr->c_ino, 8, LG_16,
+ to_ascii_or_error (p, file_hdr->c_nlink > 1 ? xlated_ino : 0, 8, LG_16,
file_hdr->c_name, _("inode number"));
p += 8;
to_ascii_or_warn (p, file_hdr->c_mode, 8, LG_16, file_hdr->c_name,
@@ -710,6 +714,7 @@ process_copy_out ()
{
if (last_link (&file_hdr) )
{
+ ++xlated_ino;
writeout_other_defers (&file_hdr, out_file_des);
}
else
--
1.7.4.4