aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--init/initramfs.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/init/initramfs.c b/init/initramfs.c
index a8497fab1c3d..4f276b6a167b 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -19,6 +19,29 @@
19#include <linux/syscalls.h> 19#include <linux/syscalls.h>
20#include <linux/utime.h> 20#include <linux/utime.h>
21 21
22static ssize_t __init xwrite(int fd, const char *p, size_t count)
23{
24 ssize_t out = 0;
25
26 /* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */
27 while (count) {
28 ssize_t rv = sys_write(fd, p, count);
29
30 if (rv < 0) {
31 if (rv == -EINTR || rv == -EAGAIN)
32 continue;
33 return out ? out : rv;
34 } else if (rv == 0)
35 break;
36
37 p += rv;
38 out += rv;
39 count -= rv;
40 }
41
42 return out;
43}
44
22static __initdata char *message; 45static __initdata char *message;
23static void __init error(char *x) 46static void __init error(char *x)
24{ 47{
@@ -346,7 +369,7 @@ static int __init do_name(void)
346static int __init do_copy(void) 369static int __init do_copy(void)
347{ 370{
348 if (count >= body_len) { 371 if (count >= body_len) {
349 sys_write(wfd, victim, body_len); 372 xwrite(wfd, victim, body_len);
350 sys_close(wfd); 373 sys_close(wfd);
351 do_utime(vcollected, mtime); 374 do_utime(vcollected, mtime);
352 kfree(vcollected); 375 kfree(vcollected);
@@ -354,7 +377,7 @@ static int __init do_copy(void)
354 state = SkipIt; 377 state = SkipIt;
355 return 0; 378 return 0;
356 } else { 379 } else {
357 sys_write(wfd, victim, count); 380 xwrite(wfd, victim, count);
358 body_len -= count; 381 body_len -= count;
359 eat(count); 382 eat(count);
360 return 1; 383 return 1;
@@ -603,8 +626,13 @@ static int __init populate_rootfs(void)
603 fd = sys_open("/initrd.image", 626 fd = sys_open("/initrd.image",
604 O_WRONLY|O_CREAT, 0700); 627 O_WRONLY|O_CREAT, 0700);
605 if (fd >= 0) { 628 if (fd >= 0) {
606 sys_write(fd, (char *)initrd_start, 629 ssize_t written = xwrite(fd, (char *)initrd_start,
607 initrd_end - initrd_start); 630 initrd_end - initrd_start);
631
632 if (written != initrd_end - initrd_start)
633 pr_err("/initrd.image: incomplete write (%zd != %ld)\n",
634 written, initrd_end - initrd_start);
635
608 sys_close(fd); 636 sys_close(fd);
609 free_initrd(); 637 free_initrd();
610 } 638 }