git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] copy.c: use `sendfile()` for in-kernel file copying on Linux

From
George Hu <integral@archlinux.org>
Date
Feb 15, 2026, 06:23 UTC
Message-ID
<77a887d0-51bf-4bf6-af8f-d5555dab2fe2@archlinux.org>
In-Reply-To
<bf0b3c41-9784-4494-a932-68abfa60cea6@gmail.com>
On 2/15/26 12:43 AM, Phillip Wood wrote:
Show 17 quoted lines
> On 13/02/2026 12:46, George Hu wrote:
>> The `sendfile()` system call copies data between one file descriptor
>> and another within the kernel, which is more efficient than the
>> combination of `read()` and `write()`.
>
> Does git copy any files big enough that this makes a noticeable 
> difference?
>
>>   int copy_fd(int ifd, int ofd)
>>   {
>> +#ifdef __linux__
>
> Our normal practice when a function has platform specific 
> implementations is to host those implementations under compat/<platform>
> (see the implementations of trace2_collect_process_information() for 
> an example)
>

The Linux implementation of `trace2_collect_process_information()` resides in compat/linux with a stub version in compat/stub. After moving the Linux-specifc `copy_fd()` implementation into compat/linux, where should the generic implementation be placed?

Show 20 quoted lines
>> +    struct stat ifd_st;
>> +    size_t ifd_len;
>> +    ssize_t ret = 0;
>> +
>> +    fstat(ifd, &ifd_st);
>
> What happens if fstat() fails?
>
>> +    ifd_len = ifd_st.st_size;
>> +
>> +    while (ifd_len && (ret = sendfile(ofd, ifd, NULL, ifd_len)) > 0)
>> +        ifd_len -= (size_t)ret;
>
> This does not propagate errors to the caller, if sendfile() fails the 
> function returns 0. write_in_full() handles non-blocking writes, we 
> should do the same here if we see EAGAIN. The man page lists various 
> restrictions on the file descriptors passed to sendfile() - I'm not 
> sure that they affect the uses of copy_file() in git but to be safe we 
> should fall back to the read()/write() loop if we see EINVAL.
>

According to the manual, `sendfile()` returns -1 on failure; a return value of 0 indicates EOF.

There are error cases besides EAGAIN and EINVAL. Maybe we should fall back to the read() / write() loop for errors other than EAGAIN?

Sincerely, George

Show 17 quoted lines
> Thanks
>
> Phillip
>
>> +#else
>>       while (1) {
>>           char buffer[8192];
>>           ssize_t len = xread(ifd, buffer, sizeof(buffer));
>> @@ -19,6 +34,8 @@ int copy_fd(int ifd, int ofd)
>>           if (write_in_full(ofd, buffer, len) < 0)
>>               return COPY_WRITE_ERROR;
>>       }
>> +#endif
>> +
>>       return 0;
>>   }
>
Previous: Phillip WoodNext: Jeff King
Message 8 of 9 in “copy.c: use `sendfile()` for in-kernel file copying on Linux”
  1. copy.c: use `sendfile()` for in-kernel file copying on LinuxGeorge Hu, Feb 13, 2026
  2. Chris TorekFeb 13, 2026
  3. George HuFeb 14, 2026
  4. Chris TorekFeb 14, 2026
  5. Ed MasteFeb 20, 2026
  6. Collin FunkFeb 20, 2026
  7. Phillip WoodFeb 14, 2026
  8. George HuFeb 15, 2026
  9. Jeff KingFeb 15, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.