| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: sys_aio.c,v 1.19.8.2 2010/01/30 20:46:20 snj Exp $ */ | | 1 | /* $NetBSD: sys_aio.c,v 1.19.8.3 2010/01/30 21:19:19 snj Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2007, Mindaugas Rasiukevicius <rmind at NetBSD org> | | 4 | * Copyright (c) 2007, Mindaugas Rasiukevicius <rmind at NetBSD org> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -22,27 +22,27 @@ | | | @@ -22,27 +22,27 @@ |
22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | /* | | 29 | /* |
30 | * Implementation of POSIX asynchronous I/O. | | 30 | * Implementation of POSIX asynchronous I/O. |
31 | * Defined in the Base Definitions volume of IEEE Std 1003.1-2001. | | 31 | * Defined in the Base Definitions volume of IEEE Std 1003.1-2001. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: sys_aio.c,v 1.19.8.2 2010/01/30 20:46:20 snj Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: sys_aio.c,v 1.19.8.3 2010/01/30 21:19:19 snj Exp $"); |
36 | | | 36 | |
37 | #include "opt_ddb.h" | | 37 | #include "opt_ddb.h" |
38 | | | 38 | |
39 | #include <sys/param.h> | | 39 | #include <sys/param.h> |
40 | #include <sys/condvar.h> | | 40 | #include <sys/condvar.h> |
41 | #include <sys/file.h> | | 41 | #include <sys/file.h> |
42 | #include <sys/filedesc.h> | | 42 | #include <sys/filedesc.h> |
43 | #include <sys/kernel.h> | | 43 | #include <sys/kernel.h> |
44 | #include <sys/kmem.h> | | 44 | #include <sys/kmem.h> |
45 | #include <sys/lwp.h> | | 45 | #include <sys/lwp.h> |
46 | #include <sys/mutex.h> | | 46 | #include <sys/mutex.h> |
47 | #include <sys/pool.h> | | 47 | #include <sys/pool.h> |
48 | #include <sys/proc.h> | | 48 | #include <sys/proc.h> |
| @@ -751,31 +751,31 @@ sys_aio_suspend(struct lwp *l, const str | | | @@ -751,31 +751,31 @@ sys_aio_suspend(struct lwp *l, const str |
751 | error = copyin(SCARG(uap, timeout), &ts, | | 751 | error = copyin(SCARG(uap, timeout), &ts, |
752 | sizeof(struct timespec)); | | 752 | sizeof(struct timespec)); |
753 | if (error) | | 753 | if (error) |
754 | return error; | | 754 | return error; |
755 | timo = mstohz((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000)); | | 755 | timo = mstohz((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000)); |
756 | if (timo == 0 && ts.tv_sec == 0 && ts.tv_nsec > 0) | | 756 | if (timo == 0 && ts.tv_sec == 0 && ts.tv_nsec > 0) |
757 | timo = 1; | | 757 | timo = 1; |
758 | if (timo <= 0) | | 758 | if (timo <= 0) |
759 | return EAGAIN; | | 759 | return EAGAIN; |
760 | } else | | 760 | } else |
761 | timo = 0; | | 761 | timo = 0; |
762 | | | 762 | |
763 | /* Get the list from user-space */ | | 763 | /* Get the list from user-space */ |
764 | aiocbp_list = kmem_zalloc(nent * sizeof(struct aio_job), KM_SLEEP); | | 764 | aiocbp_list = kmem_alloc(nent * sizeof(*aiocbp_list), KM_SLEEP); |
765 | error = copyin(SCARG(uap, list), aiocbp_list, | | 765 | error = copyin(SCARG(uap, list), aiocbp_list, |
766 | nent * sizeof(struct aiocb)); | | 766 | nent * sizeof(*aiocbp_list)); |
767 | if (error) { | | 767 | if (error) { |
768 | kmem_free(aiocbp_list, nent * sizeof(struct aio_job)); | | 768 | kmem_free(aiocbp_list, nent * sizeof(*aiocbp_list)); |
769 | return error; | | 769 | return error; |
770 | } | | 770 | } |
771 | | | 771 | |
772 | mutex_enter(&aio->aio_mtx); | | 772 | mutex_enter(&aio->aio_mtx); |
773 | for (;;) { | | 773 | for (;;) { |
774 | | | 774 | |
775 | for (i = 0; i < nent; i++) { | | 775 | for (i = 0; i < nent; i++) { |
776 | | | 776 | |
777 | /* Skip NULL entries */ | | 777 | /* Skip NULL entries */ |
778 | if (aiocbp_list[i] == NULL) | | 778 | if (aiocbp_list[i] == NULL) |
779 | continue; | | 779 | continue; |
780 | | | 780 | |
781 | /* Skip current job */ | | 781 | /* Skip current job */ |
| @@ -793,42 +793,42 @@ sys_aio_suspend(struct lwp *l, const str | | | @@ -793,42 +793,42 @@ sys_aio_suspend(struct lwp *l, const str |
793 | if (a_job == NULL) { | | 793 | if (a_job == NULL) { |
794 | struct aiocb aiocbp; | | 794 | struct aiocb aiocbp; |
795 | | | 795 | |
796 | mutex_exit(&aio->aio_mtx); | | 796 | mutex_exit(&aio->aio_mtx); |
797 | | | 797 | |
798 | error = copyin(aiocbp_list[i], &aiocbp, | | 798 | error = copyin(aiocbp_list[i], &aiocbp, |
799 | sizeof(struct aiocb)); | | 799 | sizeof(struct aiocb)); |
800 | if (error == 0 && aiocbp._state != JOB_DONE) { | | 800 | if (error == 0 && aiocbp._state != JOB_DONE) { |
801 | mutex_enter(&aio->aio_mtx); | | 801 | mutex_enter(&aio->aio_mtx); |
802 | continue; | | 802 | continue; |
803 | } | | 803 | } |
804 | | | 804 | |
805 | kmem_free(aiocbp_list, | | 805 | kmem_free(aiocbp_list, |
806 | nent * sizeof(struct aio_job)); | | 806 | nent * sizeof(*aiocbp_list)); |
807 | return error; | | 807 | return error; |
808 | } | | 808 | } |
809 | } | | 809 | } |
810 | | | 810 | |
811 | /* Wait for a signal or when timeout occurs */ | | 811 | /* Wait for a signal or when timeout occurs */ |
812 | error = cv_timedwait_sig(&aio->done_cv, &aio->aio_mtx, timo); | | 812 | error = cv_timedwait_sig(&aio->done_cv, &aio->aio_mtx, timo); |
813 | if (error) { | | 813 | if (error) { |
814 | if (error == EWOULDBLOCK) | | 814 | if (error == EWOULDBLOCK) |
815 | error = EAGAIN; | | 815 | error = EAGAIN; |
816 | break; | | 816 | break; |
817 | } | | 817 | } |
818 | } | | 818 | } |
819 | mutex_exit(&aio->aio_mtx); | | 819 | mutex_exit(&aio->aio_mtx); |
820 | | | 820 | |
821 | kmem_free(aiocbp_list, nent * sizeof(struct aio_job)); | | 821 | kmem_free(aiocbp_list, nent * sizeof(*aiocbp_list)); |
822 | return error; | | 822 | return error; |
823 | } | | 823 | } |
824 | | | 824 | |
825 | int | | 825 | int |
826 | sys_aio_write(struct lwp *l, const struct sys_aio_write_args *uap, register_t *retval) | | 826 | sys_aio_write(struct lwp *l, const struct sys_aio_write_args *uap, register_t *retval) |
827 | { | | 827 | { |
828 | /* { | | 828 | /* { |
829 | syscallarg(struct aiocb *) aiocbp; | | 829 | syscallarg(struct aiocb *) aiocbp; |
830 | } */ | | 830 | } */ |
831 | | | 831 | |
832 | return aio_enqueue_job(AIO_WRITE, SCARG(uap, aiocbp), NULL); | | 832 | return aio_enqueue_job(AIO_WRITE, SCARG(uap, aiocbp), NULL); |
833 | } | | 833 | } |
834 | | | 834 | |
| @@ -888,29 +888,29 @@ sys_lio_listio(struct lwp *l, const stru | | | @@ -888,29 +888,29 @@ sys_lio_listio(struct lwp *l, const stru |
888 | memset(&lio->sig, 0, sizeof(struct sigevent)); | | 888 | memset(&lio->sig, 0, sizeof(struct sigevent)); |
889 | break; | | 889 | break; |
890 | default: | | 890 | default: |
891 | error = EINVAL; | | 891 | error = EINVAL; |
892 | break; | | 892 | break; |
893 | } | | 893 | } |
894 | | | 894 | |
895 | if (error != 0) { | | 895 | if (error != 0) { |
896 | pool_put(&aio_lio_pool, lio); | | 896 | pool_put(&aio_lio_pool, lio); |
897 | return error; | | 897 | return error; |
898 | } | | 898 | } |
899 | | | 899 | |
900 | /* Get the list from user-space */ | | 900 | /* Get the list from user-space */ |
901 | aiocbp_list = kmem_zalloc(nent * sizeof(struct aio_job), KM_SLEEP); | | 901 | aiocbp_list = kmem_alloc(nent * sizeof(*aiocbp_list), KM_SLEEP); |
902 | error = copyin(SCARG(uap, list), aiocbp_list, | | 902 | error = copyin(SCARG(uap, list), aiocbp_list, |
903 | nent * sizeof(struct aiocb)); | | 903 | nent * sizeof(*aiocbp_list)); |
904 | if (error) { | | 904 | if (error) { |
905 | mutex_enter(&aio->aio_mtx); | | 905 | mutex_enter(&aio->aio_mtx); |
906 | goto err; | | 906 | goto err; |
907 | } | | 907 | } |
908 | | | 908 | |
909 | /* Enqueue all jobs */ | | 909 | /* Enqueue all jobs */ |
910 | errcnt = 0; | | 910 | errcnt = 0; |
911 | for (i = 0; i < nent; i++) { | | 911 | for (i = 0; i < nent; i++) { |
912 | error = aio_enqueue_job(AIO_LIO, aiocbp_list[i], lio); | | 912 | error = aio_enqueue_job(AIO_LIO, aiocbp_list[i], lio); |
913 | /* | | 913 | /* |
914 | * According to POSIX, in such error case it may | | 914 | * According to POSIX, in such error case it may |
915 | * fail with other I/O operations initiated. | | 915 | * fail with other I/O operations initiated. |
916 | */ | | 916 | */ |
| @@ -935,27 +935,27 @@ sys_lio_listio(struct lwp *l, const stru | | | @@ -935,27 +935,27 @@ sys_lio_listio(struct lwp *l, const stru |
935 | error = cv_wait_sig(&aio->done_cv, &aio->aio_mtx); | | 935 | error = cv_wait_sig(&aio->done_cv, &aio->aio_mtx); |
936 | if (error) | | 936 | if (error) |
937 | error = EINTR; | | 937 | error = EINTR; |
938 | } | | 938 | } |
939 | | | 939 | |
940 | err: | | 940 | err: |
941 | if (--lio->refcnt != 0) | | 941 | if (--lio->refcnt != 0) |
942 | lio = NULL; | | 942 | lio = NULL; |
943 | mutex_exit(&aio->aio_mtx); | | 943 | mutex_exit(&aio->aio_mtx); |
944 | if (lio != NULL) { | | 944 | if (lio != NULL) { |
945 | aio_sendsig(p, &lio->sig); | | 945 | aio_sendsig(p, &lio->sig); |
946 | pool_put(&aio_lio_pool, lio); | | 946 | pool_put(&aio_lio_pool, lio); |
947 | } | | 947 | } |
948 | kmem_free(aiocbp_list, nent * sizeof(struct aio_job)); | | 948 | kmem_free(aiocbp_list, nent * sizeof(*aiocbp_list)); |
949 | return error; | | 949 | return error; |
950 | } | | 950 | } |
951 | | | 951 | |
952 | /* | | 952 | /* |
953 | * SysCtl | | 953 | * SysCtl |
954 | */ | | 954 | */ |
955 | | | 955 | |
956 | static int | | 956 | static int |
957 | sysctl_aio_listio_max(SYSCTLFN_ARGS) | | 957 | sysctl_aio_listio_max(SYSCTLFN_ARGS) |
958 | { | | 958 | { |
959 | struct sysctlnode node; | | 959 | struct sysctlnode node; |
960 | int error, newsize; | | 960 | int error, newsize; |
961 | | | 961 | |