… | |
… | |
314 | X_LOCK (reqlock); |
314 | X_LOCK (reqlock); |
315 | X_LOCK (reslock); |
315 | X_LOCK (reslock); |
316 | #if !HAVE_PREADWRITE |
316 | #if !HAVE_PREADWRITE |
317 | X_LOCK (preadwritelock); |
317 | X_LOCK (preadwritelock); |
318 | #endif |
318 | #endif |
319 | #if !HAVE_READDIR_R |
|
|
320 | X_LOCK (readdirlock); |
|
|
321 | #endif |
|
|
322 | } |
319 | } |
323 | |
320 | |
324 | static void etp_atfork_parent (void) |
321 | static void etp_atfork_parent (void) |
325 | { |
322 | { |
326 | #if !HAVE_READDIR_R |
|
|
327 | X_UNLOCK (readdirlock); |
|
|
328 | #endif |
|
|
329 | #if !HAVE_PREADWRITE |
323 | #if !HAVE_PREADWRITE |
330 | X_UNLOCK (preadwritelock); |
324 | X_UNLOCK (preadwritelock); |
331 | #endif |
325 | #endif |
332 | X_UNLOCK (reslock); |
326 | X_UNLOCK (reslock); |
333 | X_UNLOCK (reqlock); |
327 | X_UNLOCK (reqlock); |
… | |
… | |
377 | |
371 | |
378 | pthread_once (&doinit, etp_once_init); |
372 | pthread_once (&doinit, etp_once_init); |
379 | |
373 | |
380 | want_poll_cb = want_poll; |
374 | want_poll_cb = want_poll; |
381 | done_poll_cb = done_poll; |
375 | done_poll_cb = done_poll; |
|
|
376 | |
|
|
377 | return 0; |
382 | } |
378 | } |
383 | |
379 | |
384 | X_THREAD_PROC (etp_proc); |
380 | X_THREAD_PROC (etp_proc); |
385 | |
381 | |
386 | static void etp_start_thread (void) |
382 | static void etp_start_thread (void) |
… | |
… | |
781 | |
777 | |
782 | #if !HAVE_READAHEAD |
778 | #if !HAVE_READAHEAD |
783 | # define readahead(fd,offset,count) eio__readahead (fd, offset, count, self) |
779 | # define readahead(fd,offset,count) eio__readahead (fd, offset, count, self) |
784 | |
780 | |
785 | static ssize_t |
781 | static ssize_t |
786 | eio__readahead (int fd, off_t offset, size_t count, worker *self) |
782 | eio__readahead (int fd, off_t offset, size_t count, etp_worker *self) |
787 | { |
783 | { |
788 | size_t todo = count; |
784 | size_t todo = count; |
789 | dBUF; |
785 | dBUF; |
790 | |
786 | |
791 | while (todo > 0) |
787 | while (todo > 0) |
… | |
… | |
799 | |
795 | |
800 | errno = 0; |
796 | errno = 0; |
801 | return count; |
797 | return count; |
802 | } |
798 | } |
803 | |
799 | |
804 | #endif |
|
|
805 | |
|
|
806 | #if !HAVE_READDIR_R |
|
|
807 | # define readdir_r eio__readdir_r |
|
|
808 | |
|
|
809 | static mutex_t readdirlock = X_MUTEX_INIT; |
|
|
810 | |
|
|
811 | static int |
|
|
812 | eio__readdir_r (DIR *dirp, EIO_STRUCT_DIRENT *ent, EIO_STRUCT_DIRENT **res) |
|
|
813 | { |
|
|
814 | EIO_STRUCT_DIRENT *e; |
|
|
815 | int errorno; |
|
|
816 | |
|
|
817 | X_LOCK (readdirlock); |
|
|
818 | |
|
|
819 | e = readdir (dirp); |
|
|
820 | errorno = errno; |
|
|
821 | |
|
|
822 | if (e) |
|
|
823 | { |
|
|
824 | *res = ent; |
|
|
825 | strcpy (ent->d_name, e->d_name); |
|
|
826 | } |
|
|
827 | else |
|
|
828 | *res = 0; |
|
|
829 | |
|
|
830 | X_UNLOCK (readdirlock); |
|
|
831 | |
|
|
832 | errno = errorno; |
|
|
833 | return e ? 0 : -1; |
|
|
834 | } |
|
|
835 | #endif |
800 | #endif |
836 | |
801 | |
837 | /* sendfile always needs emulation */ |
802 | /* sendfile always needs emulation */ |
838 | static ssize_t |
803 | static ssize_t |
839 | eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self) |
804 | eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self) |
… | |
… | |
931 | /* read a full directory */ |
896 | /* read a full directory */ |
932 | static void |
897 | static void |
933 | eio__scandir (eio_req *req, etp_worker *self) |
898 | eio__scandir (eio_req *req, etp_worker *self) |
934 | { |
899 | { |
935 | DIR *dirp; |
900 | DIR *dirp; |
936 | union |
|
|
937 | { |
|
|
938 | EIO_STRUCT_DIRENT d; |
|
|
939 | char b [offsetof (EIO_STRUCT_DIRENT, d_name) + NAME_MAX + 1]; |
|
|
940 | } *u; |
|
|
941 | EIO_STRUCT_DIRENT *entp; |
901 | EIO_STRUCT_DIRENT *entp; |
942 | char *name, *names; |
902 | char *name, *names; |
943 | int memlen = 4096; |
903 | int memlen = 4096; |
944 | int memofs = 0; |
904 | int memofs = 0; |
945 | int res = 0; |
905 | int res = 0; |
946 | |
906 | |
947 | X_LOCK (wrklock); |
907 | X_LOCK (wrklock); |
948 | self->dirp = dirp = opendir (req->ptr1); |
908 | self->dirp = dirp = opendir (req->ptr1); |
949 | self->dbuf = u = malloc (sizeof (*u)); |
|
|
950 | req->flags |= EIO_FLAG_PTR2_FREE; |
909 | req->flags |= EIO_FLAG_PTR2_FREE; |
951 | req->ptr2 = names = malloc (memlen); |
910 | req->ptr2 = names = malloc (memlen); |
952 | X_UNLOCK (wrklock); |
911 | X_UNLOCK (wrklock); |
953 | |
912 | |
954 | if (dirp && u && names) |
913 | if (dirp && names) |
955 | for (;;) |
914 | for (;;) |
956 | { |
915 | { |
957 | errno = 0; |
916 | errno = 0; |
958 | readdir_r (dirp, &u->d, &entp); |
917 | entp = readdir (dirp); |
959 | |
918 | |
960 | if (!entp) |
919 | if (!entp) |
961 | break; |
920 | break; |
962 | |
921 | |
963 | name = entp->d_name; |
922 | name = entp->d_name; |
… | |
… | |
1082 | |
1041 | |
1083 | /*****************************************************************************/ |
1042 | /*****************************************************************************/ |
1084 | |
1043 | |
1085 | int eio_init (void (*want_poll)(void), void (*done_poll)(void)) |
1044 | int eio_init (void (*want_poll)(void), void (*done_poll)(void)) |
1086 | { |
1045 | { |
1087 | etp_init (want_poll, done_poll); |
1046 | return etp_init (want_poll, done_poll); |
1088 | } |
1047 | } |
1089 | |
1048 | |
1090 | static void eio_api_destroy (eio_req *req) |
1049 | static void eio_api_destroy (eio_req *req) |
1091 | { |
1050 | { |
1092 | free (req); |
1051 | free (req); |
… | |
… | |
1154 | case EIO_RMDIR: req->result = rmdir (req->ptr1); break; |
1113 | case EIO_RMDIR: req->result = rmdir (req->ptr1); break; |
1155 | case EIO_MKDIR: req->result = mkdir (req->ptr1, (mode_t)req->int2); break; |
1114 | case EIO_MKDIR: req->result = mkdir (req->ptr1, (mode_t)req->int2); break; |
1156 | case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; |
1115 | case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; |
1157 | case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; |
1116 | case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; |
1158 | case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; |
1117 | case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; |
1159 | case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->offs); break; |
1118 | case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->int3); break; |
1160 | |
1119 | |
1161 | case EIO_READLINK: ALLOC (NAME_MAX); |
1120 | case EIO_READLINK: ALLOC (NAME_MAX); |
1162 | req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break; |
1121 | req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break; |
1163 | |
1122 | |
1164 | case EIO_SYNC: req->result = 0; sync (); break; |
1123 | case EIO_SYNC: req->result = 0; sync (); break; |
… | |
… | |
1371 | return eio__1path (EIO_READDIR, path, pri, cb, data); |
1330 | return eio__1path (EIO_READDIR, path, pri, cb, data); |
1372 | } |
1331 | } |
1373 | |
1332 | |
1374 | eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data) |
1333 | eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data) |
1375 | { |
1334 | { |
1376 | REQ (EIO_MKNOD); PATH; req->int2 = (long)mode; req->int2 = (long)dev; SEND; |
1335 | REQ (EIO_MKNOD); PATH; req->int2 = (long)mode; req->int3 = (long)dev; SEND; |
1377 | } |
1336 | } |
1378 | |
1337 | |
1379 | static eio_req * |
1338 | static eio_req * |
1380 | eio__2path (int type, const char *path, const char *new_path, int pri, eio_cb cb, void *data) |
1339 | eio__2path (int type, const char *path, const char *new_path, int pri, eio_cb cb, void *data) |
1381 | { |
1340 | { |