9p: untangle ->poll() mess
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 17 Jul 2017 02:53:08 +0000 (22:53 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Tue, 28 Nov 2017 16:07:13 +0000 (11:07 -0500)
First of all, NULL ->poll() means "always POLLIN, always POLLOUT", not an error.
Furthermore, mixing -EREMOTEIO with POLL... masks and expecting it to do anything
good is insane - both are arch-dependent, to start with.  Pass a pointer to
store the error value separately and make it return POLLERR in such case.

And ->poll() calling conventions do *not* include "return -Esomething".  Never
had.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
net/9p/trans_fd.c

index 985046ae42312e86505d6fded2fb56501c38536b..439014113a5cfa142e1f306888c9c094472db84b 100644 (file)
@@ -228,32 +228,31 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
        }
 }
 
-static int
-p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
+static __poll_t
+p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)
 {
-       int ret, n;
+       __poll_t ret, n;
        struct p9_trans_fd *ts = NULL;
 
        if (client && client->status == Connected)
                ts = client->trans;
 
-       if (!ts)
-               return -EREMOTEIO;
+       if (!ts) {
+               if (err)
+                       *err = -EREMOTEIO;
+               return POLLERR;
+       }
 
        if (!ts->rd->f_op->poll)
-               return -EIO;
-
-       if (!ts->wr->f_op->poll)
-               return -EIO;
-
-       ret = ts->rd->f_op->poll(ts->rd, pt);
-       if (ret < 0)
-               return ret;
+               ret = DEFAULT_POLLMASK;
+       else
+               ret = ts->rd->f_op->poll(ts->rd, pt);
 
        if (ts->rd != ts->wr) {
-               n = ts->wr->f_op->poll(ts->wr, pt);
-               if (n < 0)
-                       return n;
+               if (!ts->wr->f_op->poll)
+                       n = DEFAULT_POLLMASK;
+               else
+                       n = ts->wr->f_op->poll(ts->wr, pt);
                ret = (ret & ~POLLOUT) | (n & ~POLLIN);
        }
 
@@ -298,7 +297,8 @@ static int p9_fd_read(struct p9_client *client, void *v, int len)
 
 static void p9_read_work(struct work_struct *work)
 {
-       int n, err;
+       __poll_t n;
+       int err;
        struct p9_conn *m;
        int status = REQ_STATUS_ERROR;
 
@@ -398,7 +398,7 @@ end_clear:
                if (test_and_clear_bit(Rpending, &m->wsched))
                        n = POLLIN;
                else
-                       n = p9_fd_poll(m->client, NULL);
+                       n = p9_fd_poll(m->client, NULL, NULL);
 
                if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
                        p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
@@ -448,7 +448,8 @@ static int p9_fd_write(struct p9_client *client, void *v, int len)
 
 static void p9_write_work(struct work_struct *work)
 {
-       int n, err;
+       __poll_t n;
+       int err;
        struct p9_conn *m;
        struct p9_req_t *req;
 
@@ -506,7 +507,7 @@ end_clear:
                if (test_and_clear_bit(Wpending, &m->wsched))
                        n = POLLOUT;
                else
-                       n = p9_fd_poll(m->client, NULL);
+                       n = p9_fd_poll(m->client, NULL, NULL);
 
                if ((n & POLLOUT) &&
                   !test_and_set_bit(Wworksched, &m->wsched)) {
@@ -581,7 +582,7 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
 
 static void p9_conn_create(struct p9_client *client)
 {
-       int n;
+       __poll_t n;
        struct p9_trans_fd *ts = client->trans;
        struct p9_conn *m = &ts->conn;
 
@@ -597,7 +598,7 @@ static void p9_conn_create(struct p9_client *client)
        INIT_LIST_HEAD(&m->poll_pending_link);
        init_poll_funcptr(&m->pt, p9_pollwait);
 
-       n = p9_fd_poll(client, &m->pt);
+       n = p9_fd_poll(client, &m->pt, NULL);
        if (n & POLLIN) {
                p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
                set_bit(Rpending, &m->wsched);
@@ -617,17 +618,16 @@ static void p9_conn_create(struct p9_client *client)
 
 static void p9_poll_mux(struct p9_conn *m)
 {
-       int n;
+       __poll_t n;
+       int err = -ECONNRESET;
 
        if (m->err < 0)
                return;
 
-       n = p9_fd_poll(m->client, NULL);
-       if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
+       n = p9_fd_poll(m->client, NULL, &err);
+       if (n & (POLLERR | POLLHUP | POLLNVAL)) {
                p9_debug(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n);
-               if (n >= 0)
-                       n = -ECONNRESET;
-               p9_conn_cancel(m, n);
+               p9_conn_cancel(m, err);
        }
 
        if (n & POLLIN) {
@@ -663,7 +663,7 @@ static void p9_poll_mux(struct p9_conn *m)
 
 static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
 {
-       int n;
+       __poll_t n;
        struct p9_trans_fd *ts = client->trans;
        struct p9_conn *m = &ts->conn;
 
@@ -680,7 +680,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
        if (test_and_clear_bit(Wpending, &m->wsched))
                n = POLLOUT;
        else
-               n = p9_fd_poll(m->client, NULL);
+               n = p9_fd_poll(m->client, NULL, NULL);
 
        if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
                schedule_work(&m->wq);