blob: 9f020559c19281eb700dbede3d861b5772c25353 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * linux/fs/9p/trans_fd.c
3 *
4 * Fd transport layer. Includes deprecated socket layer.
5 *
6 * Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
7 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
8 * Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
9 * 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 */
27
28#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29
30#include <linux/in.h>
31#include <linux/module.h>
32#include <linux/net.h>
33#include <linux/ipv6.h>
34#include <linux/kthread.h>
35#include <linux/errno.h>
36#include <linux/kernel.h>
37#include <linux/un.h>
38#include <linux/uaccess.h>
39#include <linux/inet.h>
40#include <linux/idr.h>
41#include <linux/file.h>
42#include <linux/parser.h>
43#include <linux/slab.h>
44#include <linux/seq_file.h>
45#include <net/9p/9p.h>
46#include <net/9p/client.h>
47#include <net/9p/transport.h>
48
49#include <linux/syscalls.h> /* killme */
50
51#define P9_PORT 564
52#define MAX_SOCK_BUF (64*1024)
53#define MAXPOLLWADDR 2
54
55static struct p9_trans_module p9_tcp_trans;
56static struct p9_trans_module p9_fd_trans;
57
58/**
59 * struct p9_fd_opts - per-transport options
60 * @rfd: file descriptor for reading (trans=fd)
61 * @wfd: file descriptor for writing (trans=fd)
62 * @port: port to connect to (trans=tcp)
63 *
64 */
65
66struct p9_fd_opts {
67 int rfd;
68 int wfd;
69 u16 port;
70 bool privport;
71};
72
73/*
74 * Option Parsing (code inspired by NFS code)
75 * - a little lazy - parse all fd-transport options
76 */
77
78enum {
79 /* Options that take integer arguments */
80 Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
81 /* Options that take no arguments */
82 Opt_privport,
83};
84
85static const match_table_t tokens = {
86 {Opt_port, "port=%u"},
87 {Opt_rfdno, "rfdno=%u"},
88 {Opt_wfdno, "wfdno=%u"},
89 {Opt_privport, "privport"},
90 {Opt_err, NULL},
91};
92
93enum {
94 Rworksched = 1, /* read work scheduled or running */
95 Rpending = 2, /* can read */
96 Wworksched = 4, /* write work scheduled or running */
97 Wpending = 8, /* can write */
98};
99
100struct p9_poll_wait {
101 struct p9_conn *conn;
102 wait_queue_entry_t wait;
103 wait_queue_head_t *wait_addr;
104};
105
106/**
107 * struct p9_conn - fd mux connection state information
108 * @mux_list: list link for mux to manage multiple connections (?)
109 * @client: reference to client instance for this connection
110 * @err: error state
111 * @req_list: accounting for requests which have been sent
112 * @unsent_req_list: accounting for requests that haven't been sent
113 * @req: current request being processed (if any)
114 * @tmp_buf: temporary buffer to read in header
115 * @rc: temporary fcall for reading current frame
116 * @wpos: write position for current frame
117 * @wsize: amount of data to write for current frame
118 * @wbuf: current write buffer
119 * @poll_pending_link: pending links to be polled per conn
120 * @poll_wait: array of wait_q's for various worker threads
121 * @pt: poll state
122 * @rq: current read work
123 * @wq: current write work
124 * @wsched: ????
125 *
126 */
127
128struct p9_conn {
129 struct list_head mux_list;
130 struct p9_client *client;
131 int err;
132 struct list_head req_list;
133 struct list_head unsent_req_list;
134 struct p9_req_t *req;
135 char tmp_buf[7];
136 struct p9_fcall rc;
137 int wpos;
138 int wsize;
139 char *wbuf;
140 struct list_head poll_pending_link;
141 struct p9_poll_wait poll_wait[MAXPOLLWADDR];
142 poll_table pt;
143 struct work_struct rq;
144 struct work_struct wq;
145 unsigned long wsched;
146};
147
148/**
149 * struct p9_trans_fd - transport state
150 * @rd: reference to file to read from
151 * @wr: reference of file to write to
152 * @conn: connection state reference
153 *
154 */
155
156struct p9_trans_fd {
157 struct file *rd;
158 struct file *wr;
159 struct p9_conn conn;
160};
161
162static void p9_poll_workfn(struct work_struct *work);
163
164static DEFINE_SPINLOCK(p9_poll_lock);
165static LIST_HEAD(p9_poll_pending_list);
166static DECLARE_WORK(p9_poll_work, p9_poll_workfn);
167
168static unsigned int p9_ipport_resv_min = P9_DEF_MIN_RESVPORT;
169static unsigned int p9_ipport_resv_max = P9_DEF_MAX_RESVPORT;
170
171static void p9_mux_poll_stop(struct p9_conn *m)
172{
173 unsigned long flags;
174 int i;
175
176 for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
177 struct p9_poll_wait *pwait = &m->poll_wait[i];
178
179 if (pwait->wait_addr) {
180 remove_wait_queue(pwait->wait_addr, &pwait->wait);
181 pwait->wait_addr = NULL;
182 }
183 }
184
185 spin_lock_irqsave(&p9_poll_lock, flags);
186 list_del_init(&m->poll_pending_link);
187 spin_unlock_irqrestore(&p9_poll_lock, flags);
188
189 flush_work(&p9_poll_work);
190}
191
192/**
193 * p9_conn_cancel - cancel all pending requests with error
194 * @m: mux data
195 * @err: error code
196 *
197 */
198
199static void p9_conn_cancel(struct p9_conn *m, int err)
200{
201 struct p9_req_t *req, *rtmp;
202 LIST_HEAD(cancel_list);
203
204 p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
205
206 spin_lock(&m->client->lock);
207
208 if (m->err) {
209 spin_unlock(&m->client->lock);
210 return;
211 }
212
213 m->err = err;
214
215 list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
216 list_move(&req->req_list, &cancel_list);
217 }
218 list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
219 list_move(&req->req_list, &cancel_list);
220 }
221
222 list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
223 p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);
224 list_del(&req->req_list);
225 if (!req->t_err)
226 req->t_err = err;
227 p9_client_cb(m->client, req, REQ_STATUS_ERROR);
228 }
229 spin_unlock(&m->client->lock);
230}
231
232static int
233p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
234{
235 int ret, n;
236 struct p9_trans_fd *ts = NULL;
237
238 if (client && client->status == Connected)
239 ts = client->trans;
240
241 if (!ts)
242 return -EREMOTEIO;
243
244 if (!ts->rd->f_op->poll)
245 return -EIO;
246
247 if (!ts->wr->f_op->poll)
248 return -EIO;
249
250 ret = ts->rd->f_op->poll(ts->rd, pt);
251 if (ret < 0)
252 return ret;
253
254 if (ts->rd != ts->wr) {
255 n = ts->wr->f_op->poll(ts->wr, pt);
256 if (n < 0)
257 return n;
258 ret = (ret & ~POLLOUT) | (n & ~POLLIN);
259 }
260
261 return ret;
262}
263
264/**
265 * p9_fd_read- read from a fd
266 * @client: client instance
267 * @v: buffer to receive data into
268 * @len: size of receive buffer
269 *
270 */
271
272static int p9_fd_read(struct p9_client *client, void *v, int len)
273{
274 int ret;
275 struct p9_trans_fd *ts = NULL;
276 loff_t pos;
277
278 if (client && client->status != Disconnected)
279 ts = client->trans;
280
281 if (!ts)
282 return -EREMOTEIO;
283
284 if (!(ts->rd->f_flags & O_NONBLOCK))
285 p9_debug(P9_DEBUG_ERROR, "blocking read ...\n");
286
287 pos = ts->rd->f_pos;
288 ret = kernel_read(ts->rd, v, len, &pos);
289 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
290 client->status = Disconnected;
291 return ret;
292}
293
294/**
295 * p9_read_work - called when there is some data to be read from a transport
296 * @work: container of work to be done
297 *
298 */
299
300static void p9_read_work(struct work_struct *work)
301{
302 int n, err;
303 struct p9_conn *m;
304
305 m = container_of(work, struct p9_conn, rq);
306
307 if (m->err < 0)
308 return;
309
310 p9_debug(P9_DEBUG_TRANS, "start mux %p pos %zd\n", m, m->rc.offset);
311
312 if (!m->rc.sdata) {
313 m->rc.sdata = m->tmp_buf;
314 m->rc.offset = 0;
315 m->rc.capacity = 7; /* start by reading header */
316 }
317
318 clear_bit(Rpending, &m->wsched);
319 p9_debug(P9_DEBUG_TRANS, "read mux %p pos %zd size: %zd = %zd\n",
320 m, m->rc.offset, m->rc.capacity,
321 m->rc.capacity - m->rc.offset);
322 err = p9_fd_read(m->client, m->rc.sdata + m->rc.offset,
323 m->rc.capacity - m->rc.offset);
324 p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
325 if (err == -EAGAIN)
326 goto end_clear;
327
328 if (err <= 0)
329 goto error;
330
331 m->rc.offset += err;
332
333 /* header read in */
334 if ((!m->req) && (m->rc.offset == m->rc.capacity)) {
335 p9_debug(P9_DEBUG_TRANS, "got new header\n");
336
337 err = p9_parse_header(&m->rc, NULL, NULL, NULL, 0);
338 if (err) {
339 p9_debug(P9_DEBUG_ERROR,
340 "error parsing header: %d\n", err);
341 goto error;
342 }
343
344 if (m->rc.size >= m->client->msize) {
345 p9_debug(P9_DEBUG_ERROR,
346 "requested packet size too big: %d\n",
347 m->rc.size);
348 err = -EIO;
349 goto error;
350 }
351
352 p9_debug(P9_DEBUG_TRANS,
353 "mux %p pkt: size: %d bytes tag: %d\n",
354 m, m->rc.size, m->rc.tag);
355
356 m->req = p9_tag_lookup(m->client, m->rc.tag);
357 if (!m->req || (m->req->status != REQ_STATUS_SENT)) {
358 p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
359 m->rc.tag);
360 err = -EIO;
361 goto error;
362 }
363
364 if (m->req->rc == NULL) {
365 p9_debug(P9_DEBUG_ERROR,
366 "No recv fcall for tag %d (req %p), disconnecting!\n",
367 m->rc.tag, m->req);
368 m->req = NULL;
369 err = -EIO;
370 goto error;
371 }
372 m->rc.sdata = (char *)m->req->rc + sizeof(struct p9_fcall);
373 memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
374 m->rc.capacity = m->rc.size;
375 }
376
377 /* packet is read in
378 * not an else because some packets (like clunk) have no payload
379 */
380 if ((m->req) && (m->rc.offset == m->rc.capacity)) {
381 p9_debug(P9_DEBUG_TRANS, "got new packet\n");
382 spin_lock(&m->client->lock);
383 if (m->req->status == REQ_STATUS_SENT) {
384 list_del(&m->req->req_list);
385 p9_client_cb(m->client, m->req, REQ_STATUS_RCVD);
386 } else if (m->req->status == REQ_STATUS_FLSHD) {
387 /* Ignore replies associated with a cancelled request. */
388 p9_debug(P9_DEBUG_TRANS,
389 "Ignore replies associated with a cancelled request\n");
390 } else {
391 spin_unlock(&m->client->lock);
392 p9_debug(P9_DEBUG_ERROR,
393 "Request tag %d errored out while we were reading the reply\n",
394 m->rc.tag);
395 err = -EIO;
396 goto error;
397 }
398 spin_unlock(&m->client->lock);
399 m->rc.sdata = NULL;
400 m->rc.offset = 0;
401 m->rc.capacity = 0;
402 m->req = NULL;
403 }
404
405end_clear:
406 clear_bit(Rworksched, &m->wsched);
407
408 if (!list_empty(&m->req_list)) {
409 if (test_and_clear_bit(Rpending, &m->wsched))
410 n = POLLIN;
411 else
412 n = p9_fd_poll(m->client, NULL);
413
414 if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
415 p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
416 schedule_work(&m->rq);
417 }
418 }
419
420 return;
421error:
422 p9_conn_cancel(m, err);
423 clear_bit(Rworksched, &m->wsched);
424}
425
426/**
427 * p9_fd_write - write to a socket
428 * @client: client instance
429 * @v: buffer to send data from
430 * @len: size of send buffer
431 *
432 */
433
434static int p9_fd_write(struct p9_client *client, void *v, int len)
435{
436 ssize_t ret;
437 struct p9_trans_fd *ts = NULL;
438
439 if (client && client->status != Disconnected)
440 ts = client->trans;
441
442 if (!ts)
443 return -EREMOTEIO;
444
445 if (!(ts->wr->f_flags & O_NONBLOCK))
446 p9_debug(P9_DEBUG_ERROR, "blocking write ...\n");
447
448 ret = kernel_write(ts->wr, v, len, &ts->wr->f_pos);
449 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
450 client->status = Disconnected;
451 return ret;
452}
453
454/**
455 * p9_write_work - called when a transport can send some data
456 * @work: container for work to be done
457 *
458 */
459
460static void p9_write_work(struct work_struct *work)
461{
462 int n, err;
463 struct p9_conn *m;
464 struct p9_req_t *req;
465
466 m = container_of(work, struct p9_conn, wq);
467
468 if (m->err < 0) {
469 clear_bit(Wworksched, &m->wsched);
470 return;
471 }
472
473 if (!m->wsize) {
474 spin_lock(&m->client->lock);
475 if (list_empty(&m->unsent_req_list)) {
476 clear_bit(Wworksched, &m->wsched);
477 spin_unlock(&m->client->lock);
478 return;
479 }
480
481 req = list_entry(m->unsent_req_list.next, struct p9_req_t,
482 req_list);
483 req->status = REQ_STATUS_SENT;
484 p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
485 list_move_tail(&req->req_list, &m->req_list);
486
487 m->wbuf = req->tc->sdata;
488 m->wsize = req->tc->size;
489 m->wpos = 0;
490 spin_unlock(&m->client->lock);
491 }
492
493 p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n",
494 m, m->wpos, m->wsize);
495 clear_bit(Wpending, &m->wsched);
496 err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
497 p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
498 if (err == -EAGAIN)
499 goto end_clear;
500
501
502 if (err < 0)
503 goto error;
504 else if (err == 0) {
505 err = -EREMOTEIO;
506 goto error;
507 }
508
509 m->wpos += err;
510 if (m->wpos == m->wsize)
511 m->wpos = m->wsize = 0;
512
513end_clear:
514 clear_bit(Wworksched, &m->wsched);
515
516 if (m->wsize || !list_empty(&m->unsent_req_list)) {
517 if (test_and_clear_bit(Wpending, &m->wsched))
518 n = POLLOUT;
519 else
520 n = p9_fd_poll(m->client, NULL);
521
522 if ((n & POLLOUT) &&
523 !test_and_set_bit(Wworksched, &m->wsched)) {
524 p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
525 schedule_work(&m->wq);
526 }
527 }
528
529 return;
530
531error:
532 p9_conn_cancel(m, err);
533 clear_bit(Wworksched, &m->wsched);
534}
535
536static int p9_pollwake(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
537{
538 struct p9_poll_wait *pwait =
539 container_of(wait, struct p9_poll_wait, wait);
540 struct p9_conn *m = pwait->conn;
541 unsigned long flags;
542
543 spin_lock_irqsave(&p9_poll_lock, flags);
544 if (list_empty(&m->poll_pending_link))
545 list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
546 spin_unlock_irqrestore(&p9_poll_lock, flags);
547
548 schedule_work(&p9_poll_work);
549 return 1;
550}
551
552/**
553 * p9_pollwait - add poll task to the wait queue
554 * @filp: file pointer being polled
555 * @wait_address: wait_q to block on
556 * @p: poll state
557 *
558 * called by files poll operation to add v9fs-poll task to files wait queue
559 */
560
561static void
562p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
563{
564 struct p9_conn *m = container_of(p, struct p9_conn, pt);
565 struct p9_poll_wait *pwait = NULL;
566 int i;
567
568 for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
569 if (m->poll_wait[i].wait_addr == NULL) {
570 pwait = &m->poll_wait[i];
571 break;
572 }
573 }
574
575 if (!pwait) {
576 p9_debug(P9_DEBUG_ERROR, "not enough wait_address slots\n");
577 return;
578 }
579
580 pwait->conn = m;
581 pwait->wait_addr = wait_address;
582 init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
583 add_wait_queue(wait_address, &pwait->wait);
584}
585
586/**
587 * p9_conn_create - initialize the per-session mux data
588 * @client: client instance
589 *
590 * Note: Creates the polling task if this is the first session.
591 */
592
593static void p9_conn_create(struct p9_client *client)
594{
595 int n;
596 struct p9_trans_fd *ts = client->trans;
597 struct p9_conn *m = &ts->conn;
598
599 p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize);
600
601 INIT_LIST_HEAD(&m->mux_list);
602 m->client = client;
603
604 INIT_LIST_HEAD(&m->req_list);
605 INIT_LIST_HEAD(&m->unsent_req_list);
606 INIT_WORK(&m->rq, p9_read_work);
607 INIT_WORK(&m->wq, p9_write_work);
608 INIT_LIST_HEAD(&m->poll_pending_link);
609 init_poll_funcptr(&m->pt, p9_pollwait);
610
611 n = p9_fd_poll(client, &m->pt);
612 if (n & POLLIN) {
613 p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
614 set_bit(Rpending, &m->wsched);
615 }
616
617 if (n & POLLOUT) {
618 p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
619 set_bit(Wpending, &m->wsched);
620 }
621}
622
623/**
624 * p9_poll_mux - polls a mux and schedules read or write works if necessary
625 * @m: connection to poll
626 *
627 */
628
629static void p9_poll_mux(struct p9_conn *m)
630{
631 int n;
632
633 if (m->err < 0)
634 return;
635
636 n = p9_fd_poll(m->client, NULL);
637 if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
638 p9_debug(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n);
639 if (n >= 0)
640 n = -ECONNRESET;
641 p9_conn_cancel(m, n);
642 }
643
644 if (n & POLLIN) {
645 set_bit(Rpending, &m->wsched);
646 p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
647 if (!test_and_set_bit(Rworksched, &m->wsched)) {
648 p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
649 schedule_work(&m->rq);
650 }
651 }
652
653 if (n & POLLOUT) {
654 set_bit(Wpending, &m->wsched);
655 p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
656 if ((m->wsize || !list_empty(&m->unsent_req_list)) &&
657 !test_and_set_bit(Wworksched, &m->wsched)) {
658 p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
659 schedule_work(&m->wq);
660 }
661 }
662}
663
664/**
665 * p9_fd_request - send 9P request
666 * The function can sleep until the request is scheduled for sending.
667 * The function can be interrupted. Return from the function is not
668 * a guarantee that the request is sent successfully.
669 *
670 * @client: client instance
671 * @req: request to be sent
672 *
673 */
674
675static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
676{
677 int n;
678 struct p9_trans_fd *ts = client->trans;
679 struct p9_conn *m = &ts->conn;
680
681 p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
682 m, current, req->tc, req->tc->id);
683 if (m->err < 0)
684 return m->err;
685
686 spin_lock(&client->lock);
687 req->status = REQ_STATUS_UNSENT;
688 list_add_tail(&req->req_list, &m->unsent_req_list);
689 spin_unlock(&client->lock);
690
691 if (test_and_clear_bit(Wpending, &m->wsched))
692 n = POLLOUT;
693 else
694 n = p9_fd_poll(m->client, NULL);
695
696 if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
697 schedule_work(&m->wq);
698
699 return 0;
700}
701
702static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
703{
704 int ret = 1;
705
706 p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
707
708 spin_lock(&client->lock);
709
710 if (req->status == REQ_STATUS_UNSENT) {
711 list_del(&req->req_list);
712 req->status = REQ_STATUS_FLSHD;
713 ret = 0;
714 }
715 spin_unlock(&client->lock);
716
717 return ret;
718}
719
720static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
721{
722 p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
723
724 spin_lock(&client->lock);
725 /* Ignore cancelled request if message has been received
726 * before lock.
727 */
728 if (req->status == REQ_STATUS_RCVD) {
729 spin_unlock(&client->lock);
730 return 0;
731 }
732
733 /* we haven't received a response for oldreq,
734 * remove it from the list.
735 */
736 list_del(&req->req_list);
737 req->status = REQ_STATUS_FLSHD;
738 spin_unlock(&client->lock);
739
740 return 0;
741}
742
743static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt)
744{
745 if (clnt->trans_mod == &p9_tcp_trans) {
746 if (clnt->trans_opts.tcp.port != P9_PORT)
747 seq_printf(m, ",port=%u", clnt->trans_opts.tcp.port);
748 } else if (clnt->trans_mod == &p9_fd_trans) {
749 if (clnt->trans_opts.fd.rfd != ~0)
750 seq_printf(m, ",rfd=%u", clnt->trans_opts.fd.rfd);
751 if (clnt->trans_opts.fd.wfd != ~0)
752 seq_printf(m, ",wfd=%u", clnt->trans_opts.fd.wfd);
753 }
754 return 0;
755}
756
757/**
758 * parse_opts - parse mount options into p9_fd_opts structure
759 * @params: options string passed from mount
760 * @opts: fd transport-specific structure to parse options into
761 *
762 * Returns 0 upon success, -ERRNO upon failure
763 */
764
765static int parse_opts(char *params, struct p9_fd_opts *opts)
766{
767 char *p;
768 substring_t args[MAX_OPT_ARGS];
769 int option;
770 char *options, *tmp_options;
771
772 opts->port = P9_PORT;
773 opts->rfd = ~0;
774 opts->wfd = ~0;
775 opts->privport = false;
776
777 if (!params)
778 return 0;
779
780 tmp_options = kstrdup(params, GFP_KERNEL);
781 if (!tmp_options) {
782 p9_debug(P9_DEBUG_ERROR,
783 "failed to allocate copy of option string\n");
784 return -ENOMEM;
785 }
786 options = tmp_options;
787
788 while ((p = strsep(&options, ",")) != NULL) {
789 int token;
790 int r;
791 if (!*p)
792 continue;
793 token = match_token(p, tokens, args);
794 if ((token != Opt_err) && (token != Opt_privport)) {
795 r = match_int(&args[0], &option);
796 if (r < 0) {
797 p9_debug(P9_DEBUG_ERROR,
798 "integer field, but no integer?\n");
799 continue;
800 }
801 }
802 switch (token) {
803 case Opt_port:
804 opts->port = option;
805 break;
806 case Opt_rfdno:
807 opts->rfd = option;
808 break;
809 case Opt_wfdno:
810 opts->wfd = option;
811 break;
812 case Opt_privport:
813 opts->privport = true;
814 break;
815 default:
816 continue;
817 }
818 }
819
820 kfree(tmp_options);
821 return 0;
822}
823
824static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
825{
826 struct p9_trans_fd *ts = kzalloc(sizeof(struct p9_trans_fd),
827 GFP_KERNEL);
828 if (!ts)
829 return -ENOMEM;
830
831 ts->rd = fget(rfd);
832 if (!ts->rd)
833 goto out_free_ts;
834 if (!(ts->rd->f_mode & FMODE_READ))
835 goto out_put_rd;
836 ts->wr = fget(wfd);
837 if (!ts->wr)
838 goto out_put_rd;
839 if (!(ts->wr->f_mode & FMODE_WRITE))
840 goto out_put_wr;
841
842 client->trans = ts;
843 client->status = Connected;
844
845 return 0;
846
847out_put_wr:
848 fput(ts->wr);
849out_put_rd:
850 fput(ts->rd);
851out_free_ts:
852 kfree(ts);
853 return -EIO;
854}
855
856static int p9_socket_open(struct p9_client *client, struct socket *csocket)
857{
858 struct p9_trans_fd *p;
859 struct file *file;
860
861 p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
862 if (!p)
863 return -ENOMEM;
864
865 csocket->sk->sk_allocation = GFP_NOIO;
866 file = sock_alloc_file(csocket, 0, NULL);
867 if (IS_ERR(file)) {
868 pr_err("%s (%d): failed to map fd\n",
869 __func__, task_pid_nr(current));
870 sock_release(csocket);
871 kfree(p);
872 return PTR_ERR(file);
873 }
874
875 get_file(file);
876 p->wr = p->rd = file;
877 client->trans = p;
878 client->status = Connected;
879
880 p->rd->f_flags |= O_NONBLOCK;
881
882 p9_conn_create(client);
883 return 0;
884}
885
886/**
887 * p9_mux_destroy - cancels all pending requests of mux
888 * @m: mux to destroy
889 *
890 */
891
892static void p9_conn_destroy(struct p9_conn *m)
893{
894 p9_debug(P9_DEBUG_TRANS, "mux %p prev %p next %p\n",
895 m, m->mux_list.prev, m->mux_list.next);
896
897 p9_mux_poll_stop(m);
898 cancel_work_sync(&m->rq);
899 cancel_work_sync(&m->wq);
900
901 p9_conn_cancel(m, -ECONNRESET);
902
903 m->client = NULL;
904}
905
906/**
907 * p9_fd_close - shutdown file descriptor transport
908 * @client: client instance
909 *
910 */
911
912static void p9_fd_close(struct p9_client *client)
913{
914 struct p9_trans_fd *ts;
915
916 if (!client)
917 return;
918
919 ts = client->trans;
920 if (!ts)
921 return;
922
923 client->status = Disconnected;
924
925 p9_conn_destroy(&ts->conn);
926
927 if (ts->rd)
928 fput(ts->rd);
929 if (ts->wr)
930 fput(ts->wr);
931
932 kfree(ts);
933}
934
935/*
936 * stolen from NFS - maybe should be made a generic function?
937 */
938static inline int valid_ipaddr4(const char *buf)
939{
940 int rc, count, in[4];
941
942 rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
943 if (rc != 4)
944 return -EINVAL;
945 for (count = 0; count < 4; count++) {
946 if (in[count] > 255)
947 return -EINVAL;
948 }
949 return 0;
950}
951
952static int p9_bind_privport(struct socket *sock)
953{
954 struct sockaddr_in cl;
955 int port, err = -EINVAL;
956
957 memset(&cl, 0, sizeof(cl));
958 cl.sin_family = AF_INET;
959 cl.sin_addr.s_addr = INADDR_ANY;
960 for (port = p9_ipport_resv_max; port >= p9_ipport_resv_min; port--) {
961 cl.sin_port = htons((ushort)port);
962 err = kernel_bind(sock, (struct sockaddr *)&cl, sizeof(cl));
963 if (err != -EADDRINUSE)
964 break;
965 }
966 return err;
967}
968
969
970static int
971p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
972{
973 int err;
974 struct socket *csocket;
975 struct sockaddr_in sin_server;
976 struct p9_fd_opts opts;
977
978 err = parse_opts(args, &opts);
979 if (err < 0)
980 return err;
981
982 if (addr == NULL || valid_ipaddr4(addr) < 0)
983 return -EINVAL;
984
985 csocket = NULL;
986
987 client->trans_opts.tcp.port = opts.port;
988 client->trans_opts.tcp.privport = opts.privport;
989 sin_server.sin_family = AF_INET;
990 sin_server.sin_addr.s_addr = in_aton(addr);
991 sin_server.sin_port = htons(opts.port);
992 err = __sock_create(current->nsproxy->net_ns, PF_INET,
993 SOCK_STREAM, IPPROTO_TCP, &csocket, 1);
994 if (err) {
995 pr_err("%s (%d): problem creating socket\n",
996 __func__, task_pid_nr(current));
997 return err;
998 }
999
1000 if (opts.privport) {
1001 err = p9_bind_privport(csocket);
1002 if (err < 0) {
1003 pr_err("%s (%d): problem binding to privport\n",
1004 __func__, task_pid_nr(current));
1005 sock_release(csocket);
1006 return err;
1007 }
1008 }
1009
1010 err = csocket->ops->connect(csocket,
1011 (struct sockaddr *)&sin_server,
1012 sizeof(struct sockaddr_in), 0);
1013 if (err < 0) {
1014 pr_err("%s (%d): problem connecting socket to %s\n",
1015 __func__, task_pid_nr(current), addr);
1016 sock_release(csocket);
1017 return err;
1018 }
1019
1020 return p9_socket_open(client, csocket);
1021}
1022
1023static int
1024p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
1025{
1026 int err;
1027 struct socket *csocket;
1028 struct sockaddr_un sun_server;
1029
1030 csocket = NULL;
1031
1032 if (addr == NULL)
1033 return -EINVAL;
1034
1035 if (strlen(addr) >= UNIX_PATH_MAX) {
1036 pr_err("%s (%d): address too long: %s\n",
1037 __func__, task_pid_nr(current), addr);
1038 return -ENAMETOOLONG;
1039 }
1040
1041 sun_server.sun_family = PF_UNIX;
1042 strcpy(sun_server.sun_path, addr);
1043 err = __sock_create(current->nsproxy->net_ns, PF_UNIX,
1044 SOCK_STREAM, 0, &csocket, 1);
1045 if (err < 0) {
1046 pr_err("%s (%d): problem creating socket\n",
1047 __func__, task_pid_nr(current));
1048
1049 return err;
1050 }
1051 err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
1052 sizeof(struct sockaddr_un) - 1, 0);
1053 if (err < 0) {
1054 pr_err("%s (%d): problem connecting socket: %s: %d\n",
1055 __func__, task_pid_nr(current), addr, err);
1056 sock_release(csocket);
1057 return err;
1058 }
1059
1060 return p9_socket_open(client, csocket);
1061}
1062
1063static int
1064p9_fd_create(struct p9_client *client, const char *addr, char *args)
1065{
1066 int err;
1067 struct p9_fd_opts opts;
1068
1069 parse_opts(args, &opts);
1070 client->trans_opts.fd.rfd = opts.rfd;
1071 client->trans_opts.fd.wfd = opts.wfd;
1072
1073 if (opts.rfd == ~0 || opts.wfd == ~0) {
1074 pr_err("Insufficient options for proto=fd\n");
1075 return -ENOPROTOOPT;
1076 }
1077
1078 err = p9_fd_open(client, opts.rfd, opts.wfd);
1079 if (err < 0)
1080 return err;
1081
1082 p9_conn_create(client);
1083
1084 return 0;
1085}
1086
1087static struct p9_trans_module p9_tcp_trans = {
1088 .name = "tcp",
1089 .maxsize = MAX_SOCK_BUF,
1090 .def = 0,
1091 .create = p9_fd_create_tcp,
1092 .close = p9_fd_close,
1093 .request = p9_fd_request,
1094 .cancel = p9_fd_cancel,
1095 .cancelled = p9_fd_cancelled,
1096 .show_options = p9_fd_show_options,
1097 .owner = THIS_MODULE,
1098};
1099
1100static struct p9_trans_module p9_unix_trans = {
1101 .name = "unix",
1102 .maxsize = MAX_SOCK_BUF,
1103 .def = 0,
1104 .create = p9_fd_create_unix,
1105 .close = p9_fd_close,
1106 .request = p9_fd_request,
1107 .cancel = p9_fd_cancel,
1108 .cancelled = p9_fd_cancelled,
1109 .show_options = p9_fd_show_options,
1110 .owner = THIS_MODULE,
1111};
1112
1113static struct p9_trans_module p9_fd_trans = {
1114 .name = "fd",
1115 .maxsize = MAX_SOCK_BUF,
1116 .def = 0,
1117 .create = p9_fd_create,
1118 .close = p9_fd_close,
1119 .request = p9_fd_request,
1120 .cancel = p9_fd_cancel,
1121 .cancelled = p9_fd_cancelled,
1122 .show_options = p9_fd_show_options,
1123 .owner = THIS_MODULE,
1124};
1125
1126/**
1127 * p9_poll_proc - poll worker thread
1128 * @a: thread state and arguments
1129 *
1130 * polls all v9fs transports for new events and queues the appropriate
1131 * work to the work queue
1132 *
1133 */
1134
1135static void p9_poll_workfn(struct work_struct *work)
1136{
1137 unsigned long flags;
1138
1139 p9_debug(P9_DEBUG_TRANS, "start %p\n", current);
1140
1141 spin_lock_irqsave(&p9_poll_lock, flags);
1142 while (!list_empty(&p9_poll_pending_list)) {
1143 struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
1144 struct p9_conn,
1145 poll_pending_link);
1146 list_del_init(&conn->poll_pending_link);
1147 spin_unlock_irqrestore(&p9_poll_lock, flags);
1148
1149 p9_poll_mux(conn);
1150
1151 spin_lock_irqsave(&p9_poll_lock, flags);
1152 }
1153 spin_unlock_irqrestore(&p9_poll_lock, flags);
1154
1155 p9_debug(P9_DEBUG_TRANS, "finish\n");
1156}
1157
1158int p9_trans_fd_init(void)
1159{
1160 v9fs_register_trans(&p9_tcp_trans);
1161 v9fs_register_trans(&p9_unix_trans);
1162 v9fs_register_trans(&p9_fd_trans);
1163
1164 return 0;
1165}
1166
1167void p9_trans_fd_exit(void)
1168{
1169 flush_work(&p9_poll_work);
1170 v9fs_unregister_trans(&p9_tcp_trans);
1171 v9fs_unregister_trans(&p9_unix_trans);
1172 v9fs_unregister_trans(&p9_fd_trans);
1173}