cache: sendfile(2) usage results in short writes to pipes

Valdis Vītoliņš valdis.vitolins at odo.lv
Thu Dec 22 08:58:00 UTC 2022


Hi, Leah!

Do I understand you correctly that, when compiling and deploying cgit
according to https://git.zx2c4.com/cgit/tree/README

before compilation I should add in Makefile:
HAVE_LINUX_SENDFILE = 1

Thanks!
Valdis

> Hi,
> 
> in cache.c:print_slot, sendfile is called only once, but not checked
> for short writes.  These happen for example when serving cgit via
> fcgiwrap, which uses a pipe, so the write only writes 65k:
> 
> [pid 31211] openat(AT_FDCWD, "/var/cache/cgit/b9200000", O_RDONLY) = 4
> [pid 31211] fstat(4, {st_mode=S_IFREG|0600, st_size=19824215, ...}) = 0
> [pid 31211] read(4, "mirror/glibc/snapshot/glibc-3aae"..., 4096) = 4096
> [pid 31211] sendfile(1, 4, [77] => [65536], 19824138) = 65459
> [pid 31211] close(4 <unfinished ...>
> 
> This results in truncated cache responses, and therefore broken
> downloads from snapshots (larger than 65k).
> 
> I assume this is also the cause for the bug reported in
> <0ef89b1e-6543-e726-2cf0-b68e7167fabe at odo.lv>, I added the author to Cc:.
> 
> I recommend running sendfile in a loop until the whole file is sent.
> I also recommend detecting sendfile errors and falling back to the
> default read/write implementation, as there are some Linux filesystems
> where sendfile fails permanently.
> 
> Disabling HAVE_LINUX_SENDFILE on build serves as a workaround.
> 
> cu,


More information about the CGit mailing list