Fix sigevent's POSIX incompatible problem by adding member fields
sigev_notify_function and sigev_notify_attributes. AIO syscalls use sigevent, so they have to be adjusted. Reviewed by: alc
This commit is contained in:
parent
70293cc76a
commit
0972628aff
@ -467,9 +467,11 @@
|
||||
u_int nfds, int timeout); }
|
||||
253 AUE_NULL MSTD { int issetugid(void); }
|
||||
254 AUE_NULL MSTD { int lchown(char *path, int uid, int gid); }
|
||||
255 AUE_NULL UNIMPL nosys
|
||||
256 AUE_NULL UNIMPL nosys
|
||||
257 AUE_NULL UNIMPL nosys
|
||||
255 AUE_NULL NOSTD { int aio_read(struct aiocb *aiocbp); }
|
||||
256 AUE_NULL NOSTD { int aio_write(struct aiocb *aiocbp); }
|
||||
257 AUE_NULL NOSTD { int lio_listio(int mode, \
|
||||
struct aiocb * const *acb_list, \
|
||||
int nent, struct sigevent *sig); }
|
||||
258 AUE_NULL UNIMPL nosys
|
||||
259 AUE_NULL UNIMPL nosys
|
||||
260 AUE_NULL UNIMPL nosys
|
||||
@ -551,11 +553,11 @@
|
||||
316 AUE_NULL NOSTD { int aio_cancel(int fd, \
|
||||
struct aiocb *aiocbp); }
|
||||
317 AUE_NULL NOSTD { int aio_error(struct aiocb *aiocbp); }
|
||||
318 AUE_NULL NOSTD { int aio_read(struct aiocb *aiocbp); }
|
||||
319 AUE_NULL NOSTD { int aio_write(struct aiocb *aiocbp); }
|
||||
320 AUE_NULL NOSTD { int lio_listio(int mode, \
|
||||
struct aiocb * const *acb_list, \
|
||||
int nent, struct sigevent *sig); }
|
||||
318 AUE_NULL NOSTD { int oaio_read(struct oaiocb *aiocbp); }
|
||||
319 AUE_NULL NOSTD { int oaio_write(struct oaiocb *aiocbp); }
|
||||
320 AUE_NULL NOSTD { int olio_listio(int mode, \
|
||||
struct oaiocb * const *acb_list, \
|
||||
int nent, struct osigevent *sig); }
|
||||
321 AUE_NULL MSTD { int yield(void); }
|
||||
322 AUE_NULL OBSOL thr_sleep
|
||||
323 AUE_NULL OBSOL thr_wakeup
|
||||
|
@ -170,6 +170,17 @@ static int max_buf_aio = MAX_BUF_AIO;
|
||||
SYSCTL_INT(_vfs_aio, OID_AUTO, max_buf_aio, CTLFLAG_RW, &max_buf_aio, 0,
|
||||
"Maximum buf aio requests per process (stored in the process)");
|
||||
|
||||
typedef struct oaiocb {
|
||||
int aio_fildes; /* File descriptor */
|
||||
off_t aio_offset; /* File offset for I/O */
|
||||
volatile void *aio_buf; /* I/O buffer in process space */
|
||||
size_t aio_nbytes; /* Number of bytes for I/O */
|
||||
struct osigevent aio_sigevent; /* Signal to deliver */
|
||||
int aio_lio_opcode; /* LIO opcode */
|
||||
int aio_reqprio; /* Request priority -- ignored */
|
||||
struct __aiocb_private _aiocb_private;
|
||||
} oaiocb_t;
|
||||
|
||||
struct aiocblist {
|
||||
TAILQ_ENTRY(aiocblist) list; /* List of jobs */
|
||||
TAILQ_ENTRY(aiocblist) plist; /* List of jobs for proc */
|
||||
@ -254,7 +265,8 @@ static void aio_onceonly(void);
|
||||
static int aio_free_entry(struct aiocblist *aiocbe);
|
||||
static void aio_process(struct aiocblist *aiocbe);
|
||||
static int aio_newproc(void);
|
||||
static int aio_aqueue(struct thread *td, struct aiocb *job, int type);
|
||||
static int aio_aqueue(struct thread *td, struct aiocb *job, int type,
|
||||
int osigev);
|
||||
static void aio_physwakeup(struct buf *bp);
|
||||
static void aio_proc_rundown(void *arg, struct proc *p);
|
||||
static int aio_fphysio(struct aiocblist *aiocbe);
|
||||
@ -271,6 +283,8 @@ static int filt_lio(struct knote *kn, long hint);
|
||||
#define DONE_BUF 1
|
||||
#define DONE_QUEUE 2
|
||||
static void aio_bio_done_notify( struct proc *userp, struct aiocblist *aiocbe, int type);
|
||||
static int do_lio_listio(struct thread *td, struct lio_listio_args *uap,
|
||||
int oldsigev);
|
||||
|
||||
/*
|
||||
* Zones for:
|
||||
@ -328,6 +342,9 @@ SYSCALL_MODULE_HELPER(aio_read);
|
||||
SYSCALL_MODULE_HELPER(aio_write);
|
||||
SYSCALL_MODULE_HELPER(aio_waitcomplete);
|
||||
SYSCALL_MODULE_HELPER(lio_listio);
|
||||
SYSCALL_MODULE_HELPER(oaio_read);
|
||||
SYSCALL_MODULE_HELPER(oaio_write);
|
||||
SYSCALL_MODULE_HELPER(olio_listio);
|
||||
|
||||
DECLARE_MODULE(aio, aio_mod,
|
||||
SI_SUB_VFS, SI_ORDER_ANY);
|
||||
@ -1320,7 +1337,8 @@ aio_swake_cb(struct socket *so, struct sockbuf *sb)
|
||||
* technique is done in this code.
|
||||
*/
|
||||
static int
|
||||
_aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int type)
|
||||
_aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj,
|
||||
int type, int oldsigev)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
struct filedesc *fdp;
|
||||
@ -1348,7 +1366,14 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
|
||||
suword(&job->_aiocb_private.error, 0);
|
||||
suword(&job->_aiocb_private.kernelinfo, -1);
|
||||
|
||||
error = copyin(job, &aiocbe->uaiocb, sizeof(aiocbe->uaiocb));
|
||||
if (oldsigev) {
|
||||
bzero(&aiocbe->uaiocb, sizeof(struct aiocb));
|
||||
error = copyin(job, &aiocbe->uaiocb, sizeof(struct oaiocb));
|
||||
bcopy(&aiocbe->uaiocb.__spare__, &aiocbe->uaiocb.aio_sigevent,
|
||||
sizeof(struct osigevent));
|
||||
} else {
|
||||
error = copyin(job, &aiocbe->uaiocb, sizeof(struct aiocb));
|
||||
}
|
||||
if (error) {
|
||||
suword(&job->_aiocb_private.error, error);
|
||||
uma_zfree(aiocb_zone, aiocbe);
|
||||
@ -1558,7 +1583,7 @@ done:
|
||||
* This routine queues an AIO request, checking for quotas.
|
||||
*/
|
||||
static int
|
||||
aio_aqueue(struct thread *td, struct aiocb *job, int type)
|
||||
aio_aqueue(struct thread *td, struct aiocb *job, int type, int oldsigev)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
struct kaioinfo *ki;
|
||||
@ -1573,7 +1598,7 @@ aio_aqueue(struct thread *td, struct aiocb *job, int type)
|
||||
if (ki->kaio_queue_count >= ki->kaio_qallowed_count)
|
||||
return (EAGAIN);
|
||||
|
||||
return _aio_aqueue(td, job, NULL, type);
|
||||
return _aio_aqueue(td, job, NULL, type, oldsigev);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1956,24 +1981,51 @@ aio_error(struct thread *td, struct aio_error_args *uap)
|
||||
}
|
||||
|
||||
/* syscall - asynchronous read from a file (REALTIME) */
|
||||
int
|
||||
oaio_read(struct thread *td, struct oaio_read_args *uap)
|
||||
{
|
||||
|
||||
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, LIO_READ, 1);
|
||||
}
|
||||
|
||||
int
|
||||
aio_read(struct thread *td, struct aio_read_args *uap)
|
||||
{
|
||||
|
||||
return aio_aqueue(td, uap->aiocbp, LIO_READ);
|
||||
return aio_aqueue(td, uap->aiocbp, LIO_READ, 0);
|
||||
}
|
||||
|
||||
/* syscall - asynchronous write to a file (REALTIME) */
|
||||
int
|
||||
oaio_write(struct thread *td, struct oaio_write_args *uap)
|
||||
{
|
||||
|
||||
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, LIO_WRITE, 1);
|
||||
}
|
||||
|
||||
int
|
||||
aio_write(struct thread *td, struct aio_write_args *uap)
|
||||
{
|
||||
|
||||
return aio_aqueue(td, uap->aiocbp, LIO_WRITE);
|
||||
return aio_aqueue(td, uap->aiocbp, LIO_WRITE, 0);
|
||||
}
|
||||
|
||||
/* syscall - list directed I/O (REALTIME) */
|
||||
int
|
||||
olio_listio(struct thread *td, struct olio_listio_args *uap)
|
||||
{
|
||||
return do_lio_listio(td, (struct lio_listio_args *)uap, 1);
|
||||
}
|
||||
|
||||
/* syscall - list directed I/O (REALTIME) */
|
||||
int
|
||||
lio_listio(struct thread *td, struct lio_listio_args *uap)
|
||||
{
|
||||
return do_lio_listio(td, uap, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
do_lio_listio(struct thread *td, struct lio_listio_args *uap, int oldsigev)
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
int nent, nentqueued;
|
||||
@ -2023,8 +2075,10 @@ lio_listio(struct thread *td, struct lio_listio_args *uap)
|
||||
* Setup signal.
|
||||
*/
|
||||
if (uap->sig && (uap->mode == LIO_NOWAIT)) {
|
||||
bzero(&lj->lioj_signal, sizeof(&lj->lioj_signal));
|
||||
error = copyin(uap->sig, &lj->lioj_signal,
|
||||
sizeof(lj->lioj_signal));
|
||||
oldsigev ? sizeof(struct osigevent) :
|
||||
sizeof(struct sigevent));
|
||||
if (error) {
|
||||
uma_zfree(aiolio_zone, lj);
|
||||
return (error);
|
||||
@ -2071,7 +2125,7 @@ lio_listio(struct thread *td, struct lio_listio_args *uap)
|
||||
for (i = 0; i < uap->nent; i++) {
|
||||
iocb = (struct aiocb *)(intptr_t)fuword(&cbptr[i]);
|
||||
if (((intptr_t)iocb != -1) && ((intptr_t)iocb != 0)) {
|
||||
error = _aio_aqueue(td, iocb, lj, 0);
|
||||
error = _aio_aqueue(td, iocb, lj, 0, oldsigev);
|
||||
if (error == 0)
|
||||
nentqueued++;
|
||||
else
|
||||
|
@ -66,10 +66,11 @@ typedef struct aiocb {
|
||||
off_t aio_offset; /* File offset for I/O */
|
||||
volatile void *aio_buf; /* I/O buffer in process space */
|
||||
size_t aio_nbytes; /* Number of bytes for I/O */
|
||||
struct sigevent aio_sigevent; /* Signal to deliver */
|
||||
char __spare__[sizeof(int) * 2 + sizeof(void *)]; /* osigevent. */
|
||||
int aio_lio_opcode; /* LIO opcode */
|
||||
int aio_reqprio; /* Request priority -- ignored */
|
||||
struct __aiocb_private _aiocb_private;
|
||||
struct sigevent aio_sigevent; /* Signal to deliver */
|
||||
} aiocb_t;
|
||||
|
||||
#ifndef _KERNEL
|
||||
|
@ -158,28 +158,31 @@ union sigval {
|
||||
#if __POSIX_VISIBLE >= 199309
|
||||
struct sigevent {
|
||||
int sigev_notify; /* Notification type */
|
||||
union {
|
||||
int __sigev_signo; /* Signal number */
|
||||
int __sigev_notify_kqueue;
|
||||
} __sigev_u;
|
||||
int sigev_signo; /* Signal number */
|
||||
union sigval sigev_value; /* Signal value */
|
||||
/*
|
||||
* XXX missing sigev_notify_function, sigev_notify_attributes.
|
||||
*/
|
||||
union {
|
||||
__lwpid_t _threadid;
|
||||
struct {
|
||||
void (*_function)(union sigval *);
|
||||
void *_attribute; /* pthread_attr_t * */
|
||||
} _sigev_thread;
|
||||
} _sigev_un;
|
||||
};
|
||||
#define sigev_signo __sigev_u.__sigev_signo
|
||||
#if __BSD_VISIBLE
|
||||
#define sigev_notify_kqueue __sigev_u.__sigev_notify_kqueue
|
||||
#endif
|
||||
|
||||
#define SIGEV_NONE 0 /* No async notification */
|
||||
#define SIGEV_SIGNAL 1 /* Generate a queued signal */
|
||||
#if __BSD_VISIBLE
|
||||
#define SIGEV_KEVENT 3 /* Generate a kevent */
|
||||
#define sigev_notify_kqueue sigev_signo
|
||||
#define sigev_notify_thread_id _sigev_un._threadid
|
||||
#endif
|
||||
#define sigev_notify_function _sigev_un._sigev_thread._function
|
||||
#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
|
||||
|
||||
#define SIGEV_NONE 0 /* No async notification. */
|
||||
#define SIGEV_SIGNAL 1 /* Generate a queued signal. */
|
||||
#define SIGEV_THREAD 2 /* Call back from another pthread. */
|
||||
#if __BSD_VISIBLE
|
||||
#define SIGEV_KEVENT 3 /* Generate a kevent. */
|
||||
#define SIGEV_THREAD_ID 4 /* Send signal to a kernel thread. */
|
||||
#endif
|
||||
/*
|
||||
* XXX missing SIGEV_THREAD.
|
||||
*/
|
||||
#endif /* __POSIX_VISIBLE >= 199309 */
|
||||
|
||||
#if __POSIX_VISIBLE >= 199309 || __XSI_VISIBLE
|
||||
|
@ -199,6 +199,15 @@ __sigseteq(sigset_t *set1, sigset_t *set2)
|
||||
return (1);
|
||||
}
|
||||
|
||||
struct osigevent {
|
||||
int sigev_notify; /* Notification type */
|
||||
union {
|
||||
int __sigev_signo; /* Signal number */
|
||||
int __sigev_notify_kqueue;
|
||||
} __sigev_u;
|
||||
union sigval sigev_value; /* Signal value */
|
||||
};
|
||||
|
||||
typedef struct ksiginfo {
|
||||
TAILQ_ENTRY(ksiginfo) ksi_link;
|
||||
siginfo_t ksi_info;
|
||||
|
Loading…
x
Reference in New Issue
Block a user