From: David Disseldorp <ddiss@suse.de>
To: linux-kbuild@vger.kernel.org, linux-fsdevel@vger.kernel.org
Cc: linux-next@vger.kernel.org, David Disseldorp <ddiss@suse.de>
Subject: [PATCH v2 1/7] gen_init_cpio: write to fd instead of stdout stream
Date: Thu, 14 Aug 2025 15:17:59 +1000 [thread overview]
Message-ID: <20250814054818.7266-2-ddiss@suse.de> (raw)
In-Reply-To: <20250814054818.7266-1-ddiss@suse.de>
In preparation for more efficient archiving using copy_file_range(),
switch from writing archive data to stdout to using STDOUT_FILENO and
I/O via write(), dprintf(), etc.
Basic I/O error handling is added to cover cases such as ENOSPC. Partial
writes are treated as errors.
Signed-off-by: David Disseldorp <ddiss@suse.de>
---
usr/gen_init_cpio.c | 139 ++++++++++++++++++++++++++------------------
1 file changed, 81 insertions(+), 58 deletions(-)
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index edcdb8abfa31c..d8779fe4b8f1f 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -23,64 +23,71 @@
#define xstr(s) #s
#define str(s) xstr(s)
#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define CPIO_HDR_LEN 110
+#define padlen(_off, _align) (((_align) - ((_off) & ((_align) - 1))) % (_align))
+static char padding[512];
static unsigned int offset;
static unsigned int ino = 721;
static time_t default_mtime;
static bool do_file_mtime;
static bool do_csum = false;
+static int outfd = STDOUT_FILENO;
struct file_handler {
const char *type;
int (*handler)(const char *line);
};
-static void push_string(const char *name)
+static int push_string(const char *name)
{
unsigned int name_len = strlen(name) + 1;
+ ssize_t len;
+
+ len = write(outfd, name, name_len);
+ if (len != name_len)
+ return -1;
- fputs(name, stdout);
- putchar(0);
offset += name_len;
+ return 0;
}
-static void push_pad (void)
+static int push_pad(size_t padlen)
{
- while (offset & 3) {
- putchar(0);
- offset++;
- }
+ ssize_t len = 0;
+
+ if (!padlen)
+ return 0;
+
+ if (padlen < sizeof(padding))
+ len = write(outfd, padding, padlen);
+ if (len != padlen)
+ return -1;
+
+ offset += padlen;
+ return 0;
}
-static void push_rest(const char *name)
+static int push_rest(const char *name)
{
unsigned int name_len = strlen(name) + 1;
- unsigned int tmp_ofs;
+ ssize_t len;
- fputs(name, stdout);
- putchar(0);
- offset += name_len;
+ len = write(outfd, name, name_len);
+ if (len != name_len)
+ return -1;
- tmp_ofs = name_len + 110;
- while (tmp_ofs & 3) {
- putchar(0);
- offset++;
- tmp_ofs++;
- }
-}
+ offset += name_len;
-static void push_hdr(const char *s)
-{
- fputs(s, stdout);
- offset += 110;
+ return push_pad(padlen(name_len + CPIO_HDR_LEN, 4));
}
-static void cpio_trailer(void)
+static int cpio_trailer(void)
{
- char s[256];
const char name[] = "TRAILER!!!";
+ int len;
- sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
+ len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "070701", /* magic */
0, /* ino */
@@ -96,23 +103,24 @@ static void cpio_trailer(void)
0, /* rminor */
(unsigned)strlen(name)+1, /* namesize */
0); /* chksum */
- push_hdr(s);
- push_rest(name);
+ offset += len;
- while (offset % 512) {
- putchar(0);
- offset++;
- }
+ if (len != CPIO_HDR_LEN
+ || push_rest(name) < 0
+ || push_pad(padlen(offset, 512)) < 0)
+ return -1;
+
+ return 0;
}
static int cpio_mkslink(const char *name, const char *target,
unsigned int mode, uid_t uid, gid_t gid)
{
- char s[256];
+ int len;
if (name[0] == '/')
name++;
- sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
+ len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "070701", /* magic */
ino++, /* ino */
@@ -128,12 +136,17 @@ static int cpio_mkslink(const char *name, const char *target,
0, /* rminor */
(unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
- push_hdr(s);
- push_string(name);
- push_pad();
- push_string(target);
- push_pad();
+ offset += len;
+
+ if (len != CPIO_HDR_LEN
+ || push_string(name) < 0
+ || push_pad(padlen(offset, 4)) < 0
+ || push_string(target) < 0
+ || push_pad(padlen(offset, 4)) < 0)
+ return -1;
+
return 0;
+
}
static int cpio_mkslink_line(const char *line)
@@ -157,11 +170,11 @@ static int cpio_mkslink_line(const char *line)
static int cpio_mkgeneric(const char *name, unsigned int mode,
uid_t uid, gid_t gid)
{
- char s[256];
+ int len;
if (name[0] == '/')
name++;
- sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
+ len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "070701", /* magic */
ino++, /* ino */
@@ -177,8 +190,12 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
0, /* rminor */
(unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
- push_hdr(s);
- push_rest(name);
+ offset += len;
+
+ if (len != CPIO_HDR_LEN
+ || push_rest(name) < 0)
+ return -1;
+
return 0;
}
@@ -246,7 +263,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
uid_t uid, gid_t gid, char dev_type,
unsigned int maj, unsigned int min)
{
- char s[256];
+ int len;
if (dev_type == 'b')
mode |= S_IFBLK;
@@ -255,7 +272,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
if (name[0] == '/')
name++;
- sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
+ len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08X%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "070701", /* magic */
ino++, /* ino */
@@ -271,8 +288,12 @@ static int cpio_mknod(const char *name, unsigned int mode,
min, /* rminor */
(unsigned)strlen(name) + 1,/* namesize */
0); /* chksum */
- push_hdr(s);
- push_rest(name);
+ offset += len;
+
+ if (len != CPIO_HDR_LEN
+ || push_rest(name) < 0)
+ return -1;
+
return 0;
}
@@ -324,11 +345,9 @@ static int cpio_mkfile(const char *name, const char *location,
unsigned int mode, uid_t uid, gid_t gid,
unsigned int nlinks)
{
- char s[256];
struct stat buf;
unsigned long size;
- int file;
- int retval;
+ int file, retval, len;
int rc = -1;
time_t mtime;
int namesize;
@@ -386,7 +405,7 @@ static int cpio_mkfile(const char *name, const char *location,
if (name[0] == '/')
name++;
namesize = strlen(name) + 1;
- sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
+ len = dprintf(outfd, "%s%08X%08X%08lX%08lX%08X%08lX"
"%08lX%08X%08X%08X%08X%08X%08X",
do_csum ? "070702" : "070701", /* magic */
ino, /* ino */
@@ -402,9 +421,12 @@ static int cpio_mkfile(const char *name, const char *location,
0, /* rminor */
namesize, /* namesize */
size ? csum : 0); /* chksum */
- push_hdr(s);
- push_string(name);
- push_pad();
+ offset += len;
+
+ if (len != CPIO_HDR_LEN
+ || push_string(name) < 0
+ || push_pad(padlen(offset, 4)) < 0)
+ goto error;
while (size) {
unsigned char filebuf[65536];
@@ -417,14 +439,15 @@ static int cpio_mkfile(const char *name, const char *location,
goto error;
}
- if (fwrite(filebuf, this_read, 1, stdout) != 1) {
+ if (write(outfd, filebuf, this_read) != this_read) {
fprintf(stderr, "writing filebuf failed\n");
goto error;
}
offset += this_read;
size -= this_read;
}
- push_pad();
+ if (push_pad(padlen(offset, 4)) < 0)
+ goto error;
name += namesize;
}
@@ -691,7 +714,7 @@ int main (int argc, char *argv[])
}
}
if (ec == 0)
- cpio_trailer();
+ ec = cpio_trailer();
exit(ec);
}
--
2.43.0
next prev parent reply other threads:[~2025-08-14 5:48 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-14 5:17 [PATCH v2 0/7] gen_init_cpio: add copy_file_range / reflink support David Disseldorp
2025-08-14 5:17 ` David Disseldorp [this message]
2025-08-18 18:40 ` [PATCH v2 1/7] gen_init_cpio: write to fd instead of stdout stream Nicolas Schier
2025-08-14 5:18 ` [PATCH v2 2/7] gen_init_cpio: support -o <output_path> parameter David Disseldorp
2025-08-18 18:40 ` Nicolas Schier
2025-08-14 5:18 ` [PATCH v2 3/7] gen_init_cpio: attempt copy_file_range for file data David Disseldorp
2025-08-18 18:40 ` Nicolas Schier
2025-08-19 0:20 ` David Disseldorp
2025-08-14 5:18 ` [PATCH v2 4/7] gen_init_cpio: avoid duplicate strlen calls David Disseldorp
2025-08-14 5:18 ` [PATCH v2 5/7] gen_initramfs.sh: use gen_init_cpio -o parameter David Disseldorp
2025-08-18 18:40 ` Nicolas Schier
2025-08-14 5:18 ` [PATCH v2 6/7] docs: initramfs: file data alignment via name padding David Disseldorp
2025-08-14 5:18 ` [PATCH v2 7/7] gen_init_cpio: add -a <data_align> as reflink optimization David Disseldorp
2025-08-18 19:23 ` Nicolas Schier
2025-08-21 8:10 ` David Disseldorp
2025-08-18 18:40 ` [PATCH v2 0/7] gen_init_cpio: add copy_file_range / reflink support Nicolas Schier
2025-08-18 23:46 ` David Disseldorp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250814054818.7266-2-ddiss@suse.de \
--to=ddiss@suse.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-next@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.