bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] stat: don't explicitly request file size for filenames


From: Andreas Dilger
Subject: Re: [PATCH] stat: don't explicitly request file size for filenames
Date: Thu, 4 Jul 2019 19:39:53 +0000

On Jul 4, 2019, at 04:44, Pádraig Brady <address@hidden> wrote:
> 
> On 03/07/19 21:24, Andreas Dilger wrote:
>> When calling 'stat -c %N' to print the filename, don't explicitly
>> request the size of the file via statx(), as it may add overhead on
>> some filesystems.  The size is only needed to optimize an allocation
>> for the relatively rare case of reading a symlink name, and the worst
>> effect is a somewhat-too-large temporary buffer may be allocated for
>> areadlink_with_size(), or internal retries if buffer is too small.
>> 
>> The file size will be returned by statx() on most filesystems, even
>> if not requested, unless the filesystem considers this to be too
>> expensive for that file, in which case the tradeoff is worthwhile.
>> 
>> * src/stat.c: Don't explicitly request STATX_SIZE for filenames.
>> Start with a 1KB buffer for areadlink_with_size() if st_size unset.
>> ---
>> src/stat.c | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>> 
>> diff --git a/src/stat.c b/src/stat.c
>> index ec0bb7d..c887013 100644
>> --- a/src/stat.c
>> +++ b/src/stat.c
>> @@ -1282,7 +1282,7 @@ fmt_to_mask (char fmt)
>>   switch (fmt)
>>     {
>>     case 'N':
>> -      return STATX_MODE|STATX_SIZE;
>> +      return STATX_MODE;
>>     case 'd':
>>     case 'D':
>>       return STATX_MODE;
>> @@ -1491,7 +1491,9 @@ print_stat (char *pformat, size_t prefix_len, unsigned 
>> int m,
>>       out_string (pformat, prefix_len, quoteN (filename));
>>       if (S_ISLNK (statbuf->st_mode))
>>         {
>> -          char *linkname = areadlink_with_size (filename, statbuf->st_size);
>> +          /* if statx() didn't set size, most symlinks are under 1KB */
>> +          char *linkname = areadlink_with_size (filename, statbuf->st_size 
>> ?:
>> +                                                1023);
> 
> It would be nice to have areadlink_with_size treat 0 as auto select some 
> lower bound.
> There is already logic there, and it would be generally helpful,
> as st_size can often be 0, as shown with:

I had originally added code to handle this case by allocating a large buffer, 
but I
removed it to keep the patch minimal.  The benefit of passing the 1024-byte 
size from
the caller is that we know this is a temporary buffer and over-allocating 1KB 
for the
symlink is not kept in memory a long time.

That said, it doesn't make any sense to be allocating a 1-byte buffer.  I don't 
know
the glibc malloc routines, but in the kernel, allocating anything less than 32 
bytes
is meaningless, since the minimum slab size is 32 bytes.

>  $ strace -e readlink stat -c %N /proc/$$/cwd
>  readlink("/proc/9036/cwd", "/", 1)      = 1
>  readlink("/proc/9036/cwd", "/h", 2)     = 2
>  readlink("/proc/9036/cwd", "/hom", 4)   = 4
>  readlink("/proc/9036/cwd", "/home/pa", 8) = 8
>  readlink("/proc/9036/cwd", "/home/padraig", 16) = 13
> 
> With the attached gnulib diff, we get:
> 
>  $ strace -e readlink git/coreutils/src/stat -c %N /proc/$$/cwd
>  readlink("/proc/12512/cwd", "/home/padraig", 1024) = 13
> 
> I'll push both later.
> 
> thanks!
> Pádraig
> <areadlink-zero-size.diff>

Cheers, Andreas
--
Andreas Dilger
Principal Lustre Architect
Whamcloud







reply via email to

[Prev in Thread] Current Thread [Next in Thread]