On 2/19/13 4:46 AM, Richard W.M. Jones wrote:
> On Mon, Feb 18, 2013 at 03:33:33PM -0600, Eric Sandeen wrote:
>> XFS recently defaulted to allowing > 32 bit inode numbers, and btrfs
>> can let inode numbers creep past 2^32 as well.
>>
>> While most applications don't care one bit about st_ino returned
>> from a stat() call, the sad fact is that you'll get EOVERFLOW from
>> stat32 if the inode number is too big to fit in 32 bits, even if you
>> just wanted to get the file size.
>>
>> I have a script (
http://sandeen.net/misc/summarise_stat.pl) which
>> Greg Banks wrote; it can check a path or list of filenames for
>> binaries which contain non-64bit-safe stat calls. A quick look over
>> my F18 install finds the situation to be only slightly in favor of
>> executables using 64-bit variants:
>>
>> # ./summarize-stat.pl /usr
>> 270229 91.5% are scripts (shell, perl, whatever)
>> 22633 7.7% don't use any stat() family calls at all
>> 913 0.3% use 32-bit stat() family interfaces only
>> 1335 0.5% use 64-bit stat64() family interfaces only
>> 73 0.0% use both 32-bit and 64-bit stat() family interfaces
>>
>> and it's not just weird obscure packages:
>>
>> # ./summarize-stat.pl `rpm -ql sendmail`
>> 69 78.4% are scripts (shell, perl, whatever)
>> 2 2.3% don't use any stat() family calls at all
>> 17 19.3% use 32-bit stat() family interfaces only
>>
>> Anyway, if you want to check your package(s) and maybe make them
>> 64-bit-stat safe, the perl script above might help. It's more than
>> just -DFILE_OFFSET_BITS=64, since you'll need to be sure not to
>> overflow any large values you get back from stat64 etc.
>>
>> Might be nice to get out ahead of this before, say, btrfs comes into
>> wide use. I don't know if there could be any more of a formal
>> effort in this direction?
>
> Eric, I've read this email and the summarise_stat script a couple of
> times, and I admit I'm confused.
I think Petr answered, but -
> (1) Just ensuring the code is compiled with -DFILE_OFFSET_BITS=64 is
> sufficient to ensure the 32 bit stat will never be called, right?
Yep, I think so.
> (2) If my code never mentions st_ino, it's safe?
>
> [I assume the answer to this is *no* because you seem to be saying
> that -EOVERFLOW could be returned from an innocent-looking stat
> call, even if the code never looks at st_ino.]
Right, it's stat() itself that gives EOVERFLOW, it doesn't care if
you want st_ino or not.
> (3) For my code that uses st_ino, I need to ensure this is never
> assigned to a 32 bit integer (eg. 'int', 'int32_t', 'long' on
32 bit, etc.)?
To be safe I'd use it in an u64 type, I guess. The *internal* kernel stat
structure uses u64:
struct kstat {
u64 ino;
> (4) Is doing (1) & (3) sufficient to fix all stat32-related problems
> in my code?
Yep, I think so.
> (5) With -DFILE_OFFSET_BITS=64, is st_ino a 64 bit value?
Yes. (well, a 64-bit container). I wish I knew where the
canonical documentation was for these interfaces.
Sorry, it's -D_FILE_OFFSET_BITS=64 (with the extra "_"), thinko
in my original email.
-Eric