]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #27882 from DaanDeMeyer/repart-truncate
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 7 Jun 2023 11:32:11 +0000 (13:32 +0200)
committerGitHub <noreply@github.com>
Wed, 7 Jun 2023 11:32:11 +0000 (13:32 +0200)
copy: Add COPY_TRUNCATE

src/partition/repart.c
src/shared/copy.c
src/shared/copy.h

index fe471d601c048c70ca51761bf355fdc91c782d27..4cf4e4c1f75320365644797bb702c3c6b7a8875f 100644 (file)
@@ -4185,14 +4185,14 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
                                                 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",
@@ -4225,7 +4225,7 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
                         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);
 
@@ -5048,7 +5048,7 @@ static int context_split(Context *context) {
                 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);
         }
index 3216607ef8f30ffd957b5e937b66c45a0e0418bd..6b9d4b99423056f98f17c67f70eb05cb077fd347 100644 (file)
@@ -245,7 +245,7 @@ int copy_bytes_full(
                 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)
@@ -468,7 +468,16 @@ int copy_bytes_full(
                 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(
index 9a0df9f4f5328265f104433698b96f2778024205..da084b66f299e8925499a928c6bf31300c8960a1 100644 (file)
@@ -28,6 +28,7 @@ typedef enum CopyFlags {
         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 {