svn commit: r277127 - head/sys/fs/cuse

Hans Petter Selasky hselasky at FreeBSD.org
Tue Jan 13 13:32:19 UTC 2015


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


More information about the svn-src-head mailing list