mirror of
https://github.com/torvalds/linux.git
synced 2024-10-23 05:30:55 +00:00
initramfs: switch initramfs unpacking to struct file based APIs
There is no good reason to mess with file descriptors from in-kernel code, switch the initramfs unpacking to struct file based write instead. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
b2a74d5f9d
commit
bf6419e4d5
|
@ -13,13 +13,14 @@
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
|
|
||||||
static ssize_t __init xwrite(int fd, const char *p, size_t count)
|
static ssize_t __init xwrite(struct file *file, const char *p, size_t count,
|
||||||
|
loff_t *pos)
|
||||||
{
|
{
|
||||||
ssize_t out = 0;
|
ssize_t out = 0;
|
||||||
|
|
||||||
/* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */
|
/* sys_write only can write MAX_RW_COUNT aka 2G-4K bytes at most */
|
||||||
while (count) {
|
while (count) {
|
||||||
ssize_t rv = ksys_write(fd, p, count);
|
ssize_t rv = kernel_write(file, p, count, pos);
|
||||||
|
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
if (rv == -EINTR || rv == -EAGAIN)
|
if (rv == -EINTR || rv == -EAGAIN)
|
||||||
|
@ -317,7 +318,8 @@ static int __init maybe_link(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __initdata int wfd;
|
static __initdata struct file *wfile;
|
||||||
|
static __initdata loff_t wfile_pos;
|
||||||
|
|
||||||
static int __init do_name(void)
|
static int __init do_name(void)
|
||||||
{
|
{
|
||||||
|
@ -334,16 +336,17 @@ static int __init do_name(void)
|
||||||
int openflags = O_WRONLY|O_CREAT;
|
int openflags = O_WRONLY|O_CREAT;
|
||||||
if (ml != 1)
|
if (ml != 1)
|
||||||
openflags |= O_TRUNC;
|
openflags |= O_TRUNC;
|
||||||
wfd = ksys_open(collected, openflags, mode);
|
wfile = filp_open(collected, openflags, mode);
|
||||||
|
if (IS_ERR(wfile))
|
||||||
|
return 0;
|
||||||
|
wfile_pos = 0;
|
||||||
|
|
||||||
if (wfd >= 0) {
|
vfs_fchown(wfile, uid, gid);
|
||||||
ksys_fchown(wfd, uid, gid);
|
vfs_fchmod(wfile, mode);
|
||||||
ksys_fchmod(wfd, mode);
|
if (body_len)
|
||||||
if (body_len)
|
vfs_truncate(&wfile->f_path, body_len);
|
||||||
ksys_ftruncate(wfd, body_len);
|
vcollected = kstrdup(collected, GFP_KERNEL);
|
||||||
vcollected = kstrdup(collected, GFP_KERNEL);
|
state = CopyFile;
|
||||||
state = CopyFile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (S_ISDIR(mode)) {
|
} else if (S_ISDIR(mode)) {
|
||||||
ksys_mkdir(collected, mode);
|
ksys_mkdir(collected, mode);
|
||||||
|
@ -365,16 +368,16 @@ static int __init do_name(void)
|
||||||
static int __init do_copy(void)
|
static int __init do_copy(void)
|
||||||
{
|
{
|
||||||
if (byte_count >= body_len) {
|
if (byte_count >= body_len) {
|
||||||
if (xwrite(wfd, victim, body_len) != body_len)
|
if (xwrite(wfile, victim, body_len, &wfile_pos) != body_len)
|
||||||
error("write error");
|
error("write error");
|
||||||
ksys_close(wfd);
|
fput(wfile);
|
||||||
do_utime(vcollected, mtime);
|
do_utime(vcollected, mtime);
|
||||||
kfree(vcollected);
|
kfree(vcollected);
|
||||||
eat(body_len);
|
eat(body_len);
|
||||||
state = SkipIt;
|
state = SkipIt;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
if (xwrite(wfd, victim, byte_count) != byte_count)
|
if (xwrite(wfile, victim, byte_count, &wfile_pos) != byte_count)
|
||||||
error("write error");
|
error("write error");
|
||||||
body_len -= byte_count;
|
body_len -= byte_count;
|
||||||
eat(byte_count);
|
eat(byte_count);
|
||||||
|
@ -576,21 +579,23 @@ static inline bool kexec_free_initrd(void)
|
||||||
static void __init populate_initrd_image(char *err)
|
static void __init populate_initrd_image(char *err)
|
||||||
{
|
{
|
||||||
ssize_t written;
|
ssize_t written;
|
||||||
int fd;
|
struct file *file;
|
||||||
|
loff_t pos = 0;
|
||||||
|
|
||||||
unpack_to_rootfs(__initramfs_start, __initramfs_size);
|
unpack_to_rootfs(__initramfs_start, __initramfs_size);
|
||||||
|
|
||||||
printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n",
|
printk(KERN_INFO "rootfs image is not initramfs (%s); looks like an initrd\n",
|
||||||
err);
|
err);
|
||||||
fd = ksys_open("/initrd.image", O_WRONLY | O_CREAT, 0700);
|
file = filp_open("/initrd.image", O_WRONLY | O_CREAT, 0700);
|
||||||
if (fd < 0)
|
if (IS_ERR(file))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
written = xwrite(fd, (char *)initrd_start, initrd_end - initrd_start);
|
written = xwrite(file, (char *)initrd_start, initrd_end - initrd_start,
|
||||||
|
&pos);
|
||||||
if (written != initrd_end - initrd_start)
|
if (written != initrd_end - initrd_start)
|
||||||
pr_err("/initrd.image: incomplete write (%zd != %ld)\n",
|
pr_err("/initrd.image: incomplete write (%zd != %ld)\n",
|
||||||
written, initrd_end - initrd_start);
|
written, initrd_end - initrd_start);
|
||||||
ksys_close(fd);
|
fput(file);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLK_DEV_RAM */
|
#endif /* CONFIG_BLK_DEV_RAM */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user