hide kqueue_register from public view, and replace it w/ kqfd_register...

this eliminates a possible race in aio registering a kevent..
This commit is contained in:
John-Mark Gurney 2006-09-24 04:47:47 +00:00
parent aeab19b21f
commit 4db71d27a1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=162594
3 changed files with 38 additions and 37 deletions

View File

@ -88,6 +88,8 @@ TASKQUEUE_DEFINE_THREAD(kqueue);
static int kevent_copyout(void *arg, struct kevent *kevp, int count);
static int kevent_copyin(void *arg, struct kevent *kevp, int count);
static int kqueue_register(struct kqueue *kq, struct kevent *kev,
struct thread *td, int waitok);
static int kqueue_aquire(struct file *fp, struct kqueue **kqp);
static void kqueue_release(struct kqueue *kq, int locked);
static int kqueue_expand(struct kqueue *kq, struct filterops *fops,
@ -783,11 +785,11 @@ kqueue_fo_release(int filt)
}
/*
* A ref to kq (obtained via kqueue_aquire) should be held. waitok will
* A ref to kq (obtained via kqueue_aquire) must be held. waitok will
* influence if memory allocation should wait. Make sure it is 0 if you
* hold any mutexes.
*/
int
static int
kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int waitok)
{
struct filterops *fops;
@ -1939,3 +1941,29 @@ knote_free(struct knote *kn)
if (kn != NULL)
uma_zfree(knote_zone, kn);
}
/*
* Register the kev w/ the kq specified by fd.
*/
int
kqfd_register(int fd, struct kevent *kev, struct thread *td, int waitok)
{
struct kqueue *kq;
struct file *fp;
int error;
if ((error = fget(td, fd, &fp)) != 0)
return (error);
if ((error = kqueue_aquire(fp, &kq)) != 0)
goto noaquire;
error = kqueue_register(kq, kev, td, waitok);
kqueue_release(kq, 0);
noaquire:
if (fp != NULL)
fdrop(fp, td);
return error;
}

View File

@ -1332,12 +1332,10 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
struct aiocblist *aiocbe, *cb;
struct kaioinfo *ki;
struct kevent kev;
struct kqueue *kq;
struct file *kq_fp;
struct sockbuf *sb;
int opcode;
int error;
int fd;
int fd, kqfd;
int jid;
if (p->p_aioinfo == NULL)
@ -1452,26 +1450,15 @@ aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
goto aqueue_fail;
}
if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_KEVENT)
kev.ident = aiocbe->uaiocb.aio_sigevent.sigev_notify_kqueue;
else
if (aiocbe->uaiocb.aio_sigevent.sigev_notify != SIGEV_KEVENT)
goto no_kqueue;
error = fget(td, (u_int)kev.ident, &kq_fp);
if (error)
goto aqueue_fail;
if (kq_fp->f_type != DTYPE_KQUEUE) {
fdrop(kq_fp, td);
error = EBADF;
goto aqueue_fail;
}
kq = kq_fp->f_data;
kqfd = aiocbe->uaiocb.aio_sigevent.sigev_notify_kqueue;
kev.ident = (uintptr_t)aiocbe->uuaiocb;
kev.filter = EVFILT_AIO;
kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1;
kev.data = (intptr_t)aiocbe;
kev.udata = aiocbe->uaiocb.aio_sigevent.sigev_value.sival_ptr;
error = kqueue_register(kq, &kev, td, 1);
fdrop(kq_fp, td);
error = kqfd_register(kqfd, &kev, td, 1);
aqueue_fail:
if (error) {
fdrop(fp, td);
@ -1979,8 +1966,6 @@ do_lio_listio(struct thread *td, struct lio_listio_args *uap, int oldsigev)
struct kaioinfo *ki;
struct aioliojob *lj;
struct kevent kev;
struct kqueue * kq;
struct file *kq_fp;
int nent;
int error;
int nerror;
@ -2020,26 +2005,14 @@ do_lio_listio(struct thread *td, struct lio_listio_args *uap, int oldsigev)
if (lj->lioj_signal.sigev_notify == SIGEV_KEVENT) {
/* Assume only new style KEVENT */
error = fget(td, lj->lioj_signal.sigev_notify_kqueue,
&kq_fp);
if (error) {
uma_zfree(aiolio_zone, lj);
return (error);
}
if (kq_fp->f_type != DTYPE_KQUEUE) {
fdrop(kq_fp, td);
uma_zfree(aiolio_zone, lj);
return (EBADF);
}
kq = (struct kqueue *)kq_fp->f_data;
kev.filter = EVFILT_LIO;
kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1;
kev.ident = (uintptr_t)uap->acb_list; /* something unique */
kev.data = (intptr_t)lj;
/* pass user defined sigval data */
kev.udata = lj->lioj_signal.sigev_value.sival_ptr;
error = kqueue_register(kq, &kev, td, 1);
fdrop(kq_fp, td);
error = kqfd_register(
lj->lioj_signal.sigev_notify_kqueue, &kev, td, 1);
if (error) {
uma_zfree(aiolio_zone, lj);
return (error);

View File

@ -218,8 +218,8 @@ extern void knlist_cleardel(struct knlist *knl, struct thread *td,
#define knlist_delete(knl, td, islocked) \
knlist_cleardel((knl), (td), (islocked), 1)
extern void knote_fdclose(struct thread *p, int fd);
extern int kqueue_register(struct kqueue *kq,
struct kevent *kev, struct thread *p, int waitok);
extern int kqfd_register(int fd, struct kevent *kev, struct thread *p,
int waitok);
extern int kqueue_add_filteropts(int filt, struct filterops *filtops);
extern int kqueue_del_filteropts(int filt);