This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: copy_file_range evolution



On 04/06/2019 15:31, Florian Weimer wrote:
> * Adhemerval Zanella:
> 
>> On 04/06/2019 12:17, Florian Weimer wrote:
>>> We currently have emulation for copy_file_range.  I thought it was
>>> possible to implement fairly accurate userspace emulation, but I have
>>> doubts now.  What has changed?
>>>
>>> I did not consider the case where both descriptors refer to the same
>>> open file description.  Source and destination offsets in
>>> copy_file_range can either be implied or explicit.  Matching the kernel
>>> behavior looks difficult.
>>>
>>> The emulation does not check an overlapping range, but the kernel does
>>> this (or will do it).  It probably produces garbage in this case.
>>>
>>> There are further kernel changes coming, such as cross-device support.
>>>
>>> I think we should retire the userspace emulation.  We have three options
>>> for that:
>>>
>>> (1) A thin system call wrapper (returning ENOSYS without kernel
>>> support), with the existing symbol versions.
>>
>> I think from our previous attempts of system calls emulation
>> (pread/pwrite, preadv/pwritev, preadv2/pwritev2, fsaccessat, etc.)
>> that is tricky and error prone.  I think a better strategy for Linux
>> specific syscalls is just either provide the wrapper or fail with a
>> ENOSYS.
>>
>> Even for cases where it should be safe, such as preadv2/pwritev2; I
>> think we should just return ENOSYS for configured build without the
>> expected __NR (since for this specific usage there is actually gain in
>> calling preadv2/pwritev2 besides the small semantic difference to
>> pwritev2 from BZ#22753).
> 
> I think the only exception may be system calls which add a flag
> argument, where 0 means exactly the same thing as the previous system
> call.

It would be for the cases where the new syscall that accepts a flags
follows the semantic of the original one (which is not the case for
preadv2).  In any case, I still think there is no much gain in providing
a wrapper that returns ENOSUPP/ENOSYS for flags different than 0: either 
user wants some functionality provided by the flags or it is calling the
new symbol where it could be using the old one.

> 
>>> (2) The same, but with a dual symbol version including GLIBC_2.30.  This
>>> means that we can split the implementation for old binaries and
>>> transition to the next solution.
>>
>> Not sure how would be different than a compat symbol providing the current
>> implementation (syscall plus fallback in case of ENOSYS), and a default
>> one that only issues the syscall.
> 
> The code is just the same as (1), but new binaries would continue to get
> ENOSYS if we switch to (3) later.
> 
> If we do (1) only and kernel updates aren't considered an escape hatch,
> we could end up in a situation where we could not make either old nor
> new binaries happy.

It really depends of what exactly we define as the de-facto ABI. If we 
take in consideration that the fallback mechanism is a better effort
and an implementation detail then I presume we might be free to start
returning ENOSYS and document the change.

However, if we define the compat implementation is now part of the 2.27
to 2.29 ABI we will need to provide it as compat symbol (the third
option).  In fact another issue is that we defined copy_file_range as
a GNU ABI, so the fallback would still need to lay around for Hurd.

So the question is whether it would be acceptable to start returning
ENOSYS for already implemented symbol. From previous experiences I would
also say it seems to be a can of worms and I think we should not do 
this at least for future implementations. I am not sure about the already
set ones.

Also if we define that we *can't* break ABI we will need to start check 
if it is possible to emulate all the missing kernel support.

> 
>>> (3) A full compat symbol with the current implementation, plus a thin
>>> wrapper for new binaries.
>>
>> My main issue here is a program would potentially behave differently
>> whether copy_file_range would be supported by the kernel. Should we
>> really strive for compatibility in this cases?
> 
> The kernel implementation keeps evolving, so the kernel behavior is
> already a complex topic.  But taking glibc out of the equation
> simplifies things.
> 
> Especially if you think about the case where glibc was compiled with
> too-old kernel headers and always performs emulation, no matter what the
> kernel supports.
> 
> Thanks,
> Florian
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]