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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).