]> git.pld-linux.org Git - packages/rsync.git/blame - rsync-fadvise.patch
update fadvise patch to 3.1.3
[packages/rsync.git] / rsync-fadvise.patch
CommitLineData
b913b1dd
ER
1--- rsync-3.1.3/checksum.c~ 2018-01-15 05:55:07.000000000 +0200
2+++ rsync-3.1.3/checksum.c 2018-12-04 00:27:15.382240696 +0200
3@@ -26,6 +26,10 @@
9cb7906f 4 extern int proper_seed_order;
b913b1dd
ER
5 extern char *checksum_choice;
6
9cb7906f
ER
7+#ifdef WITH_DROP_CACHE
8+#define close(fd) fadv_close(fd)
9+#endif
b913b1dd
ER
10+
11 #define CSUM_NONE 0
12 #define CSUM_MD4_ARCHAIC 1
13 #define CSUM_MD4_BUSTED 2
9cb7906f
ER
14--- rsync-3.1.2.orig/cleanup.c 2015-08-08 22:47:03.000000000 +0300
15+++ rsync-3.1.2/cleanup.c 2016-10-24 15:38:28.002415712 +0300
16@@ -53,7 +53,11 @@
17 int fd;
18 int ret;
19 STRUCT_STAT st;
20-
21+#endif
22+#ifdef WITH_DROP_CACHE
23+ fadv_close_all();
24+#endif
25+#ifdef SHUTDOWN_ALL_SOCKETS
26 max_fd = sysconf(_SC_OPEN_MAX) - 1;
27 for (fd = max_fd; fd >= 0; fd--) {
28 if ((ret = do_fstat(fd, &st)) == 0) {
29diff -ru rsync-3.1.2.orig/config.h.in rsync-3.1.2/config.h.in
30--- rsync-3.1.2.orig/config.h.in 2015-12-21 22:20:53.000000000 +0200
31+++ rsync-3.1.2/config.h.in 2016-10-24 15:38:28.006415712 +0300
32@@ -275,6 +275,9 @@
33 /* Define to 1 if you have the <memory.h> header file. */
34 #undef HAVE_MEMORY_H
35
36+/* Define to 1 if you have the `mincore' function. */
37+#undef HAVE_MINCORE
38+
39 /* Define to 1 if you have the `mkfifo' function. */
40 #undef HAVE_MKFIFO
41
42@@ -287,6 +290,9 @@
43 /* Define to 1 if the system has the type `mode_t'. */
44 #undef HAVE_MODE_T
45
46+/* Define to 1 if you have the `mmap' function. */
47+#undef HAVE_MMAP
48+
49 /* Define to 1 if you have the `mtrace' function. */
50 #undef HAVE_MTRACE
51
52@@ -329,6 +335,9 @@
53 /* true if you have posix ACLs */
54 #undef HAVE_POSIX_ACLS
55
56+/* Define to 1 if you have the `posix_fadvise64' function. */
57+#undef HAVE_POSIX_FADVISE64
58+
59 /* Define to 1 if you have the `posix_fallocate' function. */
60 #undef HAVE_POSIX_FALLOCATE
61
62diff -ru rsync-3.1.2.orig/configure.ac rsync-3.1.2/configure.ac
63--- rsync-3.1.2.orig/configure.ac 2015-12-21 22:00:49.000000000 +0200
64+++ rsync-3.1.2/configure.ac 2016-10-24 15:38:28.006415712 +0300
65@@ -598,6 +598,7 @@
66 setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
67 seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \
68 extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
69+ mmap mincore posix_fadvise64 \
70 initgroups utimensat posix_fallocate attropen setvbuf usleep)
71
72 dnl cygwin iconv.h defines iconv_open as libiconv_open
73diff -ru rsync-3.1.2.orig/configure.sh rsync-3.1.2/configure.sh
74--- rsync-3.1.2.orig/configure.sh 2015-12-21 22:20:53.000000000 +0200
75+++ rsync-3.1.2/configure.sh 2016-10-24 15:38:28.006415712 +0300
76@@ -7692,6 +7692,7 @@
77 setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
78 seteuid strerror putenv iconv_open locale_charset nl_langinfo getxattr \
79 extattr_get_link sigaction sigprocmask setattrlist getgrouplist \
80+ mmap mincore posix_fadvise64 \
81 initgroups utimensat posix_fallocate attropen setvbuf usleep
82 do :
83 as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
84diff -ru rsync-3.1.2.orig/fileio.c rsync-3.1.2/fileio.c
85--- rsync-3.1.2.orig/fileio.c 2015-08-08 22:47:03.000000000 +0300
86+++ rsync-3.1.2/fileio.c 2016-10-24 15:38:28.006415712 +0300
87@@ -51,7 +51,7 @@
88 ret = -1;
89 else {
90 do {
91- ret = write(f, "", 1);
92+ ret = fadv_write(f, "", 1);
93 } while (ret < 0 && errno == EINTR);
94
95 ret = ret <= 0 ? -1 : 0;
96@@ -81,7 +81,7 @@
97 do_lseek(f, sparse_seek, SEEK_CUR);
98 sparse_seek = l2;
99
100- while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
101+ while ((ret = fadv_write(f, buf + l1, len - (l1+l2))) <= 0) {
102 if (ret < 0 && errno == EINTR)
103 continue;
104 sparse_seek = 0;
105@@ -107,7 +107,7 @@
106 char *bp = wf_writeBuf;
107
108 while (wf_writeBufCnt > 0) {
109- if ((ret = write(f, bp, wf_writeBufCnt)) < 0) {
110+ if ((ret = fadv_write(f, bp, wf_writeBufCnt)) < 0) {
111 if (errno == EINTR)
112 continue;
113 return ret;
114@@ -254,7 +254,7 @@
115 map->p_len = window_size;
116
117 while (read_size > 0) {
118- int32 nread = read(map->fd, map->p + read_offset, read_size);
119+ int32 nread = fadv_read(map->fd, map->p + read_offset, read_size);
120 if (nread <= 0) {
121 if (!map->status)
122 map->status = nread ? errno : ENODATA;
123diff -ru rsync-3.1.2.orig/generator.c rsync-3.1.2/generator.c
124--- rsync-3.1.2.orig/generator.c 2015-12-05 21:10:24.000000000 +0200
125+++ rsync-3.1.2/generator.c 2016-10-24 15:38:28.006415712 +0300
126@@ -111,6 +111,10 @@
127 static int need_retouch_dir_perms;
128 static const char *solo_file = NULL;
129
130+#ifdef WITH_DROP_CACHE
131+#define close(fd) fadv_close(fd)
132+#endif
133+
134 enum nonregtype {
135 TYPE_DIR, TYPE_SPECIAL, TYPE_DEVICE, TYPE_SYMLINK
136 };
137diff -ru rsync-3.1.2.orig/options.c rsync-3.1.2/options.c
138--- rsync-3.1.2.orig/options.c 2015-12-19 00:46:28.000000000 +0200
139+++ rsync-3.1.2/options.c 2016-10-24 15:38:28.006415712 +0300
140@@ -62,6 +62,9 @@
141 int preserve_gid = 0;
142 int preserve_times = 0;
143 int update_only = 0;
144+#ifdef WITH_DROP_CACHE
145+int drop_cache = 0;
146+#endif
147 int cvs_exclude = 0;
148 int dry_run = 0;
149 int do_xfers = 1;
150@@ -680,6 +683,9 @@
151 rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
152 rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
153 rprintf(F," -u, --update skip files that are newer on the receiver\n");
154+#ifdef WITH_DROP_CACHE
155+ rprintf(F," --drop-cache do not cache rsync files (POSIX_FADV_DONTNEED)\n");
156+#endif
157 rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
158 rprintf(F," --append append data onto shorter files\n");
159 rprintf(F," --append-verify like --append, but with old data in file checksum\n");
160@@ -914,6 +920,9 @@
161 {"no-one-file-system",0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
162 {"no-x", 0, POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
163 {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
164+#ifdef WITH_DROP_CACHE
165+ {"drop-cache", 0, POPT_ARG_NONE, &drop_cache, 0, 0, 0 },
166+#endif
167 {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
168 {"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
169 {"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 },
170@@ -1065,6 +1074,9 @@
171 rprintf(F," --log-file=FILE override the \"log file\" setting\n");
172 rprintf(F," --log-file-format=FMT override the \"log format\" setting\n");
173 rprintf(F," --sockopts=OPTIONS specify custom TCP options\n");
174+#ifdef WITH_DROP_CACHE
175+ rprintf(F," --drop-cache do not cache rsync files (POSIX_FADV_DONTNEED)\n");
176+#endif
177 rprintf(F," -v, --verbose increase verbosity\n");
178 rprintf(F," -4, --ipv4 prefer IPv4\n");
179 rprintf(F," -6, --ipv6 prefer IPv6\n");
180@@ -1089,6 +1101,9 @@
181 {"log-file", 0, POPT_ARG_STRING, &logfile_name, 0, 0, 0 },
182 {"log-file-format", 0, POPT_ARG_STRING, &logfile_format, 0, 0, 0 },
183 {"port", 0, POPT_ARG_INT, &rsync_port, 0, 0, 0 },
184+#ifdef WITH_DROP_CACHE
185+ {"drop-cache", 0, POPT_ARG_NONE, &drop_cache, 0, 0, 0 },
186+#endif
187 {"sockopts", 0, POPT_ARG_STRING, &sockopts, 0, 0, 0 },
188 {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
189 {"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
190@@ -2376,6 +2391,11 @@
191 if (!am_sender)
192 args[ac++] = "--sender";
193
194+#ifdef WITH_DROP_CACHE
195+ if (drop_cache)
196+ args[ac++] = "--drop-cache";
197+#endif
198+
199 x = 1;
200 argstr[0] = '-';
201
202diff -ru rsync-3.1.2.orig/proto.h rsync-3.1.2/proto.h
203--- rsync-3.1.2.orig/proto.h 2015-12-21 22:22:53.000000000 +0200
204+++ rsync-3.1.2/proto.h 2016-10-24 15:38:28.010415712 +0300
205@@ -348,6 +348,10 @@
206 uid_t recv_user_name(int f, uid_t uid);
207 gid_t recv_group_name(int f, gid_t gid, uint16 *flags_ptr);
208 void recv_id_list(int f, struct file_list *flist);
209+ssize_t fadv_write(int fd, const void *buf, size_t count);
210+ssize_t fadv_read(int fd, void *buf, size_t count);
211+void fadv_close_all(void);
212+int fadv_close(int fd);
213 void parse_name_map(char *map, BOOL usernames);
214 const char *getallgroups(uid_t uid, item_list *gid_list);
215 void set_nonblocking(int fd);
216diff -ru rsync-3.1.2.orig/receiver.c rsync-3.1.2/receiver.c
217--- rsync-3.1.2.orig/receiver.c 2015-09-07 20:07:17.000000000 +0300
218+++ rsync-3.1.2/receiver.c 2016-10-24 15:38:28.010415712 +0300
219@@ -62,6 +62,10 @@
220 extern struct file_list *cur_flist, *first_flist, *dir_flist;
221 extern filter_rule_list daemon_filter_list;
222
223+#ifdef WITH_DROP_CACHE
224+#define close(fd) fadv_close(fd)
225+#endif
226+
227 static struct bitbag *delayed_bits = NULL;
228 static int phase = 0, redoing = 0;
229 static flist_ndx_list batch_redo_list;
b913b1dd
ER
230--- rsync-3.1.3/rsync.1~ 2018-12-04 00:26:25.000000000 +0200
231+++ rsync-3.1.3/rsync.1 2018-12-04 00:27:43.557037661 +0200
9cb7906f
ER
232@@ -453,6 +453,7 @@
233 \-\-super receiver attempts super\-user activities
234 \-\-fake\-super store/recover privileged attrs using xattrs
b913b1dd 235 \-S, \-\-sparse turn sequences of nulls into sparse blocks
9cb7906f
ER
236+ \-\-drop\-cache drop cache continuosly using fadvise
237 \-\-preallocate allocate dest files before writing
238 \-n, \-\-dry\-run perform a trial run with no changes made
239 \-W, \-\-whole\-file copy files whole (w/o delta\-xfer algorithm)
240@@ -1426,6 +1427,13 @@
241 up less space on the destination. Conflicts with \fB\-\-inplace\fP because it\(cq\&s
242 not possible to overwrite data in a sparse fashion.
243 .IP
244+.IP "\fB\-\-drop\-cache\fP"
245+Stop rsync from filling up the file system cache with the files it copies\&. Without this
246+option other processes, that had been crunching along happily on your system, will suddenly
247+become slow as they find their data being outsed from the cache. The \fB\-\-drop\-cache\fP function
248+uses posix_fadvise64 and mincore todo its work\&. It will only get compiled if configure can find posix_fadvise64 and mincore\&.
249+Rsync will tries only to drop data from cache that has not been cached before.
250+.IP
251 .IP "\fB\-\-preallocate\fP"
252 This tells the receiver to allocate each destination
253 file to its eventual size before writing data to the file. Rsync will only use
254diff -ru rsync-3.1.2.orig/rsync.h rsync-3.1.2/rsync.h
255--- rsync-3.1.2.orig/rsync.h 2015-08-08 22:47:03.000000000 +0300
256+++ rsync-3.1.2/rsync.h 2016-10-24 15:38:28.010415712 +0300
257@@ -1291,3 +1291,13 @@
258 #ifdef MAINTAINER_MODE
259 const char *get_panic_action(void);
260 #endif
261+
262+#if defined HAVE_POSIX_FADVISE64 && defined HAVE_MINCORE && defined HAVE_MMAP
263+#define WITH_DROP_CACHE 1
264+#include <sys/mman.h>
265+int fadv_close(int fd);
266+void fadv_close_all(void);
267+#endif
268+
269+ssize_t fadv_write(int fd, const void *buf, size_t count);
270+ssize_t fadv_read(int fd, void *buf, size_t count);
271diff -ru rsync-3.1.2.orig/rsync.yo rsync-3.1.2/rsync.yo
272--- rsync-3.1.2.orig/rsync.yo 2015-12-21 22:00:49.000000000 +0200
273+++ rsync-3.1.2/rsync.yo 2016-10-24 15:38:28.010415712 +0300
274@@ -1244,6 +1244,17 @@
275 up less space on the destination. Conflicts with bf(--inplace) because it's
276 not possible to overwrite data in a sparse fashion.
277
278+dit(bf(--drop-cache)) Stop rsync from disturbing the file system cache with
279+the data from the files it copies. Without this option other processes, that
280+had been crunching along happily using cached data, will suddenly become
281+slow as they find their favorite data blocks data being evicted from the
282+cache by the files read and written by rsync. Since rsync has to wait until
283+the data is written to disk, before it can drop the cache, this option will
284+slow rsync down considerably, especially with small files and short copy
285+jobs. The bf(--drop-cache) function uses posix_fadvise64 and mincore todo
286+its work. It will only get compiled if configure can find posix_fadvise64
287+and mincore.
288+
289 dit(bf(--preallocate)) This tells the receiver to allocate each destination
290 file to its eventual size before writing data to the file. Rsync will only use
291 the real filesystem-level preallocation support provided by Linux's
292diff -ru rsync-3.1.2.orig/sender.c rsync-3.1.2/sender.c
293--- rsync-3.1.2.orig/sender.c 2015-09-07 20:07:17.000000000 +0300
294+++ rsync-3.1.2/sender.c 2016-10-24 15:38:28.010415712 +0300
295@@ -46,6 +46,9 @@
296 extern int file_old_total;
297 extern struct stats stats;
298 extern struct file_list *cur_flist, *first_flist, *dir_flist;
299+#ifdef WITH_DROP_CACHE
300+#define close(fd) fadv_close(fd)
301+#endif
302
303 BOOL extra_flist_sending_enabled;
304
305diff -ru rsync-3.1.2.orig/t_unsafe.c rsync-3.1.2/t_unsafe.c
306--- rsync-3.1.2.orig/t_unsafe.c 2015-08-08 22:47:03.000000000 +0300
307+++ rsync-3.1.2/t_unsafe.c 2016-10-24 15:38:28.010415712 +0300
308@@ -24,6 +24,7 @@
309 #include "rsync.h"
310
311 int dry_run = 0;
312+int drop_cache = 0;
313 int am_root = 0;
314 int am_sender = 1;
315 int read_only = 0;
316diff -ru rsync-3.1.2.orig/util.c rsync-3.1.2/util.c
317--- rsync-3.1.2.orig/util.c 2015-12-21 20:54:02.000000000 +0200
318+++ rsync-3.1.2/util.c 2016-10-24 15:38:28.014415712 +0300
319@@ -37,6 +37,10 @@
320 extern unsigned int module_dirlen;
321 extern char *partial_dir;
322 extern filter_rule_list daemon_filter_list;
323+#ifdef WITH_DROP_CACHE
324+#include <sys/mman.h>
325+extern int drop_cache;
326+#endif
327
328 int sanitize_paths = 0;
329
330@@ -44,6 +48,218 @@
331 unsigned int curr_dir_len;
332 int curr_dir_depth; /* This is only set for a sanitizing daemon. */
333
334+#ifdef WITH_DROP_CACHE
335+#define FADV_BUFFER_SIZE 1024*1024*16
336+
337+static struct stat fadv_fd_stat[1024];
338+static off_t fadv_fd_pos[1024];
339+static unsigned char *fadv_core_ptr[1024];
340+static int fadv_max_fd = 0;
341+static int fadv_close_ring_tail = 0;
342+static int fadv_close_ring_head = 0;
343+static int fadv_close_ring_size = 0;
344+static int fadv_close_ring[1024];
345+static int fadv_close_buffer_size = 0;
346+static size_t fadv_pagesize;
347+
348+static void fadv_fd_init_func(void)
349+{
350+ static int fadv_fd_init = 0;
351+ if (fadv_fd_init == 0){
352+ int i;
353+ fadv_fd_init = 1;
354+ fadv_pagesize = getpagesize();
355+ if (fadv_max_fd == 0){
356+ fadv_max_fd = sysconf(_SC_OPEN_MAX) - 20;
357+ if (fadv_max_fd < 0)
358+ fadv_max_fd = 1;
359+ if (fadv_max_fd > 1000)
360+ fadv_max_fd = 1000;
361+ }
362+ for (i=0;i<fadv_max_fd;i++){
363+ fadv_fd_pos[i] = 0;
364+ fadv_fd_stat[i].st_dev = 0;
365+ fadv_fd_stat[i].st_ino = 0;
366+ fadv_fd_stat[i].st_size = 0;
367+ fadv_core_ptr[i] = NULL;
368+ }
369+ }
370+}
371+
372+static void fadv_get_core(int fd)
373+{
374+ struct stat stat;
375+ void *pa;
376+ size_t pi;
377+ fstat(fd,&stat);
378+ if ( fadv_fd_stat[fd].st_dev == stat.st_dev && fadv_fd_stat[fd].st_ino == stat.st_ino ) {
379+ return;
380+ }
381+ fadv_fd_stat[fd].st_dev = stat.st_dev;
382+ fadv_fd_stat[fd].st_ino = stat.st_ino;
383+ fadv_fd_stat[fd].st_size = stat.st_size;
384+
385+ if (fadv_core_ptr[fd]!=NULL){
386+ free (fadv_core_ptr[fd]);
387+ }
388+
389+ pa = mmap((void *)0, stat.st_size, PROT_READ, MAP_SHARED, fd, 0);
390+ if (MAP_FAILED == pa) {
391+ perror("mmap");
392+ } else {
393+ fadv_core_ptr[fd] = calloc(1, (stat.st_size+fadv_pagesize)/fadv_pagesize);
394+ if ( fadv_core_ptr[fd] == NULL ){
395+ perror("calloc");
396+ } else {
397+ if ( mincore(pa, stat.st_size, (fadv_core_ptr[fd])) != 0){
398+ perror("mincore");
399+ free(fadv_core_ptr[fd]);
400+ fadv_core_ptr[fd]=(unsigned char*)0;
401+ } else if (DEBUG_GTE(IO, 4)) {
402+// } else {
403+ rprintf(FINFO, "fadv_get_core(fd=%d): ", fd);
404+ for (pi = 0; pi <= stat.st_size/fadv_pagesize; pi++) {
405+ if ((fadv_core_ptr[fd])[pi]&1) {
406+ rprintf(FINFO,"%lu ", (unsigned long)pi);
407+ }
408+ }
409+ rprintf(FINFO,"\n");
410+ }
411+ munmap(pa, stat.st_size);
412+ }
413+ }
414+}
415+
416+static void fadv_drop(int fd, int sync)
417+{
418+ /* trail 1 MB behind in dropping. we do this to make
419+ sure that the same block or stripe does not have
420+ to be written twice */
421+ off_t pos = lseek(fd,0,SEEK_CUR) - 1024*1024;
422+ if (fd > fadv_max_fd){
423+ return;
424+ }
425+ if ( fadv_fd_pos[fd] < pos - FADV_BUFFER_SIZE ) {
426+ if (sync) {
427+ /* if the file is not flushed to disk before calling fadvise,
428+ then the Cache will not be freed and the advise gets ignored
429+ this does give a severe hit on performance. If only there
430+ was a way to mark cache so that it gets release once the data
431+ is written to disk. */
432+ fdatasync(fd);
433+ }
434+ if (fadv_core_ptr[fd] != NULL) {
435+ size_t pi;
436+ if (pos < fadv_fd_stat[fd].st_size){
437+ for (pi = fadv_fd_pos[fd]/fadv_pagesize; pi <= pos/fadv_pagesize; pi++) {
438+ if (! (fadv_core_ptr[fd][pi]&1)) {
439+ posix_fadvise64(fd, pi*fadv_pagesize, fadv_pagesize, POSIX_FADV_DONTNEED);
440+ }
441+ }
442+ } else {
443+ posix_fadvise64(fd, fadv_fd_stat[fd].st_size, pos-fadv_fd_stat[fd].st_size, POSIX_FADV_DONTNEED);
444+ }
445+ } else {
446+ posix_fadvise64(fd, 0, pos, POSIX_FADV_DONTNEED);
447+ }
448+ fadv_fd_pos[fd] = pos;
449+ }
450+}
451+
452+#endif
453+
454+ssize_t fadv_write(int fd, const void *buf, size_t count)
455+{
456+ int ret = write(fd, buf, count);
457+#ifdef WITH_DROP_CACHE
458+ if (drop_cache) {
459+ fadv_drop(fd,1);
460+ }
461+#endif
462+ return ret;
463+}
464+
465+ssize_t fadv_read(int fd, void *buf, size_t count)
466+{
467+ int ret;
468+#ifdef WITH_DROP_CACHE
469+ if (drop_cache) {
470+ fadv_fd_init_func();
471+ fadv_get_core(fd);
472+ }
473+#endif
474+ ret = read(fd, buf, count);
475+#ifdef WITH_DROP_CACHE
476+ if (drop_cache) {
477+ fadv_drop(fd,0);
478+ }
479+#endif
480+ return ret;
481+}
482+
483+#ifdef WITH_DROP_CACHE
484+void fadv_close_all(void)
485+{
486+ /* printf ("%i\n",fadv_close_ring_size); */
487+ while (fadv_close_ring_size > 0){
488+ fdatasync(fadv_close_ring[fadv_close_ring_tail]);
489+ if (fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]]){
490+ size_t pi;
491+ for (pi = 0; pi <= fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_size/fadv_pagesize; pi++) {
492+ if (!(fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]][pi]&1)) {
493+ posix_fadvise64(fadv_close_ring[fadv_close_ring_tail], pi*fadv_pagesize, fadv_pagesize, POSIX_FADV_DONTNEED);
494+ }
495+ }
496+ /* if the file has grown, drop the rest */
497+ //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);
498+
499+ free(fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]]);
500+ fadv_core_ptr[fadv_close_ring[fadv_close_ring_tail]] = NULL;
501+ fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_size = 0;
502+ fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_ino = 0;
503+ fadv_fd_stat[fadv_close_ring[fadv_close_ring_tail]].st_dev = 0;
504+ } else {
505+ posix_fadvise64(fadv_close_ring[fadv_close_ring_tail], 0, 0,POSIX_FADV_DONTNEED);
506+ }
507+ fadv_close_ring_size--;
508+ close(fadv_close_ring[fadv_close_ring_tail]);
509+ fadv_close_ring_tail = (fadv_close_ring_tail + 1) % fadv_max_fd;
510+ fadv_close_buffer_size = 0;
511+ }
512+}
513+
514+int fadv_close(int fd)
515+{
516+ if (drop_cache) {
517+ /* if the file is not flushed to disk before calling fadvise,
518+ then the Cache will not be freed and the advise gets ignored
519+ this does give a severe hit on performance. So instead of doing
520+ it right away, we save us a copy of the filehandle and do it
521+ some time before we are out of filehandles. This speeds
522+ up operation for small files massively. It is directly
523+ related to the number of spare file handles you have. */
524+ int newfd = dup(fd);
525+ off_t pos = lseek(fd,0,SEEK_CUR);
526+ fadv_fd_init_func();
527+ fadv_core_ptr[newfd] = fadv_core_ptr[fd];
528+ fadv_fd_stat[newfd].st_size = fadv_fd_stat[fd].st_size ;
529+ fadv_core_ptr[fd] = NULL;
530+ fadv_close_buffer_size += pos - fadv_fd_pos[fd];
531+ fadv_close_ring[fadv_close_ring_head] = newfd;
532+ fadv_close_ring_head = (fadv_close_ring_head + 1) % fadv_max_fd;
533+ fadv_close_ring_size ++;
534+ if (fadv_close_ring_size == fadv_max_fd || fadv_close_buffer_size > 1024*1024 ){
535+ /* it seems fastest to drop things 'in groups' */
536+ fadv_close_all();
537+ }
538+ };
539+ return close(fd);
540+}
541+
542+
543+#define close(fd) fadv_close(fd)
544+#endif
545+
546 /* Set a fd into nonblocking mode. */
547 void set_nonblocking(int fd)
548 {
549@@ -273,7 +489,7 @@
550
551 total_written = 0;
552 while (len > 0) {
553- int written = write(desc, ptr, len);
554+ int written = fadv_write(desc, ptr, len);
555 if (written < 0) {
556 if (errno == EINTR)
557 continue;
558@@ -305,7 +521,7 @@
559 return len;
560
561 do {
562- n_chars = read(desc, ptr, len);
563+ n_chars = fadv_read(desc, ptr, len);
564 } while (n_chars < 0 && errno == EINTR);
565
566 return n_chars;
This page took 0.127977 seconds and 4 git commands to generate.