.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/fs/9p/trans_fd.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
7 | 8 | * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> |
---|
8 | 9 | * Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com> |
---|
9 | 10 | * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> |
---|
10 | | - * |
---|
11 | | - * This program is free software; you can redistribute it and/or modify |
---|
12 | | - * it under the terms of the GNU General Public License version 2 |
---|
13 | | - * as published by the Free Software Foundation. |
---|
14 | | - * |
---|
15 | | - * This program is distributed in the hope that it will be useful, |
---|
16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 | | - * GNU General Public License for more details. |
---|
19 | | - * |
---|
20 | | - * You should have received a copy of the GNU General Public License |
---|
21 | | - * along with this program; if not, write to: |
---|
22 | | - * Free Software Foundation |
---|
23 | | - * 51 Franklin Street, Fifth Floor |
---|
24 | | - * Boston, MA 02111-1301 USA |
---|
25 | | - * |
---|
26 | 11 | */ |
---|
27 | 12 | |
---|
28 | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
133 | 118 | struct list_head unsent_req_list; |
---|
134 | 119 | struct p9_req_t *rreq; |
---|
135 | 120 | struct p9_req_t *wreq; |
---|
136 | | - char tmp_buf[7]; |
---|
| 121 | + char tmp_buf[P9_HDRSZ]; |
---|
137 | 122 | struct p9_fcall rc; |
---|
138 | 123 | int wpos; |
---|
139 | 124 | int wsize; |
---|
.. | .. |
---|
215 | 200 | |
---|
216 | 201 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { |
---|
217 | 202 | list_move(&req->req_list, &cancel_list); |
---|
| 203 | + req->status = REQ_STATUS_ERROR; |
---|
218 | 204 | } |
---|
219 | 205 | list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) { |
---|
220 | 206 | list_move(&req->req_list, &cancel_list); |
---|
| 207 | + req->status = REQ_STATUS_ERROR; |
---|
221 | 208 | } |
---|
| 209 | + |
---|
| 210 | + spin_unlock(&m->client->lock); |
---|
222 | 211 | |
---|
223 | 212 | list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { |
---|
224 | 213 | p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); |
---|
.. | .. |
---|
227 | 216 | req->t_err = err; |
---|
228 | 217 | p9_client_cb(m->client, req, REQ_STATUS_ERROR); |
---|
229 | 218 | } |
---|
230 | | - spin_unlock(&m->client->lock); |
---|
231 | 219 | } |
---|
232 | 220 | |
---|
233 | 221 | static __poll_t |
---|
.. | .. |
---|
303 | 291 | if (!m->rc.sdata) { |
---|
304 | 292 | m->rc.sdata = m->tmp_buf; |
---|
305 | 293 | m->rc.offset = 0; |
---|
306 | | - m->rc.capacity = 7; /* start by reading header */ |
---|
| 294 | + m->rc.capacity = P9_HDRSZ; /* start by reading header */ |
---|
307 | 295 | } |
---|
308 | 296 | |
---|
309 | 297 | clear_bit(Rpending, &m->wsched); |
---|
.. | .. |
---|
326 | 314 | p9_debug(P9_DEBUG_TRANS, "got new header\n"); |
---|
327 | 315 | |
---|
328 | 316 | /* Header size */ |
---|
329 | | - m->rc.size = 7; |
---|
| 317 | + m->rc.size = P9_HDRSZ; |
---|
330 | 318 | err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0); |
---|
331 | 319 | if (err) { |
---|
332 | 320 | p9_debug(P9_DEBUG_ERROR, |
---|
.. | .. |
---|
835 | 823 | goto out_free_ts; |
---|
836 | 824 | if (!(ts->rd->f_mode & FMODE_READ)) |
---|
837 | 825 | goto out_put_rd; |
---|
| 826 | + /* prevent workers from hanging on IO when fd is a pipe */ |
---|
| 827 | + ts->rd->f_flags |= O_NONBLOCK; |
---|
838 | 828 | ts->wr = fget(wfd); |
---|
839 | 829 | if (!ts->wr) |
---|
840 | 830 | goto out_put_rd; |
---|
841 | 831 | if (!(ts->wr->f_mode & FMODE_WRITE)) |
---|
842 | 832 | goto out_put_wr; |
---|
| 833 | + ts->wr->f_flags |= O_NONBLOCK; |
---|
843 | 834 | |
---|
844 | 835 | client->trans = ts; |
---|
845 | 836 | client->status = Connected; |
---|
.. | .. |
---|
861 | 852 | struct file *file; |
---|
862 | 853 | |
---|
863 | 854 | p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); |
---|
864 | | - if (!p) |
---|
| 855 | + if (!p) { |
---|
| 856 | + sock_release(csocket); |
---|
865 | 857 | return -ENOMEM; |
---|
| 858 | + } |
---|
866 | 859 | |
---|
867 | 860 | csocket->sk->sk_allocation = GFP_NOIO; |
---|
868 | 861 | file = sock_alloc_file(csocket, 0, NULL); |
---|
.. | .. |
---|
965 | 958 | |
---|
966 | 959 | memset(&cl, 0, sizeof(cl)); |
---|
967 | 960 | cl.sin_family = AF_INET; |
---|
968 | | - cl.sin_addr.s_addr = INADDR_ANY; |
---|
| 961 | + cl.sin_addr.s_addr = htonl(INADDR_ANY); |
---|
969 | 962 | for (port = p9_ipport_resv_max; port >= p9_ipport_resv_min; port--) { |
---|
970 | 963 | cl.sin_port = htons((ushort)port); |
---|
971 | 964 | err = kernel_bind(sock, (struct sockaddr *)&cl, sizeof(cl)); |
---|