From: guy@Auspex.COM (Guy Harris)
Newsgroups: comp.sys.sun.admin
Subject: Re: cpio -p corrupted links?
Date: 16 Oct 92 02:14:34 GMT
Organization: Auspex Systems, Santa Clara

>>But why can't it just use the whole 32 bit inode-number?  
>>I mean, hey, the (pre SVR4) cpio format doesn't have to be used *internally* 
>>for implementing the cpio -p operation.  Hence there is no need
>>for an internal limitation.  
>
>There are a whole lot of cpio tapes and files out there that will no longer be
>readable if you change the cpio format.

Err, he wasn't *suggesting* changing the "cpio" format.  What he said
was:

>>I mean, hey, the (pre SVR4) cpio format doesn't have to be used *internally* 
>>for implementing the cpio -p operation.  Hence there is no need
>>for an internal limitation.  

Essentially, you'd have both "struct header" (the archival format for
non-"-c" archives), which would still have "h_ino" as a "ushort", and
"struct internal_header" or something like that, with "h_ino" as an
"ino_t".  "gethdr()" would, instead of just reading directly into the
internal header, read into a private buffer and copy into the internal
header; "getname()" would convert the internal header to the external
form.  "-p" wouldn't bother with the external-form header at all.

>The format of headers allows for an inode number of only 16 bits.

omebody wants to make the arguments made

Stuffing 18 bits of inumber into the "-c" format is possible, as the
field is 6 octal digits, but old "cpio" programs would, at best, ignore
the upper 2 bits of the field, so it's not a perfect solution. 

However, with enough work, an idea suggested by the proponents of "cpio"
in the great POSIX "tar wars", when the "not enough room for more than
16 bits of inumber" criticism of "cpio" was brought up, *might* be
doable.

They suggested treating the dev and inumber together as a single 32-bit
quantity, and, in effect, stealing bits from the dev and giving them to
the inumber.

The idea here is that "cpio" doesn't look at the dev and inumber
independently; it only compares the dev/inumber pair for one file with
the dev/inumber pair for another file on the archive when reading an
archive in.  Thus, the dev/inumber pair on the archive only has to form
a 32-bit number that's equal for two files only if they have the same
actual dev and inumber.

You can't just cut bits off the dev and give them to the inumber on all
systems.  For example, there is a machine here that:

	1) has a file system with room for more than 262144 inodes (yup,
	   you guessed it, "/usr/spool/news" :-));

	2) has a "/dev" entry for a disk partition with a major device
	   number of 84 and a minor device number greater than 128;

so, if we had a disk plugged into the disk slot (yup, you guessed it,
the machine is an Auspex) for that "/dev" entry, and put a big file
system on it with room for lots of inodes, you'd require 15 bits of
"dev_t" and, quite possibly, more than 17 bits of inumber). 

That scheme would require more effort - in effect, you'd have to
do something such as assigning unique numbers to each file system
encountered while building the "cpio" archive, and stuff them into
the combined field.  One possibility would be to assign bit-reversed
integers to them, in the hopes that you'd only use a few bits at the
top of a 32-bit quantity, and could merge that 32-bit quantity with
the 32-bit i-number to get a 32-bit value for each file that's the
same for two files iff the two files have the same dev and inumber.

(No, I didn't do any of that for 4.0.)