shared/copy: simplify return convention for try_reflink_copy_bytes
Follow-up for 5a12005c83.
Also a rescue a comment from the discussion in the PR.
This commit is contained in:
@@ -6371,6 +6371,12 @@ static int context_copy_blocks(Context *context) {
|
||||
return log_error_errno(errno, "Failed to seek to copy blocks offset in %s: %m", p->copy_blocks_path);
|
||||
}
|
||||
|
||||
/* We call copy_bytes_full() instead of copy_file_range() directly, because copy_file_range()
|
||||
* needs to be called with a size limit to allow for progress updates. But we don't want that
|
||||
* for cloning, we want one big massive reflink if possible, and unfortunately we can't know
|
||||
* if copy_file_range() will do reflink or not, so we can't call it without the size limit.
|
||||
* Hence, call copy_bytes_full(), which tries FICLONE/BTRFS_IOC_CLONE first to do one big
|
||||
* clone, and then falls back to copying in chunks. */
|
||||
r = copy_bytes_full(
|
||||
p->copy_blocks_fd,
|
||||
partition_target_fd(t),
|
||||
|
||||
+11
-22
@@ -130,36 +130,31 @@ static int create_hole(int fd, off_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns positive if the range was cloned, zero if cloning is unavailable, and negative if finalizing a
|
||||
* successful clone failed. If the range was cloned, returns the copy_bytes_full() result in ret_copy_result. */
|
||||
static int try_reflink_copy_bytes(
|
||||
int fdf,
|
||||
int fdt,
|
||||
uint64_t max_bytes,
|
||||
CopyFlags copy_flags,
|
||||
int *ret_copy_result) {
|
||||
CopyFlags copy_flags) {
|
||||
|
||||
off_t foffset, toffset;
|
||||
int r;
|
||||
|
||||
assert(fdf >= 0);
|
||||
assert(fdt >= 0);
|
||||
assert(ret_copy_result);
|
||||
|
||||
if (max_bytes == 0)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
foffset = FLAGS_SET(copy_flags, COPY_SEEK0_SOURCE) ? 0 : lseek(fdf, 0, SEEK_CUR);
|
||||
off_t foffset = FLAGS_SET(copy_flags, COPY_SEEK0_SOURCE) ? 0 : lseek(fdf, 0, SEEK_CUR);
|
||||
if (foffset < 0)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
toffset = FLAGS_SET(copy_flags, COPY_SEEK0_TARGET) ? 0 : lseek(fdt, 0, SEEK_CUR);
|
||||
off_t toffset = FLAGS_SET(copy_flags, COPY_SEEK0_TARGET) ? 0 : lseek(fdt, 0, SEEK_CUR);
|
||||
if (toffset < 0)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
r = reflink_range(fdf, foffset, fdt, toffset, max_bytes == UINT64_MAX ? 0 : max_bytes);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (max_bytes == UINT64_MAX) {
|
||||
off_t end;
|
||||
@@ -172,15 +167,11 @@ static int try_reflink_copy_bytes(
|
||||
|
||||
if (lseek(fdt, toffset + (end - foffset), SEEK_SET) < 0)
|
||||
return -errno;
|
||||
|
||||
*ret_copy_result = 0; /* We copied to EOF. */
|
||||
} else {
|
||||
if (lseek(fdf, foffset + max_bytes, SEEK_SET) < 0)
|
||||
return -errno;
|
||||
if (lseek(fdt, toffset + max_bytes, SEEK_SET) < 0)
|
||||
return -errno;
|
||||
|
||||
*ret_copy_result = 1; /* We copied the requested range. */
|
||||
}
|
||||
|
||||
if (FLAGS_SET(copy_flags, COPY_VERIFY_LINKED)) {
|
||||
@@ -189,7 +180,8 @@ static int try_reflink_copy_bytes(
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return max_bytes == UINT64_MAX ? 0 /* we copied until EOF */
|
||||
: 1 /* we copied the requested range */;
|
||||
}
|
||||
|
||||
int copy_bytes_full(
|
||||
@@ -239,12 +231,9 @@ int copy_bytes_full(
|
||||
lseek(fdt, 0, SEEK_SET) < 0)
|
||||
return -errno;
|
||||
|
||||
int reflink_result = 0;
|
||||
r = try_reflink_copy_bytes(fdf, fdt, max_bytes, copy_flags, &reflink_result);
|
||||
if (r < 0)
|
||||
r = try_reflink_copy_bytes(fdf, fdt, max_bytes, copy_flags);
|
||||
if (r != -EOPNOTSUPP)
|
||||
return r;
|
||||
if (r > 0)
|
||||
return reflink_result;
|
||||
|
||||
usec_t start_timestamp = USEC_INFINITY;
|
||||
if (progress)
|
||||
|
||||
Reference in New Issue
Block a user