ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libeio/eio.c
(Generate patch)

Comparing libeio/eio.c (file contents):
Revision 1.91 by root, Sun Jul 17 04:20:04 2011 UTC vs.
Revision 1.101 by root, Wed Aug 3 15:25:38 2011 UTC

71#endif 71#endif
72#ifndef ELOOP 72#ifndef ELOOP
73# define ELOOP EDOM 73# define ELOOP EDOM
74#endif 74#endif
75 75
76#if !defined(ENOTSOCK) && defined(WSAENOTSOCK)
77# define ENOTSOCK WSAENOTSOCK
78#endif
79
76static void eio_destroy (eio_req *req); 80static void eio_destroy (eio_req *req);
77 81
78#ifndef EIO_FINISH 82#ifndef EIO_FINISH
79# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0 83# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0
80#endif 84#endif
101#ifdef _WIN32 105#ifdef _WIN32
102 106
103 #undef PAGESIZE 107 #undef PAGESIZE
104 #define PAGESIZE 4096 /* GetSystemInfo? */ 108 #define PAGESIZE 4096 /* GetSystemInfo? */
105 109
110 /* TODO: look at how perl does stat (non-sloppy), unlink (ro-files), utime, link */
111
106 #ifdef EIO_STRUCT_STATI64 112 #ifdef EIO_STRUCT_STATI64
113 /* look at perl's non-sloppy stat */
107 #define stat(path,buf) _stati64 (path,buf) 114 #define stat(path,buf) _stati64 (path,buf)
108 #define fstat(fd,buf) _fstati64 (path,buf) 115 #define fstat(fd,buf) _fstati64 (fd,buf)
109 #endif 116 #endif
110 #define lstat(path,buf) stat (path,buf) 117 #define lstat(path,buf) stat (path,buf)
111 #define fsync(fd) (FlushFileBuffers ((HANDLE)EIO_FD_TO_WIN32_HANDLE (fd)) ? 0 : EIO_ERRNO (EBADF, -1)) 118 #define fsync(fd) (FlushFileBuffers ((HANDLE)EIO_FD_TO_WIN32_HANDLE (fd)) ? 0 : EIO_ERRNO (EBADF, -1))
112 #define mkdir(path,mode) _mkdir (path) 119 #define mkdir(path,mode) _mkdir (path)
113 #define link(old,neu) (CreateHardLink (neu, old, 0) ? 0 : EIO_ERRNO (ENOENT, -1)) 120 #define link(old,neu) (CreateHardLink (neu, old, 0) ? 0 : EIO_ERRNO (ENOENT, -1))
125 #define sync() EIO_ENOSYS () 132 #define sync() EIO_ENOSYS ()
126 #define readlink(path,buf,s) EIO_ENOSYS () 133 #define readlink(path,buf,s) EIO_ENOSYS ()
127 #define statvfs(path,buf) EIO_ENOSYS () 134 #define statvfs(path,buf) EIO_ENOSYS ()
128 #define fstatvfs(fd,buf) EIO_ENOSYS () 135 #define fstatvfs(fd,buf) EIO_ENOSYS ()
129 136
137 /* rename() uses MoveFile, which fails to overwrite */
138 #define rename(old,neu) eio__rename (old, neu)
139
140 static int
141 eio__rename (const char *old, const char *neu)
142 {
143 if (MoveFileEx (old, neu, MOVEFILE_REPLACE_EXISTING))
144 return 0;
145
146 /* should steal _dosmaperr */
147 switch (GetLastError ())
148 {
149 case ERROR_FILE_NOT_FOUND:
150 case ERROR_PATH_NOT_FOUND:
151 case ERROR_INVALID_DRIVE:
152 case ERROR_NO_MORE_FILES:
153 case ERROR_BAD_NETPATH:
154 case ERROR_BAD_NET_NAME:
155 case ERROR_BAD_PATHNAME:
156 case ERROR_FILENAME_EXCED_RANGE:
157 errno = ENOENT;
158 break;
159
160 default:
161 errno = EACCES;
162 break;
163 }
164
165 return -1;
166 }
167
130 /* we could even stat and see if it exists */ 168 /* we could even stat and see if it exists */
131 static int 169 static int
132 symlink (const char *old, const char *neu) 170 symlink (const char *old, const char *neu)
133 { 171 {
134 #if WINVER >= 0x0600 172 #if WINVER >= 0x0600
160 198
161 #include <sys/time.h> 199 #include <sys/time.h>
162 #include <sys/select.h> 200 #include <sys/select.h>
163 #include <sys/statvfs.h> 201 #include <sys/statvfs.h>
164 #include <unistd.h> 202 #include <unistd.h>
165 #include <utime.h>
166 #include <signal.h> 203 #include <signal.h>
167 #include <dirent.h> 204 #include <dirent.h>
168 205
169 #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES 206 #if _POSIX_MEMLOCK || _POSIX_MEMLOCK_RANGE || _POSIX_MAPPED_FILES
170 #include <sys/mman.h> 207 #include <sys/mman.h>
192 229
193 #ifndef EIO_STRUCT_DIRENT 230 #ifndef EIO_STRUCT_DIRENT
194 #define EIO_STRUCT_DIRENT struct dirent 231 #define EIO_STRUCT_DIRENT struct dirent
195 #endif 232 #endif
196 233
234#endif
235
236#if HAVE_UTIMES
237# include <utime.h>
238#endif
239
240#if HAVE_SYS_SYSCALL_H
241# include <sys/syscall.h>
242#endif
243
244#if HAVE_SYS_PRCTL_H
245# include <sys/prctl.h>
197#endif 246#endif
198 247
199#if HAVE_SENDFILE 248#if HAVE_SENDFILE
200# if __linux 249# if __linux
201# include <sys/sendfile.h> 250# include <sys/sendfile.h>
233 282
234/* buffer size for various temporary buffers */ 283/* buffer size for various temporary buffers */
235#define EIO_BUFSIZE 65536 284#define EIO_BUFSIZE 65536
236 285
237#define dBUF \ 286#define dBUF \
238 char *eio_buf; \
239 ETP_WORKER_LOCK (self); \
240 self->dbuf = eio_buf = malloc (EIO_BUFSIZE); \ 287 char *eio_buf = malloc (EIO_BUFSIZE); \
241 ETP_WORKER_UNLOCK (self); \
242 errno = ENOMEM; \ 288 errno = ENOMEM; \
243 if (!eio_buf) \ 289 if (!eio_buf) \
244 return -1; 290 return -1
291
292#define FUBd \
293 free (eio_buf)
245 294
246#define EIO_TICKS ((1000000 + 1023) >> 10) 295#define EIO_TICKS ((1000000 + 1023) >> 10)
247 296
248#define ETP_PRI_MIN EIO_PRI_MIN 297#define ETP_PRI_MIN EIO_PRI_MIN
249#define ETP_PRI_MAX EIO_PRI_MAX 298#define ETP_PRI_MAX EIO_PRI_MAX
255static int eio_finish (eio_req *req); 304static int eio_finish (eio_req *req);
256#define ETP_FINISH(req) eio_finish (req) 305#define ETP_FINISH(req) eio_finish (req)
257static void eio_execute (struct etp_worker *self, eio_req *req); 306static void eio_execute (struct etp_worker *self, eio_req *req);
258#define ETP_EXECUTE(wrk,req) eio_execute (wrk,req) 307#define ETP_EXECUTE(wrk,req) eio_execute (wrk,req)
259 308
260#define ETP_WORKER_CLEAR(req) \
261 if (wrk->dbuf) \
262 { \
263 free (wrk->dbuf); \
264 wrk->dbuf = 0; \
265 }
266
267#define ETP_WORKER_COMMON \
268 void *dbuf;
269
270/*****************************************************************************/ 309/*****************************************************************************/
271 310
272#define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1) 311#define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1)
273 312
274/* calculate time difference in ~1/EIO_TICKS of a second */ 313/* calculate time difference in ~1/EIO_TICKS of a second */
285static void (*done_poll_cb) (void); 324static void (*done_poll_cb) (void);
286 325
287static unsigned int max_poll_time; /* reslock */ 326static unsigned int max_poll_time; /* reslock */
288static unsigned int max_poll_reqs; /* reslock */ 327static unsigned int max_poll_reqs; /* reslock */
289 328
290static volatile unsigned int nreqs; /* reqlock */ 329static unsigned int nreqs; /* reqlock */
291static volatile unsigned int nready; /* reqlock */ 330static unsigned int nready; /* reqlock */
292static volatile unsigned int npending; /* reqlock */ 331static unsigned int npending; /* reqlock */
293static volatile unsigned int max_idle = 4; /* maximum number of threads that can idle indefinitely */ 332static unsigned int max_idle = 4; /* maximum number of threads that can idle indefinitely */
294static volatile unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */ 333static unsigned int idle_timeout = 10; /* number of seconds after which an idle threads exit */
295 334
296static xmutex_t wrklock; 335static xmutex_t wrklock;
297static xmutex_t reslock; 336static xmutex_t reslock;
298static xmutex_t reqlock; 337static xmutex_t reqlock;
299static xcond_t reqwait; 338static xcond_t reqwait;
302/* 341/*
303 * make our pread/pwrite emulation safe against themselves, but not against 342 * make our pread/pwrite emulation safe against themselves, but not against
304 * normal read/write by using a mutex. slows down execution a lot, 343 * normal read/write by using a mutex. slows down execution a lot,
305 * but that's your problem, not mine. 344 * but that's your problem, not mine.
306 */ 345 */
307static xmutex_t preadwritelock = X_MUTEX_INIT; 346static xmutex_t preadwritelock;
308#endif 347#endif
309 348
310typedef struct etp_worker 349typedef struct etp_worker
311{ 350{
312 /* locked by wrklock */ 351 /* locked by wrklock */
315 xthread_t tid; 354 xthread_t tid;
316 355
317 /* locked by reslock, reqlock or wrklock */ 356 /* locked by reslock, reqlock or wrklock */
318 ETP_REQ *req; /* currently processed request */ 357 ETP_REQ *req; /* currently processed request */
319 358
359#ifdef ETP_WORKER_COMMON
320 ETP_WORKER_COMMON 360 ETP_WORKER_COMMON
361#endif
321} etp_worker; 362} etp_worker;
322 363
323static etp_worker wrk_first = { &wrk_first, &wrk_first, 0 }; /* NOT etp */ 364static etp_worker wrk_first; /* NOT etp */
324 365
325#define ETP_WORKER_LOCK(wrk) X_LOCK (wrklock) 366#define ETP_WORKER_LOCK(wrk) X_LOCK (wrklock)
326#define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock) 367#define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock)
327 368
328/* worker threads management */ 369/* worker threads management */
329 370
330static void ecb_cold 371static void ecb_cold
331etp_worker_clear (etp_worker *wrk) 372etp_worker_clear (etp_worker *wrk)
332{ 373{
333 ETP_WORKER_CLEAR (wrk);
334} 374}
335 375
336static void ecb_cold 376static void ecb_cold
337etp_worker_free (etp_worker *wrk) 377etp_worker_free (etp_worker *wrk)
338{ 378{
453 } 493 }
454 494
455 abort (); 495 abort ();
456} 496}
457 497
458static void ecb_cold 498static int ecb_cold
459etp_thread_init (void) 499etp_init (void (*want_poll)(void), void (*done_poll)(void))
460{ 500{
461#if !HAVE_PREADWRITE
462 X_MUTEX_CREATE (preadwritelock);
463#endif
464 X_MUTEX_CREATE (wrklock); 501 X_MUTEX_CREATE (wrklock);
465 X_MUTEX_CREATE (reslock); 502 X_MUTEX_CREATE (reslock);
466 X_MUTEX_CREATE (reqlock); 503 X_MUTEX_CREATE (reqlock);
467 X_COND_CREATE (reqwait); 504 X_COND_CREATE (reqwait);
468}
469 505
470static void ecb_cold
471etp_atfork_child (void)
472{
473 reqq_init (&req_queue); 506 reqq_init (&req_queue);
474 reqq_init (&res_queue); 507 reqq_init (&res_queue);
475 508
476 wrk_first.next = 509 wrk_first.next =
477 wrk_first.prev = &wrk_first; 510 wrk_first.prev = &wrk_first;
479 started = 0; 512 started = 0;
480 idle = 0; 513 idle = 0;
481 nreqs = 0; 514 nreqs = 0;
482 nready = 0; 515 nready = 0;
483 npending = 0; 516 npending = 0;
484
485 etp_thread_init ();
486}
487
488static void ecb_cold
489etp_once_init (void)
490{
491 etp_thread_init ();
492 X_THREAD_ATFORK (0, 0, etp_atfork_child);
493}
494
495static int ecb_cold
496etp_init (void (*want_poll)(void), void (*done_poll)(void))
497{
498 static pthread_once_t doinit = PTHREAD_ONCE_INIT;
499
500 pthread_once (&doinit, etp_once_init);
501 517
502 want_poll_cb = want_poll; 518 want_poll_cb = want_poll;
503 done_poll_cb = done_poll; 519 done_poll_cb = done_poll;
504 520
505 return 0; 521 return 0;
963#if !HAVE_FDATASYNC 979#if !HAVE_FDATASYNC
964# undef fdatasync 980# undef fdatasync
965# define fdatasync(fd) fsync (fd) 981# define fdatasync(fd) fsync (fd)
966#endif 982#endif
967 983
984static int
985eio__syncfs (int fd)
986{
987 int res;
988
989#if HAVE_SYS_SYNCFS
990 res = (int)syscall (__NR_syncfs, (int)(fd));
991#else
992 res = -1;
993 errno = ENOSYS;
994#endif
995
996 if (res < 0 && errno == ENOSYS && fd >= 0)
997 sync ();
998
999 return res;
1000}
1001
968/* sync_file_range always needs emulation */ 1002/* sync_file_range always needs emulation */
969static int 1003static int
970eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags) 1004eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags)
971{ 1005{
972#if HAVE_SYNC_FILE_RANGE 1006#if HAVE_SYNC_FILE_RANGE
1021 pread (fd, eio_buf, len, offset); 1055 pread (fd, eio_buf, len, offset);
1022 offset += len; 1056 offset += len;
1023 todo -= len; 1057 todo -= len;
1024 } 1058 }
1025 1059
1060 FUBd;
1061
1026 errno = 0; 1062 errno = 0;
1027 return count; 1063 return count;
1028} 1064}
1029 1065
1030#endif 1066#endif
1031 1067
1032/* sendfile always needs emulation */ 1068/* sendfile always needs emulation */
1033static eio_ssize_t 1069static eio_ssize_t
1034eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self) 1070eio__sendfile (int ofd, int ifd, off_t offset, size_t count)
1035{ 1071{
1036 eio_ssize_t written = 0; 1072 eio_ssize_t written = 0;
1037 eio_ssize_t res; 1073 eio_ssize_t res;
1038 1074
1039 if (!count) 1075 if (!count)
1175 1211
1176 offset += cnt; 1212 offset += cnt;
1177 res += cnt; 1213 res += cnt;
1178 count -= cnt; 1214 count -= cnt;
1179 } 1215 }
1216
1217 FUBd;
1180 } 1218 }
1181 1219
1182 return res; 1220 return res;
1183} 1221}
1184 1222
1651 if (!(flags & EIO_READDIR_DENTS)) 1689 if (!(flags & EIO_READDIR_DENTS))
1652 flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER); 1690 flags &= ~(EIO_READDIR_DIRS_FIRST | EIO_READDIR_STAT_ORDER);
1653 1691
1654#ifdef _WIN32 1692#ifdef _WIN32
1655 { 1693 {
1694 int len = strlen ((const char *)req->ptr1);
1656 char *path = malloc (MAX_PATH); 1695 char *path = malloc (MAX_PATH);
1696 const char *fmt;
1697
1698 if (!len)
1699 fmt = "./*";
1700 else if (((const char *)req->ptr1)[len - 1] == '/' || ((const char *)req->ptr1)[len - 1] == '\\')
1701 fmt = "%s*";
1702 else
1703 fmt = "%s/*";
1704
1657 _snprintf (path, MAX_PATH, "%s/*", (const char *)req->ptr1); 1705 _snprintf (path, MAX_PATH, fmt, (const char *)req->ptr1);
1658 dirp = FindFirstFile (path, &entp); 1706 dirp = FindFirstFile (path, &entp);
1659 free (path); 1707 free (path);
1660 1708
1661 if (!dirp) 1709 if (dirp == INVALID_HANDLE_VALUE)
1662 { 1710 {
1711 dirp = 0;
1712
1713 /* should steal _dosmaperr */
1663 switch (GetLastError ()) 1714 switch (GetLastError ())
1664 { 1715 {
1665 case ERROR_FILE_NOT_FOUND: 1716 case ERROR_FILE_NOT_FOUND:
1666 req->result = 0; 1717 req->result = 0;
1667 break; 1718 break;
1668 1719
1720 case ERROR_INVALID_NAME:
1669 case ERROR_PATH_NOT_FOUND: 1721 case ERROR_PATH_NOT_FOUND:
1670 case ERROR_NO_MORE_FILES: 1722 case ERROR_NO_MORE_FILES:
1671 errno = ENOENT; 1723 errno = ENOENT;
1672 break; 1724 break;
1673 1725
1677 1729
1678 default: 1730 default:
1679 errno = EINVAL; 1731 errno = EINVAL;
1680 break; 1732 break;
1681 } 1733 }
1682
1683 } 1734 }
1684 } 1735 }
1685#else 1736#else
1686 dirp = opendir (req->ptr1); 1737 dirp = opendir (req->ptr1);
1687#endif 1738#endif
1688 1739
1694 req->ptr2 = names = malloc (namesalloc); 1745 req->ptr2 = names = malloc (namesalloc);
1695 1746
1696 if (dirp && names && (!flags || dents)) 1747 if (dirp && names && (!flags || dents))
1697 for (;;) 1748 for (;;)
1698 { 1749 {
1699 int more; 1750 int done;
1700 1751
1701#ifdef _WIN32 1752#ifdef _WIN32
1702 more = dirp; 1753 done = !dirp;
1703#else 1754#else
1704 errno = 0; 1755 errno = 0;
1705 entp = readdir (dirp); 1756 entp = readdir (dirp);
1706 more = entp; 1757 done = !entp;
1707#endif 1758#endif
1708 1759
1709 if (!more) 1760 if (done)
1710 { 1761 {
1711#ifndef _WIN32 1762#ifndef _WIN32
1712 int old_errno = errno; 1763 int old_errno = errno;
1713 closedir (dirp); 1764 closedir (dirp);
1714 errno = old_errno; 1765 errno = old_errno;
1901{ 1952{
1902 ETP_REQ *req; 1953 ETP_REQ *req;
1903 struct timespec ts; 1954 struct timespec ts;
1904 etp_worker *self = (etp_worker *)thr_arg; 1955 etp_worker *self = (etp_worker *)thr_arg;
1905 1956
1957#if HAVE_PRCTL_SET_NAME
1958 prctl (PR_SET_NAME, (unsigned long)"eio_thread", 0, 0, 0);
1959#endif
1960
1906 /* try to distribute timeouts somewhat evenly */ 1961 /* try to distribute timeouts somewhat evenly */
1907 ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL); 1962 ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL);
1908 1963
1909 for (;;) 1964 for (;;)
1910 { 1965 {
1979/*****************************************************************************/ 2034/*****************************************************************************/
1980 2035
1981int ecb_cold 2036int ecb_cold
1982eio_init (void (*want_poll)(void), void (*done_poll)(void)) 2037eio_init (void (*want_poll)(void), void (*done_poll)(void))
1983{ 2038{
2039#if !HAVE_PREADWRITE
2040 X_MUTEX_CREATE (preadwritelock);
2041#endif
2042
1984 return etp_init (want_poll, done_poll); 2043 return etp_init (want_poll, done_poll);
1985} 2044}
1986 2045
1987ecb_inline void 2046ecb_inline void
1988eio_api_destroy (eio_req *req) 2047eio_api_destroy (eio_req *req)
2033 case EIO_WRITE: req->result = req->offs >= 0 2092 case EIO_WRITE: req->result = req->offs >= 0
2034 ? pwrite (req->int1, req->ptr2, req->size, req->offs) 2093 ? pwrite (req->int1, req->ptr2, req->size, req->offs)
2035 : write (req->int1, req->ptr2, req->size); break; 2094 : write (req->int1, req->ptr2, req->size); break;
2036 2095
2037 case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; 2096 case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break;
2038 case EIO_SENDFILE: req->result = eio__sendfile (req->int1, req->int2, req->offs, req->size, self); break; 2097 case EIO_SENDFILE: req->result = eio__sendfile (req->int1, req->int2, req->offs, req->size); break;
2039 2098
2040 case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT)); 2099 case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT));
2041 req->result = stat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break; 2100 req->result = stat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break;
2042 case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); 2101 case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT));
2043 req->result = lstat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break; 2102 req->result = lstat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break;
2073 req->result = readlink (req->ptr1, req->ptr2, PATH_MAX); break; 2132 req->result = readlink (req->ptr1, req->ptr2, PATH_MAX); break;
2074 2133
2075 case EIO_SYNC: req->result = 0; sync (); break; 2134 case EIO_SYNC: req->result = 0; sync (); break;
2076 case EIO_FSYNC: req->result = fsync (req->int1); break; 2135 case EIO_FSYNC: req->result = fsync (req->int1); break;
2077 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; 2136 case EIO_FDATASYNC: req->result = fdatasync (req->int1); break;
2137 case EIO_SYNCFS: req->result = eio__syncfs (req->int1); break;
2138 case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
2078 case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break; 2139 case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break;
2079 case EIO_MTOUCH: req->result = eio__mtouch (req); break; 2140 case EIO_MTOUCH: req->result = eio__mtouch (req); break;
2080 case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break; 2141 case EIO_MLOCK: req->result = eio__mlock (req->ptr2, req->size); break;
2081 case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break; 2142 case EIO_MLOCKALL: req->result = eio__mlockall (req->int1); break;
2082 case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break;
2083 case EIO_FALLOCATE: req->result = eio__fallocate (req->int1, req->int2, req->offs, req->size); break; 2143 case EIO_FALLOCATE: req->result = eio__fallocate (req->int1, req->int2, req->offs, req->size); break;
2084 2144
2085 case EIO_READDIR: eio__scandir (req, self); break; 2145 case EIO_READDIR: eio__scandir (req, self); break;
2086 2146
2087 case EIO_BUSY: 2147 case EIO_BUSY:
2168eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data) 2228eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
2169{ 2229{
2170 REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND; 2230 REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
2171} 2231}
2172 2232
2233eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
2234{
2235 REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
2236}
2237
2238eio_req *eio_syncfs (int fd, int pri, eio_cb cb, void *data)
2239{
2240 REQ (EIO_SYNCFS); req->int1 = fd; SEND;
2241}
2242
2243eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
2244{
2245 REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;
2246}
2247
2173eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data) 2248eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data)
2174{ 2249{
2175 REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND; 2250 REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND;
2176} 2251}
2177 2252
2183eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data) 2258eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data)
2184{ 2259{
2185 REQ (EIO_MLOCKALL); req->int1 = flags; SEND; 2260 REQ (EIO_MLOCKALL); req->int1 = flags; SEND;
2186} 2261}
2187 2262
2188eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data)
2189{
2190 REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND;
2191}
2192
2193eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data) 2263eio_req *eio_fallocate (int fd, int mode, off_t offset, size_t len, int pri, eio_cb cb, void *data)
2194{ 2264{
2195 REQ (EIO_FALLOCATE); req->int1 = fd; req->int2 = mode; req->offs = offset; req->size = len; SEND; 2265 REQ (EIO_FALLOCATE); req->int1 = fd; req->int2 = mode; req->offs = offset; req->size = len; SEND;
2196}
2197
2198eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data)
2199{
2200 REQ (EIO_FDATASYNC); req->int1 = fd; SEND;
2201} 2266}
2202 2267
2203eio_req *eio_close (int fd, int pri, eio_cb cb, void *data) 2268eio_req *eio_close (int fd, int pri, eio_cb cb, void *data)
2204{ 2269{
2205 REQ (EIO_CLOSE); req->int1 = fd; SEND; 2270 REQ (EIO_CLOSE); req->int1 = fd; SEND;
2433/* misc garbage */ 2498/* misc garbage */
2434 2499
2435eio_ssize_t 2500eio_ssize_t
2436eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count) 2501eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count)
2437{ 2502{
2438 etp_worker wrk;
2439 eio_ssize_t ret;
2440
2441 wrk.dbuf = 0;
2442
2443 ret = eio__sendfile (ofd, ifd, offset, count, &wrk); 2503 return eio__sendfile (ofd, ifd, offset, count);
2444
2445 if (wrk.dbuf)
2446 free (wrk.dbuf);
2447
2448 return ret;
2449} 2504}
2450 2505

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines