Date: Tue, 13 Jan 2015 13:32:19 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277127 - head/sys/fs/cuse Message-ID: <201501131332.t0DDWJNb004519@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Tue Jan 13 13:32:18 2015 New Revision: 277127 URL: https://svnweb.freebsd.org/changeset/base/277127 Log: 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. Modified: head/sys/fs/cuse/cuse.c Modified: head/sys/fs/cuse/cuse.c ============================================================================== --- head/sys/fs/cuse/cuse.c Tue Jan 13 09:50:15 2015 (r277126) +++ head/sys/fs/cuse/cuse.c Tue Jan 13 13:32:18 2015 (r277127) @@ -142,6 +142,7 @@ static struct cuse_server *cuse_alloc_un 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 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_se 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, unsi * 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 e 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 e 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 e 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501131332.t0DDWJNb004519>