int error;
};
+static struct lwkt_token mapped_ioctl_token = LWKT_TOKEN_MP_INITIALIZER;
+
static int doselect(int nd, fd_set *in, fd_set *ou, fd_set *ex,
struct timespec *ts, int *res);
static int dopoll(int nfds, struct pollfd *fds, struct timespec *ts,
/*
* Ioctl system call
*
- * MPALMOSTSAFE
+ * MPSAFE
*/
int
sys_ioctl(struct ioctl_args *uap)
{
int error;
- get_mplock();
error = mapped_ioctl(uap->fd, uap->com, uap->data, NULL, &uap->sysmsg);
- rel_mplock();
return (error);
}
* The true heart of all ioctl syscall handlers (native, emulation).
* If map != NULL, it will be searched for a matching entry for com,
* and appropriate conversions/conversion functions will be utilized.
+ *
+ * MPSAFE
*/
int
mapped_ioctl(int fd, u_long com, caddr_t uspc_data, struct ioctl_map *map,
maskcmd = com & map->mask;
+ lwkt_gettoken(&mapped_ioctl_token);
LIST_FOREACH(e, &map->mapping, entries) {
for (iomc = e->cmd_ranges; iomc->start != 0 ||
iomc->maptocmd != 0 || iomc->wrapfunc != NULL ||
iomc->wrapfunc != NULL || iomc->mapfunc != NULL)
break;
}
+ lwkt_reltoken(&mapped_ioctl_token);
if (iomc == NULL ||
(iomc->start == 0 && iomc->maptocmd == 0
switch (com) {
case FIONBIO:
if ((tmp = *(int *)data))
- fp->f_flag |= FNONBLOCK;
+ atomic_set_int(&fp->f_flag, FNONBLOCK);
else
- fp->f_flag &= ~FNONBLOCK;
+ atomic_clear_int(&fp->f_flag, FNONBLOCK);
error = 0;
break;
case FIOASYNC:
if ((tmp = *(int *)data))
- fp->f_flag |= FASYNC;
+ atomic_set_int(&fp->f_flag, FASYNC);
else
- fp->f_flag &= ~FASYNC;
+ atomic_clear_int(&fp->f_flag, FASYNC);
error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, cred, msg);
break;
return(error);
}
+/*
+ * MPSAFE
+ */
int
mapped_ioctl_register_handler(struct ioctl_map_handler *he)
{
KKASSERT(he != NULL && he->map != NULL && he->cmd_ranges != NULL &&
he->subsys != NULL && *he->subsys != '\0');
- ne = kmalloc(sizeof(struct ioctl_map_entry), M_IOCTLMAP, M_WAITOK);
+ ne = kmalloc(sizeof(struct ioctl_map_entry), M_IOCTLMAP,
+ M_WAITOK | M_ZERO);
ne->subsys = he->subsys;
ne->cmd_ranges = he->cmd_ranges;
+ lwkt_gettoken(&mapped_ioctl_token);
LIST_INSERT_HEAD(&he->map->mapping, ne, entries);
+ lwkt_reltoken(&mapped_ioctl_token);
return(0);
}
+/*
+ * MPSAFE
+ */
int
mapped_ioctl_unregister_handler(struct ioctl_map_handler *he)
{
struct ioctl_map_entry *ne;
+ int error = EINVAL;
KKASSERT(he != NULL && he->map != NULL && he->cmd_ranges != NULL);
+ lwkt_gettoken(&mapped_ioctl_token);
LIST_FOREACH(ne, &he->map->mapping, entries) {
- if (ne->cmd_ranges != he->cmd_ranges)
- continue;
- LIST_REMOVE(ne, entries);
- kfree(ne, M_IOCTLMAP);
- return(0);
+ if (ne->cmd_ranges == he->cmd_ranges) {
+ LIST_REMOVE(ne, entries);
+ kfree(ne, M_IOCTLMAP);
+ error = 0;
+ break;
+ }
}
- return(EINVAL);
+ lwkt_reltoken(&mapped_ioctl_token);
+ return(error);
}
static int nselcoll; /* Select collisions since boot */