mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-17 15:27:36 +00:00
Don't use POLLNVAL as a return value from the client side poll
function. Many existing clients don't understand POLLNVAL and instead relies on an error code from the read(), write() or ioctl() system call. Also make sure we wakeup any client pollers before the cuse server is closing, so they don't wait forever for an event.
This commit is contained in:
parent
43d5c9f65a
commit
9570004318
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=277127
@ -142,6 +142,7 @@ static struct cuse_server *cuse_alloc_unit[CUSE_DEVICES_MAX];
|
||||
static int cuse_alloc_unit_id[CUSE_DEVICES_MAX];
|
||||
static struct cuse_memory cuse_mem[CUSE_ALLOC_UNIT_MAX];
|
||||
|
||||
static void cuse_server_wakeup_all_client_locked(struct cuse_server *pcs);
|
||||
static void cuse_client_kqfilter_read_detach(struct knote *kn);
|
||||
static void cuse_client_kqfilter_write_detach(struct knote *kn);
|
||||
static int cuse_client_kqfilter_read_event(struct knote *kn, long hint);
|
||||
@ -648,6 +649,8 @@ cuse_server_free(void *arg)
|
||||
return;
|
||||
}
|
||||
cuse_server_is_closing(pcs);
|
||||
/* final client wakeup, if any */
|
||||
cuse_server_wakeup_all_client_locked(pcs);
|
||||
|
||||
TAILQ_REMOVE(&cuse_server_head, pcs, entry);
|
||||
|
||||
@ -716,6 +719,9 @@ cuse_server_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
|
||||
|
||||
cuse_lock();
|
||||
cuse_server_is_closing(pcs);
|
||||
/* final client wakeup, if any */
|
||||
cuse_server_wakeup_all_client_locked(pcs);
|
||||
|
||||
knlist_clear(&pcs->selinfo.si_note, 1);
|
||||
cuse_unlock();
|
||||
|
||||
@ -920,6 +926,18 @@ cuse_server_wakeup_locked(struct cuse_server *pcs)
|
||||
KNOTE_LOCKED(&pcs->selinfo.si_note, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
cuse_server_wakeup_all_client_locked(struct cuse_server *pcs)
|
||||
{
|
||||
struct cuse_client *pcc;
|
||||
|
||||
TAILQ_FOREACH(pcc, &pcs->hcli, entry) {
|
||||
pcc->cflags |= (CUSE_CLI_KNOTE_NEED_READ |
|
||||
CUSE_CLI_KNOTE_NEED_WRITE);
|
||||
}
|
||||
cuse_server_wakeup_locked(pcs);
|
||||
}
|
||||
|
||||
static int
|
||||
cuse_free_unit_by_id_locked(struct cuse_server *pcs, int id)
|
||||
{
|
||||
@ -1226,11 +1244,7 @@ cuse_server_ioctl(struct cdev *dev, unsigned long cmd,
|
||||
* We don't know which direction caused the event.
|
||||
* Wakeup both!
|
||||
*/
|
||||
TAILQ_FOREACH(pcc, &pcs->hcli, entry) {
|
||||
pcc->cflags |= (CUSE_CLI_KNOTE_NEED_READ |
|
||||
CUSE_CLI_KNOTE_NEED_WRITE);
|
||||
}
|
||||
cuse_server_wakeup_locked(pcs);
|
||||
cuse_server_wakeup_all_client_locked(pcs);
|
||||
cuse_unlock();
|
||||
break;
|
||||
|
||||
@ -1677,7 +1691,7 @@ cuse_client_poll(struct cdev *dev, int events, struct thread *td)
|
||||
|
||||
error = cuse_client_get(&pcc);
|
||||
if (error != 0)
|
||||
return (POLLNVAL);
|
||||
goto pollnval;
|
||||
|
||||
temp = 0;
|
||||
|
||||
@ -1705,8 +1719,10 @@ cuse_client_poll(struct cdev *dev, int events, struct thread *td)
|
||||
error = cuse_client_receive_command_locked(pccmd, 0, 0);
|
||||
cuse_unlock();
|
||||
|
||||
cuse_cmd_unlock(pccmd);
|
||||
|
||||
if (error < 0) {
|
||||
revents = POLLNVAL;
|
||||
goto pollnval;
|
||||
} else {
|
||||
revents = 0;
|
||||
if (error & CUSE_POLL_READ)
|
||||
@ -1716,10 +1732,12 @@ cuse_client_poll(struct cdev *dev, int events, struct thread *td)
|
||||
if (error & CUSE_POLL_ERROR)
|
||||
revents |= (events & POLLHUP);
|
||||
}
|
||||
|
||||
cuse_cmd_unlock(pccmd);
|
||||
|
||||
return (revents);
|
||||
|
||||
pollnval:
|
||||
/* XXX many clients don't understand POLLNVAL */
|
||||
return (events & (POLLHUP | POLLPRI | POLLIN |
|
||||
POLLRDNORM | POLLOUT | POLLWRNORM));
|
||||
}
|
||||
|
||||
static int
|
||||
|
Loading…
Reference in New Issue
Block a user