vfs_aio.c (251522) | vfs_aio.c (251526) |
---|---|
1/*- 2 * Copyright (c) 1997 John S. Dyson. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 5 unchanged lines hidden (view full) --- 14 * of the author. This software is distributed AS-IS. 15 */ 16 17/* 18 * This file contains support for the POSIX 1003.1B AIO/LIO facility. 19 */ 20 21#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997 John S. Dyson. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 5 unchanged lines hidden (view full) --- 14 * of the author. This software is distributed AS-IS. 15 */ 16 17/* 18 * This file contains support for the POSIX 1003.1B AIO/LIO facility. 19 */ 20 21#include <sys/cdefs.h> |
22__FBSDID("$FreeBSD: head/sys/kern/vfs_aio.c 251522 2013-06-08 13:02:43Z glebius $"); | 22__FBSDID("$FreeBSD: head/sys/kern/vfs_aio.c 251526 2013-06-08 13:27:57Z glebius $"); |
23 24#include "opt_compat.h" 25 26#include <sys/param.h> 27#include <sys/systm.h> 28#include <sys/malloc.h> 29#include <sys/bio.h> 30#include <sys/buf.h> --- 304 unchanged lines hidden (view full) --- 335static TAILQ_HEAD(,aiocblist) aio_jobs; /* (c) Async job list */ 336static struct unrhdr *aiod_unr; 337 338void aio_init_aioinfo(struct proc *p); 339static int aio_onceonly(void); 340static int aio_free_entry(struct aiocblist *aiocbe); 341static void aio_process_rw(struct aiocblist *aiocbe); 342static void aio_process_sync(struct aiocblist *aiocbe); | 23 24#include "opt_compat.h" 25 26#include <sys/param.h> 27#include <sys/systm.h> 28#include <sys/malloc.h> 29#include <sys/bio.h> 30#include <sys/buf.h> --- 304 unchanged lines hidden (view full) --- 335static TAILQ_HEAD(,aiocblist) aio_jobs; /* (c) Async job list */ 336static struct unrhdr *aiod_unr; 337 338void aio_init_aioinfo(struct proc *p); 339static int aio_onceonly(void); 340static int aio_free_entry(struct aiocblist *aiocbe); 341static void aio_process_rw(struct aiocblist *aiocbe); 342static void aio_process_sync(struct aiocblist *aiocbe); |
343static void aio_process_mlock(struct aiocblist *aiocbe); |
|
343static int aio_newproc(int *); 344int aio_aqueue(struct thread *td, struct aiocb *job, 345 struct aioliojob *lio, int type, struct aiocb_ops *ops); 346static void aio_physwakeup(struct buf *bp); 347static void aio_proc_rundown(void *arg, struct proc *p); 348static void aio_proc_rundown_exec(void *arg, struct proc *p, struct image_params *imgp); 349static int aio_qphysio(struct proc *p, struct aiocblist *iocb); 350static void biohelper(void *, int); --- 70 unchanged lines hidden (view full) --- 421 &aio_modload, 422 NULL 423}; 424 425static struct syscall_helper_data aio_syscalls[] = { 426 SYSCALL_INIT_HELPER(aio_cancel), 427 SYSCALL_INIT_HELPER(aio_error), 428 SYSCALL_INIT_HELPER(aio_fsync), | 344static int aio_newproc(int *); 345int aio_aqueue(struct thread *td, struct aiocb *job, 346 struct aioliojob *lio, int type, struct aiocb_ops *ops); 347static void aio_physwakeup(struct buf *bp); 348static void aio_proc_rundown(void *arg, struct proc *p); 349static void aio_proc_rundown_exec(void *arg, struct proc *p, struct image_params *imgp); 350static int aio_qphysio(struct proc *p, struct aiocblist *iocb); 351static void biohelper(void *, int); --- 70 unchanged lines hidden (view full) --- 422 &aio_modload, 423 NULL 424}; 425 426static struct syscall_helper_data aio_syscalls[] = { 427 SYSCALL_INIT_HELPER(aio_cancel), 428 SYSCALL_INIT_HELPER(aio_error), 429 SYSCALL_INIT_HELPER(aio_fsync), |
430 SYSCALL_INIT_HELPER(aio_mlock), |
|
429 SYSCALL_INIT_HELPER(aio_read), 430 SYSCALL_INIT_HELPER(aio_return), 431 SYSCALL_INIT_HELPER(aio_suspend), 432 SYSCALL_INIT_HELPER(aio_waitcomplete), 433 SYSCALL_INIT_HELPER(aio_write), 434 SYSCALL_INIT_HELPER(lio_listio), 435 SYSCALL_INIT_HELPER(oaio_read), 436 SYSCALL_INIT_HELPER(oaio_write), --- 11 unchanged lines hidden (view full) --- 448#include <compat/freebsd32/freebsd32_util.h> 449 450static struct syscall_helper_data aio32_syscalls[] = { 451 SYSCALL32_INIT_HELPER(freebsd32_aio_return), 452 SYSCALL32_INIT_HELPER(freebsd32_aio_suspend), 453 SYSCALL32_INIT_HELPER(freebsd32_aio_cancel), 454 SYSCALL32_INIT_HELPER(freebsd32_aio_error), 455 SYSCALL32_INIT_HELPER(freebsd32_aio_fsync), | 431 SYSCALL_INIT_HELPER(aio_read), 432 SYSCALL_INIT_HELPER(aio_return), 433 SYSCALL_INIT_HELPER(aio_suspend), 434 SYSCALL_INIT_HELPER(aio_waitcomplete), 435 SYSCALL_INIT_HELPER(aio_write), 436 SYSCALL_INIT_HELPER(lio_listio), 437 SYSCALL_INIT_HELPER(oaio_read), 438 SYSCALL_INIT_HELPER(oaio_write), --- 11 unchanged lines hidden (view full) --- 450#include <compat/freebsd32/freebsd32_util.h> 451 452static struct syscall_helper_data aio32_syscalls[] = { 453 SYSCALL32_INIT_HELPER(freebsd32_aio_return), 454 SYSCALL32_INIT_HELPER(freebsd32_aio_suspend), 455 SYSCALL32_INIT_HELPER(freebsd32_aio_cancel), 456 SYSCALL32_INIT_HELPER(freebsd32_aio_error), 457 SYSCALL32_INIT_HELPER(freebsd32_aio_fsync), |
458 SYSCALL32_INIT_HELPER(freebsd32_aio_mlock), |
|
456 SYSCALL32_INIT_HELPER(freebsd32_aio_read), 457 SYSCALL32_INIT_HELPER(freebsd32_aio_write), 458 SYSCALL32_INIT_HELPER(freebsd32_aio_waitcomplete), 459 SYSCALL32_INIT_HELPER(freebsd32_lio_listio), 460 SYSCALL32_INIT_HELPER(freebsd32_oaio_read), 461 SYSCALL32_INIT_HELPER(freebsd32_oaio_write), 462 SYSCALL32_INIT_HELPER(freebsd32_olio_listio), 463 SYSCALL_INIT_LAST --- 233 unchanged lines hidden (view full) --- 697 * curthread can't exit since we are curthread. 698 * 699 * Therefore, we use curthread as the thread to pass to 700 * knlist_delete(). This does mean that it is possible for the 701 * thread pointer at close time to differ from the thread pointer 702 * at open time, but this is already true of file descriptors in 703 * a multithreaded process. 704 */ | 459 SYSCALL32_INIT_HELPER(freebsd32_aio_read), 460 SYSCALL32_INIT_HELPER(freebsd32_aio_write), 461 SYSCALL32_INIT_HELPER(freebsd32_aio_waitcomplete), 462 SYSCALL32_INIT_HELPER(freebsd32_lio_listio), 463 SYSCALL32_INIT_HELPER(freebsd32_oaio_read), 464 SYSCALL32_INIT_HELPER(freebsd32_oaio_write), 465 SYSCALL32_INIT_HELPER(freebsd32_olio_listio), 466 SYSCALL_INIT_LAST --- 233 unchanged lines hidden (view full) --- 700 * curthread can't exit since we are curthread. 701 * 702 * Therefore, we use curthread as the thread to pass to 703 * knlist_delete(). This does mean that it is possible for the 704 * thread pointer at close time to differ from the thread pointer 705 * at open time, but this is already true of file descriptors in 706 * a multithreaded process. 707 */ |
705 fdrop(aiocbe->fd_file, curthread); | 708 if (aiocbe->fd_file) 709 fdrop(aiocbe->fd_file, curthread); |
706 crfree(aiocbe->cred); 707 uma_zfree(aiocb_zone, aiocbe); 708 AIO_LOCK(ki); 709 710 return (0); 711} 712 713static void --- 249 unchanged lines hidden (view full) --- 963 if (fp->f_vnode != NULL) 964 error = aio_fsync_vnode(td, fp->f_vnode); 965 cb->_aiocb_private.error = error; 966 cb->_aiocb_private.status = 0; 967 td->td_ucred = td_savedcred; 968} 969 970static void | 710 crfree(aiocbe->cred); 711 uma_zfree(aiocb_zone, aiocbe); 712 AIO_LOCK(ki); 713 714 return (0); 715} 716 717static void --- 249 unchanged lines hidden (view full) --- 967 if (fp->f_vnode != NULL) 968 error = aio_fsync_vnode(td, fp->f_vnode); 969 cb->_aiocb_private.error = error; 970 cb->_aiocb_private.status = 0; 971 td->td_ucred = td_savedcred; 972} 973 974static void |
975aio_process_mlock(struct aiocblist *aiocbe) 976{ 977 struct aiocb *cb = &aiocbe->uaiocb; 978 int error; 979 980 KASSERT(aiocbe->uaiocb.aio_lio_opcode == LIO_MLOCK, 981 ("%s: opcode %d", __func__, aiocbe->uaiocb.aio_lio_opcode)); 982 983 error = vm_mlock(aiocbe->userproc, aiocbe->cred, 984 __DEVOLATILE(void *, cb->aio_buf), cb->aio_nbytes); 985 cb->_aiocb_private.error = error; 986 cb->_aiocb_private.status = 0; 987} 988 989static void |
|
971aio_bio_done_notify(struct proc *userp, struct aiocblist *aiocbe, int type) 972{ 973 struct aioliojob *lj; 974 struct kaioinfo *ki; 975 struct aiocblist *scb, *scbn; 976 int lj_done; 977 978 ki = userp->p_aioinfo; --- 159 unchanged lines hidden (view full) --- 1138 switch(aiocbe->uaiocb.aio_lio_opcode) { 1139 case LIO_READ: 1140 case LIO_WRITE: 1141 aio_process_rw(aiocbe); 1142 break; 1143 case LIO_SYNC: 1144 aio_process_sync(aiocbe); 1145 break; | 990aio_bio_done_notify(struct proc *userp, struct aiocblist *aiocbe, int type) 991{ 992 struct aioliojob *lj; 993 struct kaioinfo *ki; 994 struct aiocblist *scb, *scbn; 995 int lj_done; 996 997 ki = userp->p_aioinfo; --- 159 unchanged lines hidden (view full) --- 1157 switch(aiocbe->uaiocb.aio_lio_opcode) { 1158 case LIO_READ: 1159 case LIO_WRITE: 1160 aio_process_rw(aiocbe); 1161 break; 1162 case LIO_SYNC: 1163 aio_process_sync(aiocbe); 1164 break; |
1165 case LIO_MLOCK: 1166 aio_process_mlock(aiocbe); 1167 break; |
|
1146 } 1147 1148 mtx_lock(&aio_job_mtx); 1149 /* Decrement the active job count. */ 1150 ki->kaio_active_count--; 1151 mtx_unlock(&aio_job_mtx); 1152 1153 AIO_LOCK(ki); --- 124 unchanged lines hidden (view full) --- 1278 struct cdev *dev; 1279 struct kaioinfo *ki; 1280 struct aioliojob *lj; 1281 int error, ref; 1282 1283 cb = &aiocbe->uaiocb; 1284 fp = aiocbe->fd_file; 1285 | 1168 } 1169 1170 mtx_lock(&aio_job_mtx); 1171 /* Decrement the active job count. */ 1172 ki->kaio_active_count--; 1173 mtx_unlock(&aio_job_mtx); 1174 1175 AIO_LOCK(ki); --- 124 unchanged lines hidden (view full) --- 1300 struct cdev *dev; 1301 struct kaioinfo *ki; 1302 struct aioliojob *lj; 1303 int error, ref; 1304 1305 cb = &aiocbe->uaiocb; 1306 fp = aiocbe->fd_file; 1307 |
1286 if (fp->f_type != DTYPE_VNODE) | 1308 if (fp == NULL || fp->f_type != DTYPE_VNODE) |
1287 return (-1); 1288 1289 vp = fp->f_vnode; 1290 1291 /* 1292 * If its not a disk, we don't want to return a positive error. 1293 * It causes the aio code to not fall through to try the thread 1294 * way when you're talking to a regular file. --- 335 unchanged lines hidden (view full) --- 1630 error = fget_write(td, fd, CAP_PWRITE, &fp); 1631 break; 1632 case LIO_READ: 1633 error = fget_read(td, fd, CAP_PREAD, &fp); 1634 break; 1635 case LIO_SYNC: 1636 error = fget(td, fd, CAP_FSYNC, &fp); 1637 break; | 1309 return (-1); 1310 1311 vp = fp->f_vnode; 1312 1313 /* 1314 * If its not a disk, we don't want to return a positive error. 1315 * It causes the aio code to not fall through to try the thread 1316 * way when you're talking to a regular file. --- 335 unchanged lines hidden (view full) --- 1652 error = fget_write(td, fd, CAP_PWRITE, &fp); 1653 break; 1654 case LIO_READ: 1655 error = fget_read(td, fd, CAP_PREAD, &fp); 1656 break; 1657 case LIO_SYNC: 1658 error = fget(td, fd, CAP_FSYNC, &fp); 1659 break; |
1660 case LIO_MLOCK: 1661 fp = NULL; 1662 break; |
|
1638 case LIO_NOP: 1639 error = fget(td, fd, CAP_NONE, &fp); 1640 break; 1641 default: 1642 error = EINVAL; 1643 } 1644 if (error) { 1645 uma_zfree(aiocb_zone, aiocbe); --- 41 unchanged lines hidden (view full) --- 1687 kev.ident = (uintptr_t)aiocbe->uuaiocb; 1688 kev.filter = EVFILT_AIO; 1689 kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1 | evflags; 1690 kev.data = (intptr_t)aiocbe; 1691 kev.udata = aiocbe->uaiocb.aio_sigevent.sigev_value.sival_ptr; 1692 error = kqfd_register(kqfd, &kev, td, 1); 1693aqueue_fail: 1694 if (error) { | 1663 case LIO_NOP: 1664 error = fget(td, fd, CAP_NONE, &fp); 1665 break; 1666 default: 1667 error = EINVAL; 1668 } 1669 if (error) { 1670 uma_zfree(aiocb_zone, aiocbe); --- 41 unchanged lines hidden (view full) --- 1712 kev.ident = (uintptr_t)aiocbe->uuaiocb; 1713 kev.filter = EVFILT_AIO; 1714 kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1 | evflags; 1715 kev.data = (intptr_t)aiocbe; 1716 kev.udata = aiocbe->uaiocb.aio_sigevent.sigev_value.sival_ptr; 1717 error = kqfd_register(kqfd, &kev, td, 1); 1718aqueue_fail: 1719 if (error) { |
1695 fdrop(fp, td); | 1720 if (fp) 1721 fdrop(fp, td); |
1696 uma_zfree(aiocb_zone, aiocbe); 1697 ops->store_error(job, error); 1698 goto done; 1699 } 1700no_kqueue: 1701 1702 ops->store_error(job, EINPROGRESS); 1703 aiocbe->uaiocb._aiocb_private.error = EINPROGRESS; 1704 aiocbe->userproc = p; 1705 aiocbe->cred = crhold(td->td_ucred); 1706 aiocbe->jobflags = 0; 1707 aiocbe->lio = lj; 1708 1709 if (opcode == LIO_SYNC) 1710 goto queueit; 1711 | 1722 uma_zfree(aiocb_zone, aiocbe); 1723 ops->store_error(job, error); 1724 goto done; 1725 } 1726no_kqueue: 1727 1728 ops->store_error(job, EINPROGRESS); 1729 aiocbe->uaiocb._aiocb_private.error = EINPROGRESS; 1730 aiocbe->userproc = p; 1731 aiocbe->cred = crhold(td->td_ucred); 1732 aiocbe->jobflags = 0; 1733 aiocbe->lio = lj; 1734 1735 if (opcode == LIO_SYNC) 1736 goto queueit; 1737 |
1712 if (fp->f_type == DTYPE_SOCKET) { | 1738 if (fp && fp->f_type == DTYPE_SOCKET) { |
1713 /* 1714 * Alternate queueing for socket ops: Reach down into the 1715 * descriptor to get the socket data. Then check to see if the 1716 * socket is ready to be read or written (based on the requested 1717 * operation). 1718 * 1719 * If it is not ready for io, then queue the aiocbe on the 1720 * socket, and set the flags so we get a call when sbnotify() --- 461 unchanged lines hidden (view full) --- 2182 2183int 2184sys_aio_write(struct thread *td, struct aio_write_args *uap) 2185{ 2186 2187 return (aio_aqueue(td, uap->aiocbp, NULL, LIO_WRITE, &aiocb_ops)); 2188} 2189 | 1739 /* 1740 * Alternate queueing for socket ops: Reach down into the 1741 * descriptor to get the socket data. Then check to see if the 1742 * socket is ready to be read or written (based on the requested 1743 * operation). 1744 * 1745 * If it is not ready for io, then queue the aiocbe on the 1746 * socket, and set the flags so we get a call when sbnotify() --- 461 unchanged lines hidden (view full) --- 2208 2209int 2210sys_aio_write(struct thread *td, struct aio_write_args *uap) 2211{ 2212 2213 return (aio_aqueue(td, uap->aiocbp, NULL, LIO_WRITE, &aiocb_ops)); 2214} 2215 |
2216int 2217sys_aio_mlock(struct thread *td, struct aio_mlock_args *uap) 2218{ 2219 2220 return (aio_aqueue(td, uap->aiocbp, NULL, LIO_MLOCK, &aiocb_ops)); 2221} 2222 |
|
2190static int 2191kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list, 2192 struct aiocb **acb_list, int nent, struct sigevent *sig, 2193 struct aiocb_ops *ops) 2194{ 2195 struct proc *p = td->td_proc; 2196 struct aiocb *iocb; 2197 struct kaioinfo *ki; --- 726 unchanged lines hidden (view full) --- 2924freebsd32_aio_write(struct thread *td, struct freebsd32_aio_write_args *uap) 2925{ 2926 2927 return (aio_aqueue(td, (struct aiocb *)uap->aiocbp, NULL, LIO_WRITE, 2928 &aiocb32_ops)); 2929} 2930 2931int | 2223static int 2224kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list, 2225 struct aiocb **acb_list, int nent, struct sigevent *sig, 2226 struct aiocb_ops *ops) 2227{ 2228 struct proc *p = td->td_proc; 2229 struct aiocb *iocb; 2230 struct kaioinfo *ki; --- 726 unchanged lines hidden (view full) --- 2957freebsd32_aio_write(struct thread *td, struct freebsd32_aio_write_args *uap) 2958{ 2959 2960 return (aio_aqueue(td, (struct aiocb *)uap->aiocbp, NULL, LIO_WRITE, 2961 &aiocb32_ops)); 2962} 2963 2964int |
2965freebsd32_aio_mlock(struct thread *td, struct freebsd32_aio_mlock_args *uap) 2966{ 2967 2968 return (aio_aqueue(td, (struct aiocb *)uap->aiocbp, NULL, LIO_MLOCK, 2969 &aiocb32_ops)); 2970} 2971 2972int |
|
2932freebsd32_aio_waitcomplete(struct thread *td, 2933 struct freebsd32_aio_waitcomplete_args *uap) 2934{ 2935 struct timespec32 ts32; 2936 struct timespec ts, *tsp; 2937 int error; 2938 2939 if (uap->timeout) { --- 113 unchanged lines hidden --- | 2973freebsd32_aio_waitcomplete(struct thread *td, 2974 struct freebsd32_aio_waitcomplete_args *uap) 2975{ 2976 struct timespec32 ts32; 2977 struct timespec ts, *tsp; 2978 int error; 2979 2980 if (uap->timeout) { --- 113 unchanged lines hidden --- |