load_ramdisk_or_iso: use sendfile when possible
This commit is contained in:
parent
705cac1f94
commit
5a10623827
42
tools.c
42
tools.c
@ -35,6 +35,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <sys/mman.h> /* memfd_create */
|
||||
|
||||
@ -362,7 +363,7 @@ static int write_exactly(int fd, const char *buf, size_t len)
|
||||
* @return 0 on success, -1 on error
|
||||
* @note if size == 0 keep copying until EOF on src_fd
|
||||
*/
|
||||
static int copy_loop(int dst_fd, int src_fd, unsigned long size)
|
||||
static int copy_loop_dumb(int dst_fd, int src_fd, unsigned long size)
|
||||
{
|
||||
char buf[32768];
|
||||
unsigned long bytes_written = 0;
|
||||
@ -390,6 +391,45 @@ static int copy_loop(int dst_fd, int src_fd, unsigned long size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_loop_sendfile(int dst_fd, int src_fd, unsigned long size)
|
||||
{
|
||||
ssize_t dl;
|
||||
size_t chunk = 1024*1024;
|
||||
unsigned long bytes_written = 0;
|
||||
while (size > 0) {
|
||||
dl = sendfile(dst_fd, src_fd, NULL, chunk < size ? chunk : size);
|
||||
if (dl < 0) {
|
||||
log_message("%s: sendfile: error %s", __func__, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
size -= (unsigned long)dl;
|
||||
bytes_written += (unsigned long)dl;
|
||||
update_progression((int)BYTES2MB(bytes_written));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_mmapable(int fd)
|
||||
{
|
||||
void *dummy;
|
||||
size_t len = 65536; /* don't bother to figure out page size */
|
||||
dummy = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (dummy != MAP_FAILED) {
|
||||
munmap(dummy, len);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int copy_loop(int dst_fd, int src_fd, unsigned long size)
|
||||
{
|
||||
if (!size || !is_mmapable(src_fd))
|
||||
return copy_loop_dumb(dst_fd, src_fd, size);
|
||||
else
|
||||
return copy_loop_sendfile(dst_fd, src_fd, size);
|
||||
}
|
||||
|
||||
int make_ramfd(unsigned long size)
|
||||
{
|
||||
int ramfd;
|
||||
|
Loading…
x
Reference in New Issue
Block a user