… | |
… | |
137 | /* used for struct dirent, AIX doesn't provide it */ |
137 | /* used for struct dirent, AIX doesn't provide it */ |
138 | #ifndef NAME_MAX |
138 | #ifndef NAME_MAX |
139 | # define NAME_MAX 4096 |
139 | # define NAME_MAX 4096 |
140 | #endif |
140 | #endif |
141 | |
141 | |
|
|
142 | /* used for readlink etc. */ |
|
|
143 | #ifndef PATH_MAX |
|
|
144 | # define PATH_MAX 4096 |
|
|
145 | #endif |
|
|
146 | |
142 | /* buffer size for various temporary buffers */ |
147 | /* buffer size for various temporary buffers */ |
143 | #define EIO_BUFSIZE 65536 |
148 | #define EIO_BUFSIZE 65536 |
144 | |
149 | |
145 | #define dBUF \ |
150 | #define dBUF \ |
146 | char *eio_buf; \ |
151 | char *eio_buf; \ |
… | |
… | |
217 | static volatile unsigned int nreqs; /* reqlock */ |
222 | static volatile unsigned int nreqs; /* reqlock */ |
218 | static volatile unsigned int nready; /* reqlock */ |
223 | static volatile unsigned int nready; /* reqlock */ |
219 | static volatile unsigned int npending; /* reqlock */ |
224 | static volatile unsigned int npending; /* reqlock */ |
220 | static volatile unsigned int max_idle = 4; |
225 | static volatile unsigned int max_idle = 4; |
221 | |
226 | |
222 | static mutex_t wrklock = X_MUTEX_INIT; |
227 | static xmutex_t wrklock = X_MUTEX_INIT; |
223 | static mutex_t reslock = X_MUTEX_INIT; |
228 | static xmutex_t reslock = X_MUTEX_INIT; |
224 | static mutex_t reqlock = X_MUTEX_INIT; |
229 | static xmutex_t reqlock = X_MUTEX_INIT; |
225 | static cond_t reqwait = X_COND_INIT; |
230 | static xcond_t reqwait = X_COND_INIT; |
226 | |
231 | |
227 | #if !HAVE_PREADWRITE |
232 | #if !HAVE_PREADWRITE |
228 | /* |
233 | /* |
229 | * make our pread/pwrite emulation safe against themselves, but not against |
234 | * make our pread/pwrite emulation safe against themselves, but not against |
230 | * normal read/write by using a mutex. slows down execution a lot, |
235 | * normal read/write by using a mutex. slows down execution a lot, |
231 | * but that's your problem, not mine. |
236 | * but that's your problem, not mine. |
232 | */ |
237 | */ |
233 | static mutex_t preadwritelock = X_MUTEX_INIT; |
238 | static xmutex_t preadwritelock = X_MUTEX_INIT; |
234 | #endif |
239 | #endif |
235 | |
240 | |
236 | typedef struct etp_worker |
241 | typedef struct etp_worker |
237 | { |
242 | { |
238 | /* locked by wrklock */ |
243 | /* locked by wrklock */ |
239 | struct etp_worker *prev, *next; |
244 | struct etp_worker *prev, *next; |
240 | |
245 | |
241 | thread_t tid; |
246 | xthread_t tid; |
242 | |
247 | |
243 | /* locked by reslock, reqlock or wrklock */ |
248 | /* locked by reslock, reqlock or wrklock */ |
244 | ETP_REQ *req; /* currently processed request */ |
249 | ETP_REQ *req; /* currently processed request */ |
245 | |
250 | |
246 | ETP_WORKER_COMMON |
251 | ETP_WORKER_COMMON |
… | |
… | |
919 | */ |
924 | */ |
920 | { |
925 | { |
921 | off_t sbytes; |
926 | off_t sbytes; |
922 | res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); |
927 | res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); |
923 | |
928 | |
|
|
929 | #if 0 /* according to the manpage, this is correct, but broken behaviour */ |
924 | /* freebsd' sendfile will return 0 on success */ |
930 | /* freebsd' sendfile will return 0 on success */ |
925 | /* freebsd 8 documents it as only setting *sbytes on EINTR and EAGAIN, but */ |
931 | /* freebsd 8 documents it as only setting *sbytes on EINTR and EAGAIN, but */ |
926 | /* not on e.g. EIO or EPIPE - sounds broken */ |
932 | /* not on e.g. EIO or EPIPE - sounds broken */ |
927 | if ((res < 0 && (errno == EAGAIN || errno == EINTR) && sbytes) || res == 0) |
933 | if ((res < 0 && (errno == EAGAIN || errno == EINTR) && sbytes) || res == 0) |
|
|
934 | res = sbytes; |
|
|
935 | #endif |
|
|
936 | |
|
|
937 | /* according to source inspection, this is correct, and useful behaviour */ |
|
|
938 | if (sbytes) |
928 | res = sbytes; |
939 | res = sbytes; |
929 | } |
940 | } |
930 | |
941 | |
931 | # elif defined (__APPLE__) |
942 | # elif defined (__APPLE__) |
932 | |
943 | |
… | |
… | |
1602 | case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; |
1613 | case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; |
1603 | case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; |
1614 | case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; |
1604 | case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; |
1615 | case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; |
1605 | case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->int3); break; |
1616 | case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->int3); break; |
1606 | |
1617 | |
1607 | case EIO_READLINK: ALLOC (NAME_MAX); |
1618 | case EIO_READLINK: ALLOC (PATH_MAX); |
1608 | req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break; |
1619 | req->result = readlink (req->ptr1, req->ptr2, PATH_MAX); break; |
1609 | |
1620 | |
1610 | case EIO_SYNC: req->result = 0; sync (); break; |
1621 | case EIO_SYNC: req->result = 0; sync (); break; |
1611 | case EIO_FSYNC: req->result = fsync (req->int1); break; |
1622 | case EIO_FSYNC: req->result = fsync (req->int1); break; |
1612 | case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; |
1623 | case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; |
1613 | case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break; |
1624 | case EIO_MSYNC: req->result = eio__msync (req->ptr2, req->size, req->int1); break; |