Skip site navigation (1)Skip section navigation (2)
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>