Skip to content
Snippets Groups Projects
Commit 7a2f26a3 authored by Jonathan Lebon's avatar Jonathan Lebon
Browse files

fdio: fix fd offset handling with `FICLONE`

When using `FICLONE`, the kernel does a full file clone and disregards the
fd offsets. Users of this API however assume that it *is*
offset-sensitive. So we need to verify that the fd offsets are at the
start of the files before we call `FICLONE`. This was done in systemd also
in:

https://github.com/systemd/systemd/commit/c622fbdb8d37

The commit message does not explain this but `ioctl_ficlone(2)` says:

    The `FICLONE` ioctl clones entire files.

(Compare with `FICLONERANGE`, which takes a struct with offsets and the
length).

Similarly, we need to seek to the end of the file descriptors on success
so that we're consistent with the behaviour of the other backends
available (`copy_file_range`, `sendfile` and manual copying). This also
matches what systemd does nowadays:

https://github.com/systemd/systemd/blob/80f967311ac5/src/shared/copy.c#L199
parent c59eb271
No related branches found
No related tags found
1 merge request!504Update libglnx
......@@ -794,10 +794,21 @@ glnx_regfile_copy_bytes (int fdf, int fdt, off_t max_bytes)
/* If we've requested to copy the whole range, try a full-file clone first.
*/
if (max_bytes == (off_t) -1)
if (max_bytes == (off_t) -1 &&
lseek (fdf, 0, SEEK_CUR) == 0 &&
lseek (fdt, 0, SEEK_CUR) == 0)
{
if (ioctl (fdt, FICLONE, fdf) == 0)
return 0;
{
/* All the other methods advance the fds. Do it here too for consistency. */
if (lseek (fdf, 0, SEEK_END) < 0)
return -1;
if (lseek (fdt, 0, SEEK_END) < 0)
return -1;
return 0;
}
/* Fall through */
struct stat stbuf;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment