X-Git-Url: http://git.pld-linux.org/?p=packages%2Frsync.git;a=blobdiff_plain;f=rsync-fadvise.patch;fp=rsync-fadvise.patch;h=24e1f9bfc52f8c83264c052e8ea158b163c936f7;hp=0000000000000000000000000000000000000000;hb=9cb7906fb8c9c2e334ac71ede1ac2a8ad21fde0f;hpb=c852e1416ec8285777677ed6b1fe3737ed603b50 diff --git a/rsync-fadvise.patch b/rsync-fadvise.patch new file mode 100644 index 0000000..24e1f9b --- /dev/null +++ b/rsync-fadvise.patch @@ -0,0 +1,568 @@ +diff -ru rsync-3.1.2.orig/checksum.c rsync-3.1.2/checksum.c +--- rsync-3.1.2.orig/checksum.c 2015-08-08 22:47:03.000000000 +0300 ++++ rsync-3.1.2/checksum.c 2016-10-24 15:38:28.002415712 +0300 +@@ -24,6 +24,9 @@ + extern int checksum_seed; + extern int protocol_version; + extern int proper_seed_order; ++#ifdef WITH_DROP_CACHE ++#define close(fd) fadv_close(fd) ++#endif + + /* + a simple 32 bit checksum that can be upadted from either end +diff -ru rsync-3.1.2.orig/cleanup.c rsync-3.1.2/cleanup.c +--- rsync-3.1.2.orig/cleanup.c 2015-08-08 22:47:03.000000000 +0300 ++++ rsync-3.1.2/cleanup.c 2016-10-24 15:38:28.002415712 +0300 +@@ -53,7 +53,11 @@ + int fd; + int ret; + STRUCT_STAT st; +- ++#endif ++#ifdef WITH_DROP_CACHE ++ fadv_close_all(); ++#endif ++#ifdef SHUTDOWN_ALL_SOCKETS + max_fd = sysconf(_SC_OPEN_MAX) - 1; + for (fd = max_fd; fd >= 0; fd--) { + if ((ret = do_fstat(fd, &st)) == 0) { +diff -ru rsync-3.1.2.orig/config.h.in rsync-3.1.2/config.h.in +--- rsync-3.1.2.orig/config.h.in 2015-12-21 22:20:53.000000000 +0200 ++++ rsync-3.1.2/config.h.in 2016-10-24 15:38:28.006415712 +0300 +@@ -275,6 +275,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_MEMORY_H + ++/* Define to 1 if you have the `mincore' function. */ ++#undef HAVE_MINCORE ++ + /* Define to 1 if you have the `mkfifo' function. */ + #undef HAVE_MKFIFO + +@@ -287,6 +290,9 @@ + /* Define to 1 if the system has the type `mode_t'. */ + #undef HAVE_MODE_T + ++/* Define to 1 if you have the `mmap' function. */ ++#undef HAVE_MMAP ++ + /* Define to 1 if you have the `mtrace' function. */ + #undef HAVE_MTRACE + +@@ -329,6 +335,9 @@ + /* true if you have posix ACLs */ + #undef HAVE_POSIX_ACLS + ++/* Define to 1 if you have the `posix_fadvise64' function. */ ++#undef HAVE_POSIX_FADVISE64 ++ + /* Define to 1 if you have the `posix_fallocate' function. */ + #undef HAVE_POSIX_FALLOCATE + +diff -ru rsync-3.1.2.orig/configure.ac rsync-3.1.2/configure.ac +--- rsync-3.1.2.orig/configure.ac 2015-12-21 22:00:49.000000000 +0200 ++++ rsync-3.1.2/configure.ac 2016-10-24 15:38:28.006415712 +0300 +@@ -598,6 +598,7 @@ + setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \ + seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \ + extattr_get_link sigaction sigprocmask setattrlist getgrouplist \ ++ mmap mincore posix_fadvise64 \ + initgroups utimensat posix_fallocate attropen setvbuf usleep) + + dnl cygwin iconv.h defines iconv_open as libiconv_open +diff -ru rsync-3.1.2.orig/configure.sh rsync-3.1.2/configure.sh +--- rsync-3.1.2.orig/configure.sh 2015-12-21 22:20:53.000000000 +0200 ++++ rsync-3.1.2/configure.sh 2016-10-24 15:38:28.006415712 +0300 +@@ -7692,6 +7692,7 @@ + setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \ + seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \ + extattr_get_link sigaction sigprocmask setattrlist getgrouplist \ ++ mmap mincore posix_fadvise64 \ + initgroups utimensat posix_fallocate attropen setvbuf usleep + do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +diff -ru rsync-3.1.2.orig/fileio.c rsync-3.1.2/fileio.c +--- rsync-3.1.2.orig/fileio.c 2015-08-08 22:47:03.000000000 +0300 ++++ rsync-3.1.2/fileio.c 2016-10-24 15:38:28.006415712 +0300 +@@ -51,7 +51,7 @@ + ret = -1; + else { + do { +- ret = write(f, "", 1); ++ ret = fadv_write(f, "", 1); + } while (ret < 0 && errno == EINTR); + + ret = ret <= 0 ? -1 : 0; +@@ -81,7 +81,7 @@ + do_lseek(f, sparse_seek, SEEK_CUR); + sparse_seek = l2; + +- while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) { ++ while ((ret = fadv_write(f, buf + l1, len - (l1+l2))) <= 0) { + if (ret < 0 && errno == EINTR) + continue; + sparse_seek = 0; +@@ -107,7 +107,7 @@ + char *bp = wf_writeBuf; + + while (wf_writeBufCnt > 0) { +- if ((ret = write(f, bp, wf_writeBufCnt)) < 0) { ++ if ((ret = fadv_write(f, bp, wf_writeBufCnt)) < 0) { + if (errno == EINTR) + continue; + return ret; +@@ -254,7 +254,7 @@ + map->p_len = window_size; + + while (read_size > 0) { +- int32 nread = read(map->fd, map->p + read_offset, read_size); ++ int32 nread = fadv_read(map->fd, map->p + read_offset, read_size); + if (nread <= 0) { + if (!map->status) + map->status = nread ? errno : ENODATA; +diff -ru rsync-3.1.2.orig/generator.c rsync-3.1.2/generator.c +--- rsync-3.1.2.orig/generator.c 2015-12-05 21:10:24.000000000 +0200 ++++ rsync-3.1.2/generator.c 2016-10-24 15:38:28.006415712 +0300 +@@ -111,6 +111,10 @@ + static int need_retouch_dir_perms; + static const char *solo_file = NULL; + ++#ifdef WITH_DROP_CACHE ++#define close(fd) fadv_close(fd) ++#endif ++ + enum nonregtype { + TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK + }; +diff -ru rsync-3.1.2.orig/options.c rsync-3.1.2/options.c +--- rsync-3.1.2.orig/options.c 2015-12-19 00:46:28.000000000 +0200 ++++ rsync-3.1.2/options.c 2016-10-24 15:38:28.006415712 +0300 +@@ -62,6 +62,9 @@ + int preserve_gid = 0; + int preserve_times = 0; + int update_only = 0; ++#ifdef WITH_DROP_CACHE ++int drop_cache = 0; ++#endif + int cvs_exclude = 0; + int dry_run = 0; + int do_xfers = 1; +@@ -680,6 +683,9 @@ + rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n"); + rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX); + rprintf(F," -u, --update skip files that are newer on the receiver\n"); ++#ifdef WITH_DROP_CACHE ++ rprintf(F," --drop-cache do not cache rsync files (POSIX_FADV_DONTNEED)\n"); ++#endif + rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n"); + rprintf(F," --append append data onto shorter files\n"); + rprintf(F," --append-verify like --append, but with old data in file checksum\n"); +@@ -914,6 +920,9 @@ + {"no-one-file-system",0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, + {"no-x", 0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 }, + {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 }, ++#ifdef WITH_DROP_CACHE ++ {"drop-cache", 0, POPT_ARG_NONE, &drop_cache, 0, 0, 0 }, ++#endif + {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, + {"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 }, + {"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 }, +@@ -1065,6 +1074,9 @@ + rprintf(F," --log-file=FILE override the \"log file\" setting\n"); + rprintf(F," --log-file-format=FMT override the \"log format\" setting\n"); + rprintf(F," --sockopts=OPTIONS specify custom TCP options\n"); ++#ifdef WITH_DROP_CACHE ++ rprintf(F," --drop-cache do not cache rsync files (POSIX_FADV_DONTNEED)\n"); ++#endif + rprintf(F," -v, --verbose increase verbosity\n"); + rprintf(F," -4, --ipv4 prefer IPv4\n"); + rprintf(F," -6, --ipv6 prefer IPv6\n"); +@@ -1089,6 +1101,9 @@ + {"log-file", 0, POPT_ARG_STRING, &logfile_name, 0, 0, 0 }, + {"log-file-format", 0, POPT_ARG_STRING, &logfile_format, 0, 0, 0 }, + {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 }, ++#ifdef WITH_DROP_CACHE ++ {"drop-cache", 0, POPT_ARG_NONE, &drop_cache, 0, 0, 0 }, ++#endif + {"sockopts", 0, POPT_ARG_STRING, &sockopts, 0, 0, 0 }, + {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, + {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 }, +@@ -2376,6 +2391,11 @@ + if (!am_sender) + args[ac++] = "--sender"; + ++#ifdef WITH_DROP_CACHE ++ if (drop_cache) ++ args[ac++] = "--drop-cache"; ++#endif ++ + x = 1; + argstr[0] = '-'; + +diff -ru rsync-3.1.2.orig/proto.h rsync-3.1.2/proto.h +--- rsync-3.1.2.orig/proto.h 2015-12-21 22:22:53.000000000 +0200 ++++ rsync-3.1.2/proto.h 2016-10-24 15:38:28.010415712 +0300 +@@ -348,6 +348,10 @@ + uid_t recv_user_name(int f, uid_t uid); + gid_t recv_group_name(int f, gid_t gid, uint16 *flags_ptr); + void recv_id_list(int f, struct file_list *flist); ++ssize_t fadv_write(int fd, const void *buf, size_t count); ++ssize_t fadv_read(int fd, void *buf, size_t count); ++void fadv_close_all(void); ++int fadv_close(int fd); + void parse_name_map(char *map, BOOL usernames); + const char *getallgroups(uid_t uid, item_list *gid_list); + void set_nonblocking(int fd); +diff -ru rsync-3.1.2.orig/receiver.c rsync-3.1.2/receiver.c +--- rsync-3.1.2.orig/receiver.c 2015-09-07 20:07:17.000000000 +0300 ++++ rsync-3.1.2/receiver.c 2016-10-24 15:38:28.010415712 +0300 +@@ -62,6 +62,10 @@ + extern struct file_list *cur_flist, *first_flist, *dir_flist; + extern filter_rule_list daemon_filter_list; + ++#ifdef WITH_DROP_CACHE ++#define close(fd) fadv_close(fd) ++#endif ++ + static struct bitbag *delayed_bits = NULL; + static int phase = 0, redoing = 0; + static flist_ndx_list batch_redo_list; +diff -ru rsync-3.1.2.orig/rsync.1 rsync-3.1.2/rsync.1 +--- rsync-3.1.2.orig/rsync.1 2015-12-21 22:22:41.000000000 +0200 ++++ rsync-3.1.2/rsync.1 2016-10-24 15:38:28.010415712 +0300 +@@ -453,6 +453,7 @@ + \-\-super receiver attempts super\-user activities + \-\-fake\-super store/recover privileged attrs using xattrs + \-S, \-\-sparse handle sparse files efficiently ++ \-\-drop\-cache drop cache continuosly using fadvise + \-\-preallocate allocate dest files before writing + \-n, \-\-dry\-run perform a trial run with no changes made + \-W, \-\-whole\-file copy files whole (w/o delta\-xfer algorithm) +@@ -1426,6 +1427,13 @@ + up less space on the destination. Conflicts with \fB\-\-inplace\fP because it\(cq\&s + not possible to overwrite data in a sparse fashion. + .IP ++.IP "\fB\-\-drop\-cache\fP" ++Stop rsync from filling up the file system cache with the files it copies\&. Without this ++option other processes, that had been crunching along happily on your system, will suddenly ++become slow as they find their data being outsed from the cache. The \fB\-\-drop\-cache\fP function ++uses posix_fadvise64 and mincore todo its work\&. It will only get compiled if configure can find posix_fadvise64 and mincore\&. ++Rsync will tries only to drop data from cache that has not been cached before. ++.IP + .IP "\fB\-\-preallocate\fP" + This tells the receiver to allocate each destination + file to its eventual size before writing data to the file. Rsync will only use +diff -ru rsync-3.1.2.orig/rsync.h rsync-3.1.2/rsync.h +--- rsync-3.1.2.orig/rsync.h 2015-08-08 22:47:03.000000000 +0300 ++++ rsync-3.1.2/rsync.h 2016-10-24 15:38:28.010415712 +0300 +@@ -1291,3 +1291,13 @@ + #ifdef MAINTAINER_MODE + const char *get_panic_action(void); + #endif ++ ++#if defined HAVE_POSIX_FADVISE64 && defined HAVE_MINCORE && defined HAVE_MMAP ++#define WITH_DROP_CACHE 1 ++#include ++int fadv_close(int fd); ++void fadv_close_all(void); ++#endif ++ ++ssize_t fadv_write(int fd, const void *buf, size_t count); ++ssize_t fadv_read(int fd, void *buf, size_t count); +diff -ru rsync-3.1.2.orig/rsync.yo rsync-3.1.2/rsync.yo +--- rsync-3.1.2.orig/rsync.yo 2015-12-21 22:00:49.000000000 +0200 ++++ rsync-3.1.2/rsync.yo 2016-10-24 15:38:28.010415712 +0300 +@@ -1244,6 +1244,17 @@ + up less space on the destination. Conflicts with bf(--inplace) because it's + not possible to overwrite data in a sparse fashion. + ++dit(bf(--drop-cache)) Stop rsync from disturbing the file system cache with ++the data from the files it copies. Without this option other processes, that ++had been crunching along happily using cached data, will suddenly become ++slow as they find their favorite data blocks data being evicted from the ++cache by the files read and written by rsync. Since rsync has to wait until ++the data is written to disk, before it can drop the cache, this option will ++slow rsync down considerably, especially with small files and short copy ++jobs. The bf(--drop-cache) function uses posix_fadvise64 and mincore todo ++its work. It will only get compiled if configure can find posix_fadvise64 ++and mincore. ++ + dit(bf(--preallocate)) This tells the receiver to allocate each destination + file to its eventual size before writing data to the file. Rsync will only use + the real filesystem-level preallocation support provided by Linux's +diff -ru rsync-3.1.2.orig/sender.c rsync-3.1.2/sender.c +--- rsync-3.1.2.orig/sender.c 2015-09-07 20:07:17.000000000 +0300 ++++ rsync-3.1.2/sender.c 2016-10-24 15:38:28.010415712 +0300 +@@ -46,6 +46,9 @@ + extern int file_old_total; + extern struct stats stats; + extern struct file_list *cur_flist, *first_flist, *dir_flist; ++#ifdef WITH_DROP_CACHE ++#define close(fd) fadv_close(fd) ++#endif + + BOOL extra_flist_sending_enabled; + +diff -ru rsync-3.1.2.orig/t_unsafe.c rsync-3.1.2/t_unsafe.c +--- rsync-3.1.2.orig/t_unsafe.c 2015-08-08 22:47:03.000000000 +0300 ++++ rsync-3.1.2/t_unsafe.c 2016-10-24 15:38:28.010415712 +0300 +@@ -24,6 +24,7 @@ + #include "rsync.h" + + int dry_run = 0; ++int drop_cache = 0; + int am_root = 0; + int am_sender = 1; + int read_only = 0; +diff -ru rsync-3.1.2.orig/util.c rsync-3.1.2/util.c +--- rsync-3.1.2.orig/util.c 2015-12-21 20:54:02.000000000 +0200 ++++ rsync-3.1.2/util.c 2016-10-24 15:38:28.014415712 +0300 +@@ -37,6 +37,10 @@ + extern unsigned int module_dirlen; + extern char *partial_dir; + extern filter_rule_list daemon_filter_list; ++#ifdef WITH_DROP_CACHE ++#include ++extern int drop_cache; ++#endif + + int sanitize_paths = 0; + +@@ -44,6 +48,218 @@ + unsigned int curr_dir_len; + int curr_dir_depth; /* This is only set for a sanitizing daemon. */ + ++#ifdef WITH_DROP_CACHE ++#define FADV_BUFFER_SIZE 1024*1024*16 ++ ++static struct stat fadv_fd_stat[1024]; ++static off_t fadv_fd_pos[1024]; ++static unsigned char *fadv_core_ptr[1024]; ++static int fadv_max_fd = 0; ++static int fadv_close_ring_tail = 0; ++static int fadv_close_ring_head = 0; ++static int fadv_close_ring_size = 0; ++static int fadv_close_ring[1024]; ++static int fadv_close_buffer_size = 0; ++static size_t fadv_pagesize; ++ ++static void fadv_fd_init_func(void) ++{ ++ static int fadv_fd_init = 0; ++ if (fadv_fd_init == 0){ ++ int i; ++ fadv_fd_init = 1; ++ fadv_pagesize = getpagesize(); ++ if (fadv_max_fd == 0){ ++ fadv_max_fd = sysconf(_SC_OPEN_MAX) - 20; ++ if (fadv_max_fd < 0) ++ fadv_max_fd = 1; ++ if (fadv_max_fd > 1000) ++ fadv_max_fd = 1000; ++ } ++ for (i=0;i fadv_max_fd){ ++ return; ++ } ++ if ( fadv_fd_pos[fd] < pos - FADV_BUFFER_SIZE ) { ++ if (sync) { ++ /* if the file is not flushed to disk before calling fadvise, ++ then the Cache will not be freed and the advise gets ignored ++ this does give a severe hit on performance. If only there ++ was a way to mark cache so that it gets release once the data ++ is written to disk. */ ++ fdatasync(fd); ++ } ++ if (fadv_core_ptr[fd] != NULL) { ++ size_t pi; ++ if (pos < fadv_fd_stat[fd].st_size){ ++ for (pi = fadv_fd_pos[fd]/fadv_pagesize; pi <= pos/fadv_pagesize; pi++) { ++ if (! (fadv_core_ptr[fd][pi]&1)) { ++ posix_fadvise64(fd, pi*fadv_pagesize, fadv_pagesize, POSIX_FADV_DONTNEED); ++ } ++ } ++ } else { ++ posix_fadvise64(fd, fadv_fd_stat[fd].st_size, pos-fadv_fd_stat[fd].st_size, POSIX_FADV_DONTNEED); ++ } ++ } else { ++ posix_fadvise64(fd, 0, pos, POSIX_FADV_DONTNEED); ++ } ++ fadv_fd_pos[fd] = pos; ++ } ++} ++ ++#endif ++ ++ssize_t fadv_write(int fd, const void *buf, size_t count) ++{ ++ int ret = write(fd, buf, count); ++#ifdef WITH_DROP_CACHE ++ if (drop_cache) { ++ fadv_drop(fd,1); ++ } ++#endif ++ return ret; ++} ++ ++ssize_t fadv_read(int fd, void *buf, size_t count) ++{ ++ int ret; ++#ifdef WITH_DROP_CACHE ++ if (drop_cache) { ++ fadv_fd_init_func(); ++ fadv_get_core(fd); ++ } ++#endif ++ ret = read(fd, buf, count); ++#ifdef WITH_DROP_CACHE ++ if (drop_cache) { ++ fadv_drop(fd,0); ++ } ++#endif ++ return ret; ++} ++ ++#ifdef WITH_DROP_CACHE ++void fadv_close_all(void) ++{ ++ /* printf ("%i\n",fadv_close_ring_size); */ ++ while (fadv_close_ring_size > 0){ ++ fdatasync(fadv_close_ring[fadv_close_ring_tail]); ++ if (fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]]){ ++ size_t pi; ++ for (pi = 0; pi <= fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_size/fadv_pagesize; pi++) { ++ if (!(fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]][pi]&1)) { ++ posix_fadvise64(fadv_close_ring[fadv_close_ring_tail], pi*fadv_pagesize, fadv_pagesize, POSIX_FADV_DONTNEED); ++ } ++ } ++ /* if the file has grown, drop the rest */ ++ //posix_fadvise64(fadv_close_ring[fadv_close_ring_tail], fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_size,0, POSIX_FADV_DONTNEED); ++ ++ free(fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]]); ++ fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]] = NULL; ++ fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_size = 0; ++ fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_ino = 0; ++ fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_dev = 0; ++ } else { ++ posix_fadvise64(fadv_close_ring[fadv_close_ring_tail], 0, 0,POSIX_FADV_DONTNEED); ++ } ++ fadv_close_ring_size--; ++ close(fadv_close_ring[fadv_close_ring_tail]); ++ fadv_close_ring_tail = (fadv_close_ring_tail + 1) % fadv_max_fd; ++ fadv_close_buffer_size = 0; ++ } ++} ++ ++int fadv_close(int fd) ++{ ++ if (drop_cache) { ++ /* if the file is not flushed to disk before calling fadvise, ++ then the Cache will not be freed and the advise gets ignored ++ this does give a severe hit on performance. So instead of doing ++ it right away, we save us a copy of the filehandle and do it ++ some time before we are out of filehandles. This speeds ++ up operation for small files massively. It is directly ++ related to the number of spare file handles you have. */ ++ int newfd = dup(fd); ++ off_t pos = lseek(fd,0,SEEK_CUR); ++ fadv_fd_init_func(); ++ fadv_core_ptr[newfd] = fadv_core_ptr[fd]; ++ fadv_fd_stat[newfd].st_size = fadv_fd_stat[fd].st_size ; ++ fadv_core_ptr[fd] = NULL; ++ fadv_close_buffer_size += pos - fadv_fd_pos[fd]; ++ fadv_close_ring[fadv_close_ring_head] = newfd; ++ fadv_close_ring_head = (fadv_close_ring_head + 1) % fadv_max_fd; ++ fadv_close_ring_size ++; ++ if (fadv_close_ring_size == fadv_max_fd || fadv_close_buffer_size > 1024*1024 ){ ++ /* it seems fastest to drop things 'in groups' */ ++ fadv_close_all(); ++ } ++ }; ++ return close(fd); ++} ++ ++ ++#define close(fd) fadv_close(fd) ++#endif ++ + /* Set a fd into nonblocking mode. */ + void set_nonblocking(int fd) + { +@@ -273,7 +489,7 @@ + + total_written = 0; + while (len > 0) { +- int written = write(desc, ptr, len); ++ int written = fadv_write(desc, ptr, len); + if (written < 0) { + if (errno == EINTR) + continue; +@@ -305,7 +521,7 @@ + return len; + + do { +- n_chars = read(desc, ptr, len); ++ n_chars = fadv_read(desc, ptr, len); + } while (n_chars < 0 && errno == EINTR); + + return n_chars;