[PATCH] copy_file_range: New function to copy file data

Florian Weimer fweimer@redhat.com
Mon Dec 18 20:19:00 GMT 2017


On 12/18/2017 09:04 PM, Adhemerval Zanella wrote:

> I am seeing a lot of failures from tst-copy_file_range on both x86_64 and i686
> when using the fallback implementation (io/copy_file_range.c) due the fact
> write is returning EFBIG (I attached the test output):

Which file system is this?

> 
> [...]
> openat(AT_FDCWD, "/tmp/tst-copy_file_range-in-mT9I6j", O_RDWR) = 3
> ftruncate(3, 0)                         = 0
> openat(AT_FDCWD, "/tmp/tst-copy_file_range-out-0RbGw2", O_RDWR) = 4
> ftruncate(4, 0)
> [...]
> fcntl(4, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
> read(3, "k2dft\31*b#F=P.AyuQ[\22M\2\37\21f\0243\20\r\177\33Ak"..., 8192) = 8192
> write(4, "k2dft\31*b#F=P.AyuQ[\22M\2\37\21f\0243\20\r\177\33Ak"..., 8192) = -1 EFBIG (File too large)
> lseek(3, -8192, SEEK_CUR)               = 0
> write(1, "tst-copy_file_range.c:285: numer"..., 54tst-copy_file_range.c:285: numeric comparison failure
> [...]

It would be interesting to compare this with the real copy_file_range 
system call.  I don't think it remaps EFBIG, so this might also apply 
there, too.

> I also noted it does not provided a non-LFS version and it a good way forward
> imho, however I think we need to explicit handle the case where a non-LFS
> invocation tries to use copy_file_range in a non-supported way.  For instance
> the snippet:
> 
> [...]
> int fin  = open ("/tmp/file.in",  O_RDWR | O_CREAT | O_TRUNC, 0600);                                                                                                                                                                                                                                                                                          int fout = open ("/tmp/file.out", O_RDWR | O_CREAT | O_TRUNC, 0600);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 char buffer[8192] = { 0xcc };                                                                                                                                                                       const size_t size = 8192;                                                                                                                                                                                                                                                                                                                           pwrite (fin, buffer, size, 0);                                                                                                                                                                                                                                                                                                                                   copy_file_range (fin, 0, fout, &(__off64_t) { INT32_MAX }, size, 0);
> [...]
> 
> Will again return EFBIG.

Hmm.  I think this is just the EFBIG problem.  I'd be more concerned 
about EBADF here.

> We have some options as 1. handle EFBIG
> as an expected retuned error, 2. do not declare copy_file_range for
> !__USE_FILE_OFFSET64, 3. add a dummy implementation for non-LFS
> (which return ENOSYS).

I'd like to reproduce this with the file system you used on a kernel 
with a copy_file_range system call, and see what the system call does there.

>> +  /* Main copying loop.  The buffer size is arbitrary and is a
>> +     trade-off between stack size consumption, cache usage, and
>> +     amortization of system call overhead.  */
>> +  size_t copied = 0;
>> +  char buf[8192];
> 
> Do we you have any numbers with shorter sizes? Maybe

Sorry, could you expand?

Choosing buffer sizes is notoriously difficult, I'm afraid.

Thanks,
Florian


More information about the Libc-alpha mailing list