Skip to content
Snippets Groups Projects
Commit a83f181a authored by Simon McVittie's avatar Simon McVittie
Browse files

pv_cheap_tree_copy: Fall back to reflink or copy if hard link fails


Rather than saying "but what if they are on different filesystems?"
we might as well just make it work optimally fast either way, since
the author of libglnx has already done the hard part for us.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent 15fb0c4e
Branches
Tags
No related merge requests found
...@@ -339,13 +339,26 @@ copy_tree_helper (const char *fpath, ...@@ -339,13 +339,26 @@ copy_tree_helper (const char *fpath,
break; break;
case FTW_F: case FTW_F:
/* TODO: If creating a hard link doesn't work, fall back to /* Fast path: try to make a hard link. */
* copying */ if (link (fpath, dest) == 0)
if (link (fpath, dest) != 0) break;
/* Slow path: fall back to copying.
*
* This does a FICLONE or copy_file_range to get btrfs reflinks
* if possible, making the copy as cheap as cp --reflink=auto.
*
* Rather than second-guessing which errno values would result
* in link() failing but a copy succeeding, we just try it
* unconditionally - the worst that can happen is that this
* fails too. */
if (!glnx_file_copy_at (AT_FDCWD, fpath, sb,
AT_FDCWD, dest,
GLNX_FILE_COPY_OVERWRITE,
NULL, error))
{ {
glnx_throw_errno_prefix (error, glnx_prefix_error (error, "Unable to copy \"%s\" to \"%s\"",
"Unable to create hard link from \"%s\" to \"%s\"", fpath, dest);
fpath, dest);
return 1; return 1;
} }
break; break;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment