From 8ae322e5a70e3d39ac9952f4bb15718f800e133a Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Mon, 9 Apr 2012 16:53:04 +0100 Subject: Use posix_fadvise when uploading or downloading files. But ignore it if the call fails, since the file descriptor could be a non-file (eg. /dev/stdout). --- configure.ac | 1 + src/proto.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/configure.ac b/configure.ac index bfa6e5d6..3f7123be 100644 --- a/configure.ac +++ b/configure.ac @@ -212,6 +212,7 @@ AC_CHECK_FUNCS([\ ntohl \ ntohs \ posix_fallocate \ + posix_fadvise \ realpath \ removexattr \ setitimer \ diff --git a/src/proto.c b/src/proto.c index bf3feaed..16cff4fc 100644 --- a/src/proto.c +++ b/src/proto.c @@ -872,6 +872,19 @@ guestfs___send (guestfs_h *g, int proc_nr, return -1; } +static void +fadvise_sequential (int fd) +{ +#if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_SEQUENTIAL) + /* Since the fd might be a non-file, eg. /dev/stdout, just ignore + * this when it fails. It's not clear from the man page, but the + * 'advice' parameter is NOT a bitmask. You can only pass one + * parameter with each call. + */ + ignore_value (posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL)); +#endif +} + static int send_file_chunk (guestfs_h *g, int cancel, const char *buf, size_t len); static int send_file_data (guestfs_h *g, const char *buf, size_t len); static int send_file_cancellation (guestfs_h *g); @@ -898,6 +911,8 @@ guestfs___send_file (guestfs_h *g, const char *filename) return -1; } + fadvise_sequential (fd); + /* Send file in chunked encoding. */ while (!g->user_cancel) { r = read (fd, buf, sizeof buf); @@ -1131,6 +1146,8 @@ guestfs___recv_file (guestfs_h *g, const char *filename) goto cancel; } + fadvise_sequential (fd); + /* Receive the file in chunked encoding. */ while ((r = receive_file_data (g, &buf)) > 0) { if (xwrite (fd, buf, r) == -1) { -- cgit