sfd, ".",
pfd, fn,
UID_INVALID, GID_INVALID,
- COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN,
+ COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE,
denylist);
} else
r = copy_tree_at(
sfd, ".",
tfd, ".",
UID_INVALID, GID_INVALID,
- COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN,
+ COPY_REFLINK|COPY_HOLES|COPY_MERGE|COPY_REPLACE|COPY_SIGINT|COPY_HARDLINKS|COPY_ALL_XATTRS|COPY_GRACEFUL_WARN|COPY_TRUNCATE,
denylist);
if (r < 0)
return log_error_errno(r, "Failed to copy '%s%s' to '%s%s': %m",
if (tfd < 0)
return log_error_errno(errno, "Failed to create target file '%s': %m", *target);
- r = copy_bytes(sfd, tfd, UINT64_MAX, COPY_REFLINK|COPY_HOLES|COPY_SIGINT);
+ r = copy_bytes(sfd, tfd, UINT64_MAX, COPY_REFLINK|COPY_HOLES|COPY_SIGINT|COPY_TRUNCATE);
if (r < 0)
return log_error_errno(r, "Failed to copy '%s' to '%s%s': %m", *source, strempty(arg_root), *target);
if (lseek(fd, p->offset, SEEK_SET) < 0)
return log_error_errno(errno, "Failed to seek to partition offset: %m");
- r = copy_bytes(fd, fdt, p->new_size, COPY_REFLINK|COPY_HOLES);
+ r = copy_bytes(fd, fdt, p->new_size, COPY_REFLINK|COPY_HOLES|COPY_TRUNCATE);
if (r < 0)
return log_error_errno(r, "Failed to copy to split partition %s: %m", p->split_path);
}
ssize_t n;
if (max_bytes <= 0)
- return 1; /* return > 0 if we hit the max_bytes limit */
+ break;
r = look_for_signals(copy_flags);
if (r < 0)
copied_something = true;
}
- return 0; /* return 0 if we hit EOF earlier than the size limit */
+ if (copy_flags & COPY_TRUNCATE) {
+ off_t off = lseek(fdt, 0, SEEK_CUR);
+ if (off < 0)
+ return -errno;
+
+ if (ftruncate(fdt, off) < 0)
+ return -errno;
+ }
+
+ return max_bytes <= 0; /* return 0 if we hit EOF earlier than the size limit */
}
static int fd_copy_symlink(
COPY_ALL_XATTRS = 1 << 13, /* Preserve all xattrs when copying, not just those in the user namespace */
COPY_HOLES = 1 << 14, /* Copy holes */
COPY_GRACEFUL_WARN = 1 << 15, /* Skip copying file types that aren't supported by the target filesystem */
+ COPY_TRUNCATE = 1 << 16, /* Truncate to current file offset after copying */
} CopyFlags;
typedef enum DenyType {