diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-07-16 22:53:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-11-28 11:07:13 -0500 |
commit | 7594bf37ae9ffc434da425120c576909eb33b0bc (patch) | |
tree | ccbb8b447e97b56420e383961a5842f2c4547875 /net/9p | |
parent | 5dc533c66b131726a1a747eb3c92b20a9ede9219 (diff) |
9p: untangle ->poll() mess
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>
Diffstat (limited to 'net/9p')
-rw-r--r-- | net/9p/trans_fd.c | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 985046ae4231..439014113a5c 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -228,32 +228,31 @@ static void p9_conn_cancel(struct p9_conn *m, int err) | |||
228 | } | 228 | } |
229 | } | 229 | } |
230 | 230 | ||
231 | static int | 231 | static __poll_t |
232 | p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt) | 232 | p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err) |
233 | { | 233 | { |
234 | int ret, n; | 234 | __poll_t ret, n; |
235 | struct p9_trans_fd *ts = NULL; | 235 | struct p9_trans_fd *ts = NULL; |
236 | 236 | ||
237 | if (client && client->status == Connected) | 237 | if (client && client->status == Connected) |
238 | ts = client->trans; | 238 | ts = client->trans; |
239 | 239 | ||
240 | if (!ts) | 240 | if (!ts) { |
241 | return -EREMOTEIO; | 241 | if (err) |
242 | *err = -EREMOTEIO; | ||
243 | return POLLERR; | ||
244 | } | ||
242 | 245 | ||
243 | if (!ts->rd->f_op->poll) | 246 | if (!ts->rd->f_op->poll) |
244 | return -EIO; | 247 | ret = DEFAULT_POLLMASK; |
245 | 248 | else | |
246 | if (!ts->wr->f_op->poll) | 249 | ret = ts->rd->f_op->poll(ts->rd, pt); |
247 | return -EIO; | ||
248 | |||
249 | ret = ts->rd->f_op->poll(ts->rd, pt); | ||
250 | if (ret < 0) | ||
251 | return ret; | ||
252 | 250 | ||
253 | if (ts->rd != ts->wr) { | 251 | if (ts->rd != ts->wr) { |
254 | n = ts->wr->f_op->poll(ts->wr, pt); | 252 | if (!ts->wr->f_op->poll) |
255 | if (n < 0) | 253 | n = DEFAULT_POLLMASK; |
256 | return n; | 254 | else |
255 | n = ts->wr->f_op->poll(ts->wr, pt); | ||
257 | ret = (ret & ~POLLOUT) | (n & ~POLLIN); | 256 | ret = (ret & ~POLLOUT) | (n & ~POLLIN); |
258 | } | 257 | } |
259 | 258 | ||
@@ -298,7 +297,8 @@ static int p9_fd_read(struct p9_client *client, void *v, int len) | |||
298 | 297 | ||
299 | static void p9_read_work(struct work_struct *work) | 298 | static void p9_read_work(struct work_struct *work) |
300 | { | 299 | { |
301 | int n, err; | 300 | __poll_t n; |
301 | int err; | ||
302 | struct p9_conn *m; | 302 | struct p9_conn *m; |
303 | int status = REQ_STATUS_ERROR; | 303 | int status = REQ_STATUS_ERROR; |
304 | 304 | ||
@@ -398,7 +398,7 @@ end_clear: | |||
398 | if (test_and_clear_bit(Rpending, &m->wsched)) | 398 | if (test_and_clear_bit(Rpending, &m->wsched)) |
399 | n = POLLIN; | 399 | n = POLLIN; |
400 | else | 400 | else |
401 | n = p9_fd_poll(m->client, NULL); | 401 | n = p9_fd_poll(m->client, NULL, NULL); |
402 | 402 | ||
403 | if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) { | 403 | if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) { |
404 | p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m); | 404 | 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) | |||
448 | 448 | ||
449 | static void p9_write_work(struct work_struct *work) | 449 | static void p9_write_work(struct work_struct *work) |
450 | { | 450 | { |
451 | int n, err; | 451 | __poll_t n; |
452 | int err; | ||
452 | struct p9_conn *m; | 453 | struct p9_conn *m; |
453 | struct p9_req_t *req; | 454 | struct p9_req_t *req; |
454 | 455 | ||
@@ -506,7 +507,7 @@ end_clear: | |||
506 | if (test_and_clear_bit(Wpending, &m->wsched)) | 507 | if (test_and_clear_bit(Wpending, &m->wsched)) |
507 | n = POLLOUT; | 508 | n = POLLOUT; |
508 | else | 509 | else |
509 | n = p9_fd_poll(m->client, NULL); | 510 | n = p9_fd_poll(m->client, NULL, NULL); |
510 | 511 | ||
511 | if ((n & POLLOUT) && | 512 | if ((n & POLLOUT) && |
512 | !test_and_set_bit(Wworksched, &m->wsched)) { | 513 | !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) | |||
581 | 582 | ||
582 | static void p9_conn_create(struct p9_client *client) | 583 | static void p9_conn_create(struct p9_client *client) |
583 | { | 584 | { |
584 | int n; | 585 | __poll_t n; |
585 | struct p9_trans_fd *ts = client->trans; | 586 | struct p9_trans_fd *ts = client->trans; |
586 | struct p9_conn *m = &ts->conn; | 587 | struct p9_conn *m = &ts->conn; |
587 | 588 | ||
@@ -597,7 +598,7 @@ static void p9_conn_create(struct p9_client *client) | |||
597 | INIT_LIST_HEAD(&m->poll_pending_link); | 598 | INIT_LIST_HEAD(&m->poll_pending_link); |
598 | init_poll_funcptr(&m->pt, p9_pollwait); | 599 | init_poll_funcptr(&m->pt, p9_pollwait); |
599 | 600 | ||
600 | n = p9_fd_poll(client, &m->pt); | 601 | n = p9_fd_poll(client, &m->pt, NULL); |
601 | if (n & POLLIN) { | 602 | if (n & POLLIN) { |
602 | p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m); | 603 | p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m); |
603 | set_bit(Rpending, &m->wsched); | 604 | set_bit(Rpending, &m->wsched); |
@@ -617,17 +618,16 @@ static void p9_conn_create(struct p9_client *client) | |||
617 | 618 | ||
618 | static void p9_poll_mux(struct p9_conn *m) | 619 | static void p9_poll_mux(struct p9_conn *m) |
619 | { | 620 | { |
620 | int n; | 621 | __poll_t n; |
622 | int err = -ECONNRESET; | ||
621 | 623 | ||
622 | if (m->err < 0) | 624 | if (m->err < 0) |
623 | return; | 625 | return; |
624 | 626 | ||
625 | n = p9_fd_poll(m->client, NULL); | 627 | n = p9_fd_poll(m->client, NULL, &err); |
626 | if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) { | 628 | if (n & (POLLERR | POLLHUP | POLLNVAL)) { |
627 | p9_debug(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n); | 629 | p9_debug(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n); |
628 | if (n >= 0) | 630 | p9_conn_cancel(m, err); |
629 | n = -ECONNRESET; | ||
630 | p9_conn_cancel(m, n); | ||
631 | } | 631 | } |
632 | 632 | ||
633 | if (n & POLLIN) { | 633 | if (n & POLLIN) { |
@@ -663,7 +663,7 @@ static void p9_poll_mux(struct p9_conn *m) | |||
663 | 663 | ||
664 | static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) | 664 | static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) |
665 | { | 665 | { |
666 | int n; | 666 | __poll_t n; |
667 | struct p9_trans_fd *ts = client->trans; | 667 | struct p9_trans_fd *ts = client->trans; |
668 | struct p9_conn *m = &ts->conn; | 668 | struct p9_conn *m = &ts->conn; |
669 | 669 | ||
@@ -680,7 +680,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) | |||
680 | if (test_and_clear_bit(Wpending, &m->wsched)) | 680 | if (test_and_clear_bit(Wpending, &m->wsched)) |
681 | n = POLLOUT; | 681 | n = POLLOUT; |
682 | else | 682 | else |
683 | n = p9_fd_poll(m->client, NULL); | 683 | n = p9_fd_poll(m->client, NULL, NULL); |
684 | 684 | ||
685 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) | 685 | if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched)) |
686 | schedule_work(&m->wq); | 686 | schedule_work(&m->wq); |