0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012
0013 #include <linux/in.h>
0014 #include <linux/module.h>
0015 #include <linux/net.h>
0016 #include <linux/ipv6.h>
0017 #include <linux/kthread.h>
0018 #include <linux/errno.h>
0019 #include <linux/kernel.h>
0020 #include <linux/un.h>
0021 #include <linux/uaccess.h>
0022 #include <linux/inet.h>
0023 #include <linux/idr.h>
0024 #include <linux/file.h>
0025 #include <linux/parser.h>
0026 #include <linux/slab.h>
0027 #include <linux/seq_file.h>
0028 #include <net/9p/9p.h>
0029 #include <net/9p/client.h>
0030 #include <net/9p/transport.h>
0031
0032 #include <linux/syscalls.h> /* killme */
0033
0034 #define P9_PORT 564
0035 #define MAX_SOCK_BUF (1024*1024)
0036 #define MAXPOLLWADDR 2
0037
0038 static struct p9_trans_module p9_tcp_trans;
0039 static struct p9_trans_module p9_fd_trans;
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 struct p9_fd_opts {
0050 int rfd;
0051 int wfd;
0052 u16 port;
0053 bool privport;
0054 };
0055
0056
0057
0058
0059
0060
0061 enum {
0062
0063 Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
0064
0065 Opt_privport,
0066 };
0067
0068 static const match_table_t tokens = {
0069 {Opt_port, "port=%u"},
0070 {Opt_rfdno, "rfdno=%u"},
0071 {Opt_wfdno, "wfdno=%u"},
0072 {Opt_privport, "privport"},
0073 {Opt_err, NULL},
0074 };
0075
0076 enum {
0077 Rworksched = 1,
0078 Rpending = 2,
0079 Wworksched = 4,
0080 Wpending = 8,
0081 };
0082
0083 struct p9_poll_wait {
0084 struct p9_conn *conn;
0085 wait_queue_entry_t wait;
0086 wait_queue_head_t *wait_addr;
0087 };
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 struct p9_conn {
0114 struct list_head mux_list;
0115 struct p9_client *client;
0116 int err;
0117 struct list_head req_list;
0118 struct list_head unsent_req_list;
0119 struct p9_req_t *rreq;
0120 struct p9_req_t *wreq;
0121 char tmp_buf[7];
0122 struct p9_fcall rc;
0123 int wpos;
0124 int wsize;
0125 char *wbuf;
0126 struct list_head poll_pending_link;
0127 struct p9_poll_wait poll_wait[MAXPOLLWADDR];
0128 poll_table pt;
0129 struct work_struct rq;
0130 struct work_struct wq;
0131 unsigned long wsched;
0132 };
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 struct p9_trans_fd {
0143 struct file *rd;
0144 struct file *wr;
0145 struct p9_conn conn;
0146 };
0147
0148 static void p9_poll_workfn(struct work_struct *work);
0149
0150 static DEFINE_SPINLOCK(p9_poll_lock);
0151 static LIST_HEAD(p9_poll_pending_list);
0152 static DECLARE_WORK(p9_poll_work, p9_poll_workfn);
0153
0154 static unsigned int p9_ipport_resv_min = P9_DEF_MIN_RESVPORT;
0155 static unsigned int p9_ipport_resv_max = P9_DEF_MAX_RESVPORT;
0156
0157 static void p9_mux_poll_stop(struct p9_conn *m)
0158 {
0159 unsigned long flags;
0160 int i;
0161
0162 for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
0163 struct p9_poll_wait *pwait = &m->poll_wait[i];
0164
0165 if (pwait->wait_addr) {
0166 remove_wait_queue(pwait->wait_addr, &pwait->wait);
0167 pwait->wait_addr = NULL;
0168 }
0169 }
0170
0171 spin_lock_irqsave(&p9_poll_lock, flags);
0172 list_del_init(&m->poll_pending_link);
0173 spin_unlock_irqrestore(&p9_poll_lock, flags);
0174
0175 flush_work(&p9_poll_work);
0176 }
0177
0178
0179
0180
0181
0182
0183
0184
0185 static void p9_conn_cancel(struct p9_conn *m, int err)
0186 {
0187 struct p9_req_t *req, *rtmp;
0188 LIST_HEAD(cancel_list);
0189
0190 p9_debug(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
0191
0192 spin_lock(&m->client->lock);
0193
0194 if (m->err) {
0195 spin_unlock(&m->client->lock);
0196 return;
0197 }
0198
0199 m->err = err;
0200
0201 list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
0202 list_move(&req->req_list, &cancel_list);
0203 }
0204 list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
0205 list_move(&req->req_list, &cancel_list);
0206 }
0207
0208 list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
0209 p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req);
0210 list_del(&req->req_list);
0211 if (!req->t_err)
0212 req->t_err = err;
0213 p9_client_cb(m->client, req, REQ_STATUS_ERROR);
0214 }
0215 spin_unlock(&m->client->lock);
0216 }
0217
0218 static __poll_t
0219 p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)
0220 {
0221 __poll_t ret;
0222 struct p9_trans_fd *ts = NULL;
0223
0224 if (client && client->status == Connected)
0225 ts = client->trans;
0226
0227 if (!ts) {
0228 if (err)
0229 *err = -EREMOTEIO;
0230 return EPOLLERR;
0231 }
0232
0233 ret = vfs_poll(ts->rd, pt);
0234 if (ts->rd != ts->wr)
0235 ret = (ret & ~EPOLLOUT) | (vfs_poll(ts->wr, pt) & ~EPOLLIN);
0236 return ret;
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 static int p9_fd_read(struct p9_client *client, void *v, int len)
0248 {
0249 int ret;
0250 struct p9_trans_fd *ts = NULL;
0251 loff_t pos;
0252
0253 if (client && client->status != Disconnected)
0254 ts = client->trans;
0255
0256 if (!ts)
0257 return -EREMOTEIO;
0258
0259 if (!(ts->rd->f_flags & O_NONBLOCK))
0260 p9_debug(P9_DEBUG_ERROR, "blocking read ...\n");
0261
0262 pos = ts->rd->f_pos;
0263 ret = kernel_read(ts->rd, v, len, &pos);
0264 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
0265 client->status = Disconnected;
0266 return ret;
0267 }
0268
0269
0270
0271
0272
0273
0274
0275 static void p9_read_work(struct work_struct *work)
0276 {
0277 __poll_t n;
0278 int err;
0279 struct p9_conn *m;
0280
0281 m = container_of(work, struct p9_conn, rq);
0282
0283 if (m->err < 0)
0284 return;
0285
0286 p9_debug(P9_DEBUG_TRANS, "start mux %p pos %zd\n", m, m->rc.offset);
0287
0288 if (!m->rc.sdata) {
0289 m->rc.sdata = m->tmp_buf;
0290 m->rc.offset = 0;
0291 m->rc.capacity = 7;
0292 }
0293
0294 clear_bit(Rpending, &m->wsched);
0295 p9_debug(P9_DEBUG_TRANS, "read mux %p pos %zd size: %zd = %zd\n",
0296 m, m->rc.offset, m->rc.capacity,
0297 m->rc.capacity - m->rc.offset);
0298 err = p9_fd_read(m->client, m->rc.sdata + m->rc.offset,
0299 m->rc.capacity - m->rc.offset);
0300 p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
0301 if (err == -EAGAIN)
0302 goto end_clear;
0303
0304 if (err <= 0)
0305 goto error;
0306
0307 m->rc.offset += err;
0308
0309
0310 if ((!m->rreq) && (m->rc.offset == m->rc.capacity)) {
0311 p9_debug(P9_DEBUG_TRANS, "got new header\n");
0312
0313
0314 m->rc.size = 7;
0315 err = p9_parse_header(&m->rc, &m->rc.size, NULL, NULL, 0);
0316 if (err) {
0317 p9_debug(P9_DEBUG_ERROR,
0318 "error parsing header: %d\n", err);
0319 goto error;
0320 }
0321
0322 if (m->rc.size >= m->client->msize) {
0323 p9_debug(P9_DEBUG_ERROR,
0324 "requested packet size too big: %d\n",
0325 m->rc.size);
0326 err = -EIO;
0327 goto error;
0328 }
0329
0330 p9_debug(P9_DEBUG_TRANS,
0331 "mux %p pkt: size: %d bytes tag: %d\n",
0332 m, m->rc.size, m->rc.tag);
0333
0334 m->rreq = p9_tag_lookup(m->client, m->rc.tag);
0335 if (!m->rreq || (m->rreq->status != REQ_STATUS_SENT)) {
0336 p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
0337 m->rc.tag);
0338 err = -EIO;
0339 goto error;
0340 }
0341
0342 if (!m->rreq->rc.sdata) {
0343 p9_debug(P9_DEBUG_ERROR,
0344 "No recv fcall for tag %d (req %p), disconnecting!\n",
0345 m->rc.tag, m->rreq);
0346 p9_req_put(m->client, m->rreq);
0347 m->rreq = NULL;
0348 err = -EIO;
0349 goto error;
0350 }
0351 m->rc.sdata = m->rreq->rc.sdata;
0352 memcpy(m->rc.sdata, m->tmp_buf, m->rc.capacity);
0353 m->rc.capacity = m->rc.size;
0354 }
0355
0356
0357
0358
0359 if ((m->rreq) && (m->rc.offset == m->rc.capacity)) {
0360 p9_debug(P9_DEBUG_TRANS, "got new packet\n");
0361 m->rreq->rc.size = m->rc.offset;
0362 spin_lock(&m->client->lock);
0363 if (m->rreq->status == REQ_STATUS_SENT) {
0364 list_del(&m->rreq->req_list);
0365 p9_client_cb(m->client, m->rreq, REQ_STATUS_RCVD);
0366 } else if (m->rreq->status == REQ_STATUS_FLSHD) {
0367
0368 p9_debug(P9_DEBUG_TRANS,
0369 "Ignore replies associated with a cancelled request\n");
0370 } else {
0371 spin_unlock(&m->client->lock);
0372 p9_debug(P9_DEBUG_ERROR,
0373 "Request tag %d errored out while we were reading the reply\n",
0374 m->rc.tag);
0375 err = -EIO;
0376 goto error;
0377 }
0378 spin_unlock(&m->client->lock);
0379 m->rc.sdata = NULL;
0380 m->rc.offset = 0;
0381 m->rc.capacity = 0;
0382 p9_req_put(m->client, m->rreq);
0383 m->rreq = NULL;
0384 }
0385
0386 end_clear:
0387 clear_bit(Rworksched, &m->wsched);
0388
0389 if (!list_empty(&m->req_list)) {
0390 if (test_and_clear_bit(Rpending, &m->wsched))
0391 n = EPOLLIN;
0392 else
0393 n = p9_fd_poll(m->client, NULL, NULL);
0394
0395 if ((n & EPOLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
0396 p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
0397 schedule_work(&m->rq);
0398 }
0399 }
0400
0401 return;
0402 error:
0403 p9_conn_cancel(m, err);
0404 clear_bit(Rworksched, &m->wsched);
0405 }
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415 static int p9_fd_write(struct p9_client *client, void *v, int len)
0416 {
0417 ssize_t ret;
0418 struct p9_trans_fd *ts = NULL;
0419
0420 if (client && client->status != Disconnected)
0421 ts = client->trans;
0422
0423 if (!ts)
0424 return -EREMOTEIO;
0425
0426 if (!(ts->wr->f_flags & O_NONBLOCK))
0427 p9_debug(P9_DEBUG_ERROR, "blocking write ...\n");
0428
0429 ret = kernel_write(ts->wr, v, len, &ts->wr->f_pos);
0430 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
0431 client->status = Disconnected;
0432 return ret;
0433 }
0434
0435
0436
0437
0438
0439
0440
0441 static void p9_write_work(struct work_struct *work)
0442 {
0443 __poll_t n;
0444 int err;
0445 struct p9_conn *m;
0446 struct p9_req_t *req;
0447
0448 m = container_of(work, struct p9_conn, wq);
0449
0450 if (m->err < 0) {
0451 clear_bit(Wworksched, &m->wsched);
0452 return;
0453 }
0454
0455 if (!m->wsize) {
0456 spin_lock(&m->client->lock);
0457 if (list_empty(&m->unsent_req_list)) {
0458 clear_bit(Wworksched, &m->wsched);
0459 spin_unlock(&m->client->lock);
0460 return;
0461 }
0462
0463 req = list_entry(m->unsent_req_list.next, struct p9_req_t,
0464 req_list);
0465 req->status = REQ_STATUS_SENT;
0466 p9_debug(P9_DEBUG_TRANS, "move req %p\n", req);
0467 list_move_tail(&req->req_list, &m->req_list);
0468
0469 m->wbuf = req->tc.sdata;
0470 m->wsize = req->tc.size;
0471 m->wpos = 0;
0472 p9_req_get(req);
0473 m->wreq = req;
0474 spin_unlock(&m->client->lock);
0475 }
0476
0477 p9_debug(P9_DEBUG_TRANS, "mux %p pos %d size %d\n",
0478 m, m->wpos, m->wsize);
0479 clear_bit(Wpending, &m->wsched);
0480 err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
0481 p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
0482 if (err == -EAGAIN)
0483 goto end_clear;
0484
0485
0486 if (err < 0)
0487 goto error;
0488 else if (err == 0) {
0489 err = -EREMOTEIO;
0490 goto error;
0491 }
0492
0493 m->wpos += err;
0494 if (m->wpos == m->wsize) {
0495 m->wpos = m->wsize = 0;
0496 p9_req_put(m->client, m->wreq);
0497 m->wreq = NULL;
0498 }
0499
0500 end_clear:
0501 clear_bit(Wworksched, &m->wsched);
0502
0503 if (m->wsize || !list_empty(&m->unsent_req_list)) {
0504 if (test_and_clear_bit(Wpending, &m->wsched))
0505 n = EPOLLOUT;
0506 else
0507 n = p9_fd_poll(m->client, NULL, NULL);
0508
0509 if ((n & EPOLLOUT) &&
0510 !test_and_set_bit(Wworksched, &m->wsched)) {
0511 p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
0512 schedule_work(&m->wq);
0513 }
0514 }
0515
0516 return;
0517
0518 error:
0519 p9_conn_cancel(m, err);
0520 clear_bit(Wworksched, &m->wsched);
0521 }
0522
0523 static int p9_pollwake(wait_queue_entry_t *wait, unsigned int mode, int sync, void *key)
0524 {
0525 struct p9_poll_wait *pwait =
0526 container_of(wait, struct p9_poll_wait, wait);
0527 struct p9_conn *m = pwait->conn;
0528 unsigned long flags;
0529
0530 spin_lock_irqsave(&p9_poll_lock, flags);
0531 if (list_empty(&m->poll_pending_link))
0532 list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
0533 spin_unlock_irqrestore(&p9_poll_lock, flags);
0534
0535 schedule_work(&p9_poll_work);
0536 return 1;
0537 }
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548 static void
0549 p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
0550 {
0551 struct p9_conn *m = container_of(p, struct p9_conn, pt);
0552 struct p9_poll_wait *pwait = NULL;
0553 int i;
0554
0555 for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
0556 if (m->poll_wait[i].wait_addr == NULL) {
0557 pwait = &m->poll_wait[i];
0558 break;
0559 }
0560 }
0561
0562 if (!pwait) {
0563 p9_debug(P9_DEBUG_ERROR, "not enough wait_address slots\n");
0564 return;
0565 }
0566
0567 pwait->conn = m;
0568 pwait->wait_addr = wait_address;
0569 init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
0570 add_wait_queue(wait_address, &pwait->wait);
0571 }
0572
0573
0574
0575
0576
0577
0578
0579
0580 static void p9_conn_create(struct p9_client *client)
0581 {
0582 __poll_t n;
0583 struct p9_trans_fd *ts = client->trans;
0584 struct p9_conn *m = &ts->conn;
0585
0586 p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize);
0587
0588 INIT_LIST_HEAD(&m->mux_list);
0589 m->client = client;
0590
0591 INIT_LIST_HEAD(&m->req_list);
0592 INIT_LIST_HEAD(&m->unsent_req_list);
0593 INIT_WORK(&m->rq, p9_read_work);
0594 INIT_WORK(&m->wq, p9_write_work);
0595 INIT_LIST_HEAD(&m->poll_pending_link);
0596 init_poll_funcptr(&m->pt, p9_pollwait);
0597
0598 n = p9_fd_poll(client, &m->pt, NULL);
0599 if (n & EPOLLIN) {
0600 p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
0601 set_bit(Rpending, &m->wsched);
0602 }
0603
0604 if (n & EPOLLOUT) {
0605 p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
0606 set_bit(Wpending, &m->wsched);
0607 }
0608 }
0609
0610
0611
0612
0613
0614
0615
0616 static void p9_poll_mux(struct p9_conn *m)
0617 {
0618 __poll_t n;
0619 int err = -ECONNRESET;
0620
0621 if (m->err < 0)
0622 return;
0623
0624 n = p9_fd_poll(m->client, NULL, &err);
0625 if (n & (EPOLLERR | EPOLLHUP | EPOLLNVAL)) {
0626 p9_debug(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n);
0627 p9_conn_cancel(m, err);
0628 }
0629
0630 if (n & EPOLLIN) {
0631 set_bit(Rpending, &m->wsched);
0632 p9_debug(P9_DEBUG_TRANS, "mux %p can read\n", m);
0633 if (!test_and_set_bit(Rworksched, &m->wsched)) {
0634 p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
0635 schedule_work(&m->rq);
0636 }
0637 }
0638
0639 if (n & EPOLLOUT) {
0640 set_bit(Wpending, &m->wsched);
0641 p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m);
0642 if ((m->wsize || !list_empty(&m->unsent_req_list)) &&
0643 !test_and_set_bit(Wworksched, &m->wsched)) {
0644 p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
0645 schedule_work(&m->wq);
0646 }
0647 }
0648 }
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
0662 {
0663 __poll_t n;
0664 struct p9_trans_fd *ts = client->trans;
0665 struct p9_conn *m = &ts->conn;
0666
0667 p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n",
0668 m, current, &req->tc, req->tc.id);
0669 if (m->err < 0)
0670 return m->err;
0671
0672 spin_lock(&client->lock);
0673 req->status = REQ_STATUS_UNSENT;
0674 list_add_tail(&req->req_list, &m->unsent_req_list);
0675 spin_unlock(&client->lock);
0676
0677 if (test_and_clear_bit(Wpending, &m->wsched))
0678 n = EPOLLOUT;
0679 else
0680 n = p9_fd_poll(m->client, NULL, NULL);
0681
0682 if (n & EPOLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
0683 schedule_work(&m->wq);
0684
0685 return 0;
0686 }
0687
0688 static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
0689 {
0690 int ret = 1;
0691
0692 p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
0693
0694 spin_lock(&client->lock);
0695
0696 if (req->status == REQ_STATUS_UNSENT) {
0697 list_del(&req->req_list);
0698 req->status = REQ_STATUS_FLSHD;
0699 p9_req_put(client, req);
0700 ret = 0;
0701 }
0702 spin_unlock(&client->lock);
0703
0704 return ret;
0705 }
0706
0707 static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req)
0708 {
0709 p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req);
0710
0711 spin_lock(&client->lock);
0712
0713
0714
0715 if (req->status == REQ_STATUS_RCVD) {
0716 spin_unlock(&client->lock);
0717 return 0;
0718 }
0719
0720
0721
0722
0723 list_del(&req->req_list);
0724 req->status = REQ_STATUS_FLSHD;
0725 spin_unlock(&client->lock);
0726 p9_req_put(client, req);
0727
0728 return 0;
0729 }
0730
0731 static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt)
0732 {
0733 if (clnt->trans_mod == &p9_tcp_trans) {
0734 if (clnt->trans_opts.tcp.port != P9_PORT)
0735 seq_printf(m, ",port=%u", clnt->trans_opts.tcp.port);
0736 } else if (clnt->trans_mod == &p9_fd_trans) {
0737 if (clnt->trans_opts.fd.rfd != ~0)
0738 seq_printf(m, ",rfd=%u", clnt->trans_opts.fd.rfd);
0739 if (clnt->trans_opts.fd.wfd != ~0)
0740 seq_printf(m, ",wfd=%u", clnt->trans_opts.fd.wfd);
0741 }
0742 return 0;
0743 }
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753 static int parse_opts(char *params, struct p9_fd_opts *opts)
0754 {
0755 char *p;
0756 substring_t args[MAX_OPT_ARGS];
0757 int option;
0758 char *options, *tmp_options;
0759
0760 opts->port = P9_PORT;
0761 opts->rfd = ~0;
0762 opts->wfd = ~0;
0763 opts->privport = false;
0764
0765 if (!params)
0766 return 0;
0767
0768 tmp_options = kstrdup(params, GFP_KERNEL);
0769 if (!tmp_options) {
0770 p9_debug(P9_DEBUG_ERROR,
0771 "failed to allocate copy of option string\n");
0772 return -ENOMEM;
0773 }
0774 options = tmp_options;
0775
0776 while ((p = strsep(&options, ",")) != NULL) {
0777 int token;
0778 int r;
0779 if (!*p)
0780 continue;
0781 token = match_token(p, tokens, args);
0782 if ((token != Opt_err) && (token != Opt_privport)) {
0783 r = match_int(&args[0], &option);
0784 if (r < 0) {
0785 p9_debug(P9_DEBUG_ERROR,
0786 "integer field, but no integer?\n");
0787 continue;
0788 }
0789 }
0790 switch (token) {
0791 case Opt_port:
0792 opts->port = option;
0793 break;
0794 case Opt_rfdno:
0795 opts->rfd = option;
0796 break;
0797 case Opt_wfdno:
0798 opts->wfd = option;
0799 break;
0800 case Opt_privport:
0801 opts->privport = true;
0802 break;
0803 default:
0804 continue;
0805 }
0806 }
0807
0808 kfree(tmp_options);
0809 return 0;
0810 }
0811
0812 static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
0813 {
0814 struct p9_trans_fd *ts = kzalloc(sizeof(struct p9_trans_fd),
0815 GFP_KERNEL);
0816 if (!ts)
0817 return -ENOMEM;
0818
0819 ts->rd = fget(rfd);
0820 if (!ts->rd)
0821 goto out_free_ts;
0822 if (!(ts->rd->f_mode & FMODE_READ))
0823 goto out_put_rd;
0824 ts->wr = fget(wfd);
0825 if (!ts->wr)
0826 goto out_put_rd;
0827 if (!(ts->wr->f_mode & FMODE_WRITE))
0828 goto out_put_wr;
0829
0830 client->trans = ts;
0831 client->status = Connected;
0832
0833 return 0;
0834
0835 out_put_wr:
0836 fput(ts->wr);
0837 out_put_rd:
0838 fput(ts->rd);
0839 out_free_ts:
0840 kfree(ts);
0841 return -EIO;
0842 }
0843
0844 static int p9_socket_open(struct p9_client *client, struct socket *csocket)
0845 {
0846 struct p9_trans_fd *p;
0847 struct file *file;
0848
0849 p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL);
0850 if (!p)
0851 return -ENOMEM;
0852
0853 csocket->sk->sk_allocation = GFP_NOIO;
0854 file = sock_alloc_file(csocket, 0, NULL);
0855 if (IS_ERR(file)) {
0856 pr_err("%s (%d): failed to map fd\n",
0857 __func__, task_pid_nr(current));
0858 kfree(p);
0859 return PTR_ERR(file);
0860 }
0861
0862 get_file(file);
0863 p->wr = p->rd = file;
0864 client->trans = p;
0865 client->status = Connected;
0866
0867 p->rd->f_flags |= O_NONBLOCK;
0868
0869 p9_conn_create(client);
0870 return 0;
0871 }
0872
0873
0874
0875
0876
0877
0878
0879 static void p9_conn_destroy(struct p9_conn *m)
0880 {
0881 p9_debug(P9_DEBUG_TRANS, "mux %p prev %p next %p\n",
0882 m, m->mux_list.prev, m->mux_list.next);
0883
0884 p9_mux_poll_stop(m);
0885 cancel_work_sync(&m->rq);
0886 if (m->rreq) {
0887 p9_req_put(m->client, m->rreq);
0888 m->rreq = NULL;
0889 }
0890 cancel_work_sync(&m->wq);
0891 if (m->wreq) {
0892 p9_req_put(m->client, m->wreq);
0893 m->wreq = NULL;
0894 }
0895
0896 p9_conn_cancel(m, -ECONNRESET);
0897
0898 m->client = NULL;
0899 }
0900
0901
0902
0903
0904
0905
0906
0907 static void p9_fd_close(struct p9_client *client)
0908 {
0909 struct p9_trans_fd *ts;
0910
0911 if (!client)
0912 return;
0913
0914 ts = client->trans;
0915 if (!ts)
0916 return;
0917
0918 client->status = Disconnected;
0919
0920 p9_conn_destroy(&ts->conn);
0921
0922 if (ts->rd)
0923 fput(ts->rd);
0924 if (ts->wr)
0925 fput(ts->wr);
0926
0927 kfree(ts);
0928 }
0929
0930
0931
0932
0933 static inline int valid_ipaddr4(const char *buf)
0934 {
0935 int rc, count, in[4];
0936
0937 rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
0938 if (rc != 4)
0939 return -EINVAL;
0940 for (count = 0; count < 4; count++) {
0941 if (in[count] > 255)
0942 return -EINVAL;
0943 }
0944 return 0;
0945 }
0946
0947 static int p9_bind_privport(struct socket *sock)
0948 {
0949 struct sockaddr_in cl;
0950 int port, err = -EINVAL;
0951
0952 memset(&cl, 0, sizeof(cl));
0953 cl.sin_family = AF_INET;
0954 cl.sin_addr.s_addr = htonl(INADDR_ANY);
0955 for (port = p9_ipport_resv_max; port >= p9_ipport_resv_min; port--) {
0956 cl.sin_port = htons((ushort)port);
0957 err = kernel_bind(sock, (struct sockaddr *)&cl, sizeof(cl));
0958 if (err != -EADDRINUSE)
0959 break;
0960 }
0961 return err;
0962 }
0963
0964
0965 static int
0966 p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
0967 {
0968 int err;
0969 struct socket *csocket;
0970 struct sockaddr_in sin_server;
0971 struct p9_fd_opts opts;
0972
0973 err = parse_opts(args, &opts);
0974 if (err < 0)
0975 return err;
0976
0977 if (addr == NULL || valid_ipaddr4(addr) < 0)
0978 return -EINVAL;
0979
0980 csocket = NULL;
0981
0982 client->trans_opts.tcp.port = opts.port;
0983 client->trans_opts.tcp.privport = opts.privport;
0984 sin_server.sin_family = AF_INET;
0985 sin_server.sin_addr.s_addr = in_aton(addr);
0986 sin_server.sin_port = htons(opts.port);
0987 err = __sock_create(current->nsproxy->net_ns, PF_INET,
0988 SOCK_STREAM, IPPROTO_TCP, &csocket, 1);
0989 if (err) {
0990 pr_err("%s (%d): problem creating socket\n",
0991 __func__, task_pid_nr(current));
0992 return err;
0993 }
0994
0995 if (opts.privport) {
0996 err = p9_bind_privport(csocket);
0997 if (err < 0) {
0998 pr_err("%s (%d): problem binding to privport\n",
0999 __func__, task_pid_nr(current));
1000 sock_release(csocket);
1001 return err;
1002 }
1003 }
1004
1005 err = csocket->ops->connect(csocket,
1006 (struct sockaddr *)&sin_server,
1007 sizeof(struct sockaddr_in), 0);
1008 if (err < 0) {
1009 pr_err("%s (%d): problem connecting socket to %s\n",
1010 __func__, task_pid_nr(current), addr);
1011 sock_release(csocket);
1012 return err;
1013 }
1014
1015 return p9_socket_open(client, csocket);
1016 }
1017
1018 static int
1019 p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
1020 {
1021 int err;
1022 struct socket *csocket;
1023 struct sockaddr_un sun_server;
1024
1025 csocket = NULL;
1026
1027 if (!addr || !strlen(addr))
1028 return -EINVAL;
1029
1030 if (strlen(addr) >= UNIX_PATH_MAX) {
1031 pr_err("%s (%d): address too long: %s\n",
1032 __func__, task_pid_nr(current), addr);
1033 return -ENAMETOOLONG;
1034 }
1035
1036 sun_server.sun_family = PF_UNIX;
1037 strcpy(sun_server.sun_path, addr);
1038 err = __sock_create(current->nsproxy->net_ns, PF_UNIX,
1039 SOCK_STREAM, 0, &csocket, 1);
1040 if (err < 0) {
1041 pr_err("%s (%d): problem creating socket\n",
1042 __func__, task_pid_nr(current));
1043
1044 return err;
1045 }
1046 err = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
1047 sizeof(struct sockaddr_un) - 1, 0);
1048 if (err < 0) {
1049 pr_err("%s (%d): problem connecting socket: %s: %d\n",
1050 __func__, task_pid_nr(current), addr, err);
1051 sock_release(csocket);
1052 return err;
1053 }
1054
1055 return p9_socket_open(client, csocket);
1056 }
1057
1058 static int
1059 p9_fd_create(struct p9_client *client, const char *addr, char *args)
1060 {
1061 int err;
1062 struct p9_fd_opts opts;
1063
1064 parse_opts(args, &opts);
1065 client->trans_opts.fd.rfd = opts.rfd;
1066 client->trans_opts.fd.wfd = opts.wfd;
1067
1068 if (opts.rfd == ~0 || opts.wfd == ~0) {
1069 pr_err("Insufficient options for proto=fd\n");
1070 return -ENOPROTOOPT;
1071 }
1072
1073 err = p9_fd_open(client, opts.rfd, opts.wfd);
1074 if (err < 0)
1075 return err;
1076
1077 p9_conn_create(client);
1078
1079 return 0;
1080 }
1081
1082 static struct p9_trans_module p9_tcp_trans = {
1083 .name = "tcp",
1084 .maxsize = MAX_SOCK_BUF,
1085 .def = 0,
1086 .create = p9_fd_create_tcp,
1087 .close = p9_fd_close,
1088 .request = p9_fd_request,
1089 .cancel = p9_fd_cancel,
1090 .cancelled = p9_fd_cancelled,
1091 .show_options = p9_fd_show_options,
1092 .owner = THIS_MODULE,
1093 };
1094 MODULE_ALIAS_9P("tcp");
1095
1096 static struct p9_trans_module p9_unix_trans = {
1097 .name = "unix",
1098 .maxsize = MAX_SOCK_BUF,
1099 .def = 0,
1100 .create = p9_fd_create_unix,
1101 .close = p9_fd_close,
1102 .request = p9_fd_request,
1103 .cancel = p9_fd_cancel,
1104 .cancelled = p9_fd_cancelled,
1105 .show_options = p9_fd_show_options,
1106 .owner = THIS_MODULE,
1107 };
1108 MODULE_ALIAS_9P("unix");
1109
1110 static struct p9_trans_module p9_fd_trans = {
1111 .name = "fd",
1112 .maxsize = MAX_SOCK_BUF,
1113 .def = 0,
1114 .create = p9_fd_create,
1115 .close = p9_fd_close,
1116 .request = p9_fd_request,
1117 .cancel = p9_fd_cancel,
1118 .cancelled = p9_fd_cancelled,
1119 .show_options = p9_fd_show_options,
1120 .owner = THIS_MODULE,
1121 };
1122 MODULE_ALIAS_9P("fd");
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133 static void p9_poll_workfn(struct work_struct *work)
1134 {
1135 unsigned long flags;
1136
1137 p9_debug(P9_DEBUG_TRANS, "start %p\n", current);
1138
1139 spin_lock_irqsave(&p9_poll_lock, flags);
1140 while (!list_empty(&p9_poll_pending_list)) {
1141 struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
1142 struct p9_conn,
1143 poll_pending_link);
1144 list_del_init(&conn->poll_pending_link);
1145 spin_unlock_irqrestore(&p9_poll_lock, flags);
1146
1147 p9_poll_mux(conn);
1148
1149 spin_lock_irqsave(&p9_poll_lock, flags);
1150 }
1151 spin_unlock_irqrestore(&p9_poll_lock, flags);
1152
1153 p9_debug(P9_DEBUG_TRANS, "finish\n");
1154 }
1155
1156 static int __init p9_trans_fd_init(void)
1157 {
1158 v9fs_register_trans(&p9_tcp_trans);
1159 v9fs_register_trans(&p9_unix_trans);
1160 v9fs_register_trans(&p9_fd_trans);
1161
1162 return 0;
1163 }
1164
1165 static void __exit p9_trans_fd_exit(void)
1166 {
1167 flush_work(&p9_poll_work);
1168 v9fs_unregister_trans(&p9_tcp_trans);
1169 v9fs_unregister_trans(&p9_unix_trans);
1170 v9fs_unregister_trans(&p9_fd_trans);
1171 }
1172
1173 module_init(p9_trans_fd_init);
1174 module_exit(p9_trans_fd_exit);
1175
1176 MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
1177 MODULE_DESCRIPTION("Filedescriptor Transport for 9P");
1178 MODULE_LICENSE("GPL");