trans_fd.c 30.3 KB
Newer Older
1 2 3 4 5 6 7
/*
 * linux/fs/9p/trans_fd.c
 *
 * Fd transport layer.  Includes deprecated socket layer.
 *
 *  Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
 *  Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
8
 *  Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 *  Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to:
 *  Free Software Foundation
 *  51 Franklin Street, Fifth Floor
 *  Boston, MA  02111-1301  USA
 *
 */

#include <linux/in.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/ipv6.h>
32
#include <linux/kthread.h>
33 34 35 36 37 38 39
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/un.h>
#include <linux/uaccess.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>
40
#include <linux/parser.h>
41
#include <net/9p/9p.h>
42
#include <net/9p/client.h>
43 44 45
#include <net/9p/transport.h>

#define P9_PORT 564
46
#define MAX_SOCK_BUF (64*1024)
47 48
#define ERREQFLUSH	1
#define MAXPOLLWADDR	2
49

50 51 52 53 54 55 56 57
/**
 * struct p9_fd_opts - per-transport options
 * @rfd: file descriptor for reading (trans=fd)
 * @wfd: file descriptor for writing (trans=fd)
 * @port: port to connect to (trans=tcp)
 *
 */

58 59 60 61 62
struct p9_fd_opts {
	int rfd;
	int wfd;
	u16 port;
};
63

64 65 66 67 68 69 70 71
/**
 * struct p9_trans_fd - transport state
 * @rd: reference to file to read from
 * @wr: reference of file to write to
 * @conn: connection state reference
 *
 */

72 73 74
struct p9_trans_fd {
	struct file *rd;
	struct file *wr;
75
	struct p9_conn *conn;
76 77
};

78 79 80 81
/*
  * Option Parsing (code inspired by NFS code)
  *  - a little lazy - parse all fd-transport options
  */
82

83 84
enum {
	/* Options that take integer arguments */
85
	Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
86
};
87

88
static const match_table_t tokens = {
89 90 91
	{Opt_port, "port=%u"},
	{Opt_rfdno, "rfdno=%u"},
	{Opt_wfdno, "wfdno=%u"},
92
	{Opt_err, NULL},
93
};
94

95 96 97 98 99 100 101 102 103 104 105 106 107
enum {
	Rworksched = 1,		/* read work scheduled or running */
	Rpending = 2,		/* can read */
	Wworksched = 4,		/* write work scheduled or running */
	Wpending = 8,		/* can write */
};

enum {
	None,
	Flushing,
	Flushed,
};

108 109 110 111 112 113 114 115 116
/**
 * struct p9_req - fd mux encoding of an rpc transaction
 * @lock: protects req_list
 * @tag: numeric tag for rpc transaction
 * @tcall: request &p9_fcall structure
 * @rcall: response &p9_fcall structure
 * @err: error state
 * @flush: flag to indicate RPC has been flushed
 * @req_list: list link for higher level objects to chain requests
117 118
 * @m: connection this request was issued on
 * @wqueue: wait queue that client is blocked on for this rpc
119 120 121
 *
 */

122
struct p9_req {
123
	spinlock_t lock;
124 125 126 127 128 129
	int tag;
	struct p9_fcall *tcall;
	struct p9_fcall *rcall;
	int err;
	int flush;
	struct list_head req_list;
130 131
	struct p9_conn *m;
	wait_queue_head_t wqueue;
132 133
};

Tejun Heo's avatar
Tejun Heo committed
134 135 136 137
struct p9_poll_wait {
	struct p9_conn *conn;
	wait_queue_t wait;
	wait_queue_head_t *wait_addr;
138 139 140 141 142 143
};

/**
 * struct p9_conn - fd mux connection state information
 * @lock: protects mux_list (?)
 * @mux_list: list link for mux to manage multiple connections (?)
144
 * @client: reference to client instance for this connection
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
 * @err: error state
 * @req_list: accounting for requests which have been sent
 * @unsent_req_list: accounting for requests that haven't been sent
 * @rcall: current response &p9_fcall structure
 * @rpos: read position in current frame
 * @rbuf: current read buffer
 * @wpos: write position for current frame
 * @wsize: amount of data to write for current frame
 * @wbuf: current write buffer
 * @poll_wait: array of wait_q's for various worker threads
 * @poll_waddr: ????
 * @pt: poll state
 * @rq: current read work
 * @wq: current write work
 * @wsched: ????
 *
 */
162 163 164 165

struct p9_conn {
	spinlock_t lock; /* protect lock structure */
	struct list_head mux_list;
166
	struct p9_client *client;
167 168 169 170 171 172 173 174 175
	int err;
	struct list_head req_list;
	struct list_head unsent_req_list;
	struct p9_fcall *rcall;
	int rpos;
	char *rbuf;
	int wpos;
	int wsize;
	char *wbuf;
Tejun Heo's avatar
Tejun Heo committed
176 177
	struct list_head poll_pending_link;
	struct p9_poll_wait poll_wait[MAXPOLLWADDR];
178 179 180 181 182 183
	poll_table pt;
	struct work_struct rq;
	struct work_struct wq;
	unsigned long wsched;
};

Tejun Heo's avatar
Tejun Heo committed
184 185
static DEFINE_SPINLOCK(p9_poll_lock);
static LIST_HEAD(p9_poll_pending_list);
186
static struct workqueue_struct *p9_mux_wq;
Tejun Heo's avatar
Tejun Heo committed
187
static struct task_struct *p9_poll_task;
188

Tejun Heo's avatar
Tejun Heo committed
189
static void p9_mux_poll_stop(struct p9_conn *m)
190
{
Tejun Heo's avatar
Tejun Heo committed
191 192
	unsigned long flags;
	int i;
193

Tejun Heo's avatar
Tejun Heo committed
194 195
	for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
		struct p9_poll_wait *pwait = &m->poll_wait[i];
196

Tejun Heo's avatar
Tejun Heo committed
197 198 199
		if (pwait->wait_addr) {
			remove_wait_queue(pwait->wait_addr, &pwait->wait);
			pwait->wait_addr = NULL;
200 201 202
		}
	}

Tejun Heo's avatar
Tejun Heo committed
203 204 205
	spin_lock_irqsave(&p9_poll_lock, flags);
	list_del_init(&m->poll_pending_link);
	spin_unlock_irqrestore(&p9_poll_lock, flags);
206 207
}

208 209
static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req)
{
210 211 212
	if (req->tag != P9_NOTAG &&
	    p9_idpool_check(req->tag, m->client->tagpool))
		p9_idpool_put(req->tag, m->client->tagpool);
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
	kfree(req);
}

static void p9_conn_rpc_cb(struct p9_req *req);

static void p9_mux_flush_cb(struct p9_req *freq)
{
	int tag;
	struct p9_conn *m = freq->m;
	struct p9_req *req, *rreq, *rptr;

	P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m,
		freq->tcall, freq->rcall, freq->err,
		freq->tcall->params.tflush.oldtag);

	spin_lock(&m->lock);
	tag = freq->tcall->params.tflush.oldtag;
	req = NULL;
	list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
		if (rreq->tag == tag) {
			req = rreq;
			list_del(&req->req_list);
			break;
		}
	}
	spin_unlock(&m->lock);

	if (req) {
		spin_lock(&req->lock);
		req->flush = Flushed;
		spin_unlock(&req->lock);

		p9_conn_rpc_cb(req);
	}

	kfree(freq->tcall);
	kfree(freq->rcall);
	p9_mux_free_request(m, freq);
}

static void p9_conn_rpc_cb(struct p9_req *req)
{
	P9_DPRINTK(P9_DEBUG_MUX, "req %p\n", req);

	if (req->tcall->id == P9_TFLUSH) { /* flush callback */
		P9_DPRINTK(P9_DEBUG_MUX, "flush req %p\n", req);
		p9_mux_flush_cb(req);
	} else {			/* normal wakeup path */
		P9_DPRINTK(P9_DEBUG_MUX, "normal req %p\n", req);
		if (req->flush != None && !req->err)
			req->err = -ERESTARTSYS;

		wake_up(&req->wqueue);
	}
}

269
/**
270 271 272
 * p9_conn_cancel - cancel all pending requests with error
 * @m: mux data
 * @err: error code
273 274
 *
 */
275

276
void p9_conn_cancel(struct p9_conn *m, int err)
277
{
278 279
	struct p9_req *req, *rtmp;
	LIST_HEAD(cancel_list);
280

281 282 283 284 285 286 287 288
	P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
	m->err = err;
	spin_lock(&m->lock);
	list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
		list_move(&req->req_list, &cancel_list);
	}
	list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
		list_move(&req->req_list, &cancel_list);
289
	}
290
	spin_unlock(&m->lock);
291

292 293 294 295
	list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
		list_del(&req->req_list);
		if (!req->err)
			req->err = err;
296

297
		p9_conn_rpc_cb(req);
298
	}
299
}
300

301 302 303 304
static void process_request(struct p9_conn *m, struct p9_req *req)
{
	int ecode;
	struct p9_str *ename;
305

306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
	if (!req->err && req->rcall->id == P9_RERROR) {
		ecode = req->rcall->params.rerror.errno;
		ename = &req->rcall->params.rerror.error;

		P9_DPRINTK(P9_DEBUG_MUX, "Rerror %.*s\n", ename->len,
								ename->str);

		if (m->client->dotu)
			req->err = -ecode;

		if (!req->err) {
			req->err = p9_errstr2errno(ename->str, ename->len);

			/* string match failed */
			if (!req->err) {
				PRINT_FCALL_ERROR("unknown error", req->rcall);
				req->err = -ESERVERFAULT;
			}
324
		}
325 326 327 328 329 330
	} else if (req->tcall && req->rcall->id != req->tcall->id + 1) {
		P9_DPRINTK(P9_DEBUG_ERROR,
				"fcall mismatch: expected %d, got %d\n",
				req->tcall->id + 1, req->rcall->id);
		if (!req->err)
			req->err = -EIO;
331 332 333
	}
}

334 335
static unsigned int
p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
336
{
337 338
	int ret, n;
	struct p9_trans_fd *ts = NULL;
339

340 341
	if (client && client->status == Connected)
		ts = client->trans;
342

343 344
	if (!ts)
		return -EREMOTEIO;
345

346 347
	if (!ts->rd->f_op || !ts->rd->f_op->poll)
		return -EIO;
348

349 350
	if (!ts->wr->f_op || !ts->wr->f_op->poll)
		return -EIO;
Tejun Heo's avatar
Tejun Heo committed
351

352 353 354
	ret = ts->rd->f_op->poll(ts->rd, pt);
	if (ret < 0)
		return ret;
Tejun Heo's avatar
Tejun Heo committed
355

356 357 358 359 360 361 362 363
	if (ts->rd != ts->wr) {
		n = ts->wr->f_op->poll(ts->wr, pt);
		if (n < 0)
			return n;
		ret = (ret & ~POLLOUT) | (n & ~POLLIN);
	}

	return ret;
Tejun Heo's avatar
Tejun Heo committed
364 365
}

366
/**
367 368 369 370
 * p9_fd_read- read from a fd
 * @client: client instance
 * @v: buffer to receive data into
 * @len: size of receive buffer
371
 *
372
 */
373

374
static int p9_fd_read(struct p9_client *client, void *v, int len)
375
{
376 377
	int ret;
	struct p9_trans_fd *ts = NULL;
378

379 380
	if (client && client->status != Disconnected)
		ts = client->trans;
381

382 383
	if (!ts)
		return -EREMOTEIO;
384

385 386
	if (!(ts->rd->f_flags & O_NONBLOCK))
		P9_DPRINTK(P9_DEBUG_ERROR, "blocking read ...\n");
387

388 389 390 391
	ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
	if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
		client->status = Disconnected;
	return ret;
392 393 394
}

/**
395 396
 * p9_read_work - called when there is some data to be read from a transport
 * @work: container of work to be done
397
 *
398
 */
399

400
static void p9_read_work(struct work_struct *work)
401
{
402 403 404 405 406 407 408
	int n, err;
	struct p9_conn *m;
	struct p9_req *req, *rptr, *rreq;
	struct p9_fcall *rcall;
	char *rbuf;

	m = container_of(work, struct p9_conn, rq);
409 410 411 412

	if (m->err < 0)
		return;

413 414
	rcall = NULL;
	P9_DPRINTK(P9_DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos);
415

416 417 418 419 420 421 422
	if (!m->rcall) {
		m->rcall =
		    kmalloc(sizeof(struct p9_fcall) + m->client->msize,
								GFP_KERNEL);
		if (!m->rcall) {
			err = -ENOMEM;
			goto error;
423
		}
424 425 426

		m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall);
		m->rpos = 0;
427 428
	}

429 430 431 432 433 434 435
	clear_bit(Rpending, &m->wsched);
	err = p9_fd_read(m->client, m->rbuf + m->rpos,
						m->client->msize - m->rpos);
	P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err);
	if (err == -EAGAIN) {
		clear_bit(Rworksched, &m->wsched);
		return;
436 437
	}

438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
	if (err <= 0)
		goto error;

	m->rpos += err;
	while (m->rpos > 4) {
		n = le32_to_cpu(*(__le32 *) m->rbuf);
		if (n >= m->client->msize) {
			P9_DPRINTK(P9_DEBUG_ERROR,
				"requested packet size too big: %d\n", n);
			err = -EIO;
			goto error;
		}

		if (m->rpos < n)
			break;

		err =
		    p9_deserialize_fcall(m->rbuf, n, m->rcall, m->client->dotu);
		if (err < 0)
			goto error;

#ifdef CONFIG_NET_9P_DEBUG
		if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
			char buf[150];

			p9_printfcall(buf, sizeof(buf), m->rcall,
				m->client->dotu);
			printk(KERN_NOTICE ">>> %p %s\n", m, buf);
		}
#endif

		rcall = m->rcall;
		rbuf = m->rbuf;
		if (m->rpos > n) {
			m->rcall = kmalloc(sizeof(struct p9_fcall) +
						m->client->msize, GFP_KERNEL);
			if (!m->rcall) {
				err = -ENOMEM;
				goto error;
			}

			m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall);
			memmove(m->rbuf, rbuf + n, m->rpos - n);
			m->rpos -= n;
		} else {
			m->rcall = NULL;
			m->rbuf = NULL;
			m->rpos = 0;
		}

		P9_DPRINTK(P9_DEBUG_MUX, "mux %p fcall id %d tag %d\n", m,
							rcall->id, rcall->tag);

		req = NULL;
		spin_lock(&m->lock);
		list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
			if (rreq->tag == rcall->tag) {
				req = rreq;
				if (req->flush != Flushing)
					list_del(&req->req_list);
				break;
			}
		}
		spin_unlock(&m->lock);

		if (req) {
			req->rcall = rcall;
			process_request(m, req);

507 508
			if (req->flush != Flushing)
				p9_conn_rpc_cb(req);
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
		} else {
			if (err >= 0 && rcall->id != P9_RFLUSH)
				P9_DPRINTK(P9_DEBUG_ERROR,
				  "unexpected response mux %p id %d tag %d\n",
				  m, rcall->id, rcall->tag);
			kfree(rcall);
		}
	}

	if (!list_empty(&m->req_list)) {
		if (test_and_clear_bit(Rpending, &m->wsched))
			n = POLLIN;
		else
			n = p9_fd_poll(m->client, NULL);

		if (n & POLLIN) {
			P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m);
			queue_work(p9_mux_wq, &m->rq);
		} else
			clear_bit(Rworksched, &m->wsched);
	} else
		clear_bit(Rworksched, &m->wsched);

	return;

error:
	p9_conn_cancel(m, err);
	clear_bit(Rworksched, &m->wsched);
}

/**
 * p9_fd_write - write to a socket
 * @client: client instance
 * @v: buffer to send data from
 * @len: size of send buffer
544
 *
545
 */
546

547
static int p9_fd_write(struct p9_client *client, void *v, int len)
548
{
549 550 551
	int ret;
	mm_segment_t oldfs;
	struct p9_trans_fd *ts = NULL;
552

553 554
	if (client && client->status != Disconnected)
		ts = client->trans;
555

556 557
	if (!ts)
		return -EREMOTEIO;
558

559 560
	if (!(ts->wr->f_flags & O_NONBLOCK))
		P9_DPRINTK(P9_DEBUG_ERROR, "blocking write ...\n");
Tejun Heo's avatar
Tejun Heo committed
561

562 563 564 565 566
	oldfs = get_fs();
	set_fs(get_ds());
	/* The cast to a user pointer is valid due to the set_fs() */
	ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos);
	set_fs(oldfs);
Tejun Heo's avatar
Tejun Heo committed
567

568 569 570
	if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
		client->status = Disconnected;
	return ret;
571 572 573 574
}

/**
 * p9_write_work - called when a transport can send some data
575 576
 * @work: container for work to be done
 *
577
 */
578

579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
static void p9_write_work(struct work_struct *work)
{
	int n, err;
	struct p9_conn *m;
	struct p9_req *req;

	m = container_of(work, struct p9_conn, wq);

	if (m->err < 0) {
		clear_bit(Wworksched, &m->wsched);
		return;
	}

	if (!m->wsize) {
		if (list_empty(&m->unsent_req_list)) {
			clear_bit(Wworksched, &m->wsched);
			return;
		}

		spin_lock(&m->lock);
again:
		req = list_entry(m->unsent_req_list.next, struct p9_req,
			       req_list);
		list_move_tail(&req->req_list, &m->req_list);
		if (req->err == ERREQFLUSH)
			goto again;

		m->wbuf = req->tcall->sdata;
		m->wsize = req->tcall->size;
		m->wpos = 0;
		spin_unlock(&m->lock);
	}

	P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos,
								m->wsize);
	clear_bit(Wpending, &m->wsched);
615
	err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
	P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err);
	if (err == -EAGAIN) {
		clear_bit(Wworksched, &m->wsched);
		return;
	}

	if (err < 0)
		goto error;
	else if (err == 0) {
		err = -EREMOTEIO;
		goto error;
	}

	m->wpos += err;
	if (m->wpos == m->wsize)
		m->wpos = m->wsize = 0;

	if (m->wsize == 0 && !list_empty(&m->unsent_req_list)) {
		if (test_and_clear_bit(Wpending, &m->wsched))
			n = POLLOUT;
		else
637
			n = p9_fd_poll(m->client, NULL);
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653

		if (n & POLLOUT) {
			P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m);
			queue_work(p9_mux_wq, &m->wq);
		} else
			clear_bit(Wworksched, &m->wsched);
	} else
		clear_bit(Wworksched, &m->wsched);

	return;

error:
	p9_conn_cancel(m, err);
	clear_bit(Wworksched, &m->wsched);
}

654
static int p9_pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
655
{
656 657 658 659 660
	struct p9_poll_wait *pwait =
		container_of(wait, struct p9_poll_wait, wait);
	struct p9_conn *m = pwait->conn;
	unsigned long flags;
	DECLARE_WAITQUEUE(dummy_wait, p9_poll_task);
661

662 663 664 665
	spin_lock_irqsave(&p9_poll_lock, flags);
	if (list_empty(&m->poll_pending_link))
		list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
	spin_unlock_irqrestore(&p9_poll_lock, flags);
666

667 668
	/* perform the default wake up operation */
	return default_wake_function(&dummy_wait, mode, sync, key);
669 670 671
}

/**
672 673 674 675
 * p9_pollwait - add poll task to the wait queue
 * @filp: file pointer being polled
 * @wait_address: wait_q to block on
 * @p: poll state
676
 *
677
 * called by files poll operation to add v9fs-poll task to files wait queue
678
 */
679

680 681
static void
p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
682
{
683 684 685
	struct p9_conn *m = container_of(p, struct p9_conn, pt);
	struct p9_poll_wait *pwait = NULL;
	int i;
686

687 688 689 690
	for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
		if (m->poll_wait[i].wait_addr == NULL) {
			pwait = &m->poll_wait[i];
			break;
691 692 693
		}
	}

694 695
	if (!pwait) {
		P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n");
696 697 698
		return;
	}

699 700 701 702 703
	if (!wait_address) {
		P9_DPRINTK(P9_DEBUG_ERROR, "no wait_address\n");
		pwait->wait_addr = ERR_PTR(-EIO);
		return;
	}
704

705 706 707 708 709
	pwait->conn = m;
	pwait->wait_addr = wait_address;
	init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
	add_wait_queue(wait_address, &pwait->wait);
}
710

711 712 713 714 715 716
/**
 * p9_conn_create - allocate and initialize the per-session mux data
 * @client: client instance
 *
 * Note: Creates the polling task if this is the first session.
 */
717

718 719 720 721
static struct p9_conn *p9_conn_create(struct p9_client *client)
{
	int i, n;
	struct p9_conn *m;
722

723 724 725 726
	P9_DPRINTK(P9_DEBUG_MUX, "client %p msize %d\n", client, client->msize);
	m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
	if (!m)
		return ERR_PTR(-ENOMEM);
727

728 729 730
	spin_lock_init(&m->lock);
	INIT_LIST_HEAD(&m->mux_list);
	m->client = client;
731

732 733 734 735 736 737
	INIT_LIST_HEAD(&m->req_list);
	INIT_LIST_HEAD(&m->unsent_req_list);
	INIT_WORK(&m->rq, p9_read_work);
	INIT_WORK(&m->wq, p9_write_work);
	INIT_LIST_HEAD(&m->poll_pending_link);
	init_poll_funcptr(&m->pt, p9_pollwait);
738

739 740 741 742 743
	n = p9_fd_poll(client, &m->pt);
	if (n & POLLIN) {
		P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m);
		set_bit(Rpending, &m->wsched);
	}
744

745 746 747 748 749 750 751 752 753 754 755
	if (n & POLLOUT) {
		P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m);
		set_bit(Wpending, &m->wsched);
	}

	for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
		if (IS_ERR(m->poll_wait[i].wait_addr)) {
			p9_mux_poll_stop(m);
			kfree(m);
			/* return the error code */
			return (void *)m->poll_wait[i].wait_addr;
756 757 758
		}
	}

759 760
	return m;
}
761

762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786
/**
 * p9_poll_mux - polls a mux and schedules read or write works if necessary
 * @m: connection to poll
 *
 */

static void p9_poll_mux(struct p9_conn *m)
{
	int n;

	if (m->err < 0)
		return;

	n = p9_fd_poll(m->client, NULL);
	if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
		P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n);
		if (n >= 0)
			n = -ECONNRESET;
		p9_conn_cancel(m, n);
	}

	if (n & POLLIN) {
		set_bit(Rpending, &m->wsched);
		P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m);
		if (!test_and_set_bit(Rworksched, &m->wsched)) {
787 788
			P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m);
			queue_work(p9_mux_wq, &m->rq);
789 790
		}
	}
791

792 793 794 795 796 797 798 799 800
	if (n & POLLOUT) {
		set_bit(Wpending, &m->wsched);
		P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m);
		if ((m->wsize || !list_empty(&m->unsent_req_list))
		    && !test_and_set_bit(Wworksched, &m->wsched)) {
			P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m);
			queue_work(p9_mux_wq, &m->wq);
		}
	}
801 802 803 804 805 806 807 808 809 810 811
}

/**
 * p9_send_request - send 9P request
 * The function can sleep until the request is scheduled for sending.
 * The function can be interrupted. Return from the function is not
 * a guarantee that the request is sent successfully. Can return errors
 * that can be retrieved by PTR_ERR macros.
 *
 * @m: mux data
 * @tc: request to be sent
812
 *
813
 */
814

815
static struct p9_req *p9_send_request(struct p9_conn *m, struct p9_fcall *tc)
816 817 818 819 820 821 822 823 824 825 826 827 828
{
	int n;
	struct p9_req *req;

	P9_DPRINTK(P9_DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current,
		tc, tc->id);
	if (m->err < 0)
		return ERR_PTR(m->err);

	req = kmalloc(sizeof(struct p9_req), GFP_KERNEL);
	if (!req)
		return ERR_PTR(-ENOMEM);

829 830 831 832 833 834 835
	n = P9_NOTAG;
	if (tc->id != P9_TVERSION) {
		n = p9_idpool_get(m->client->tagpool);
		if (n < 0) {
			kfree(req);
			return ERR_PTR(-ENOMEM);
		}
Julia Lawall's avatar
Julia Lawall committed
836
	}
837 838 839 840 841 842 843

	p9_set_tag(tc, n);

#ifdef CONFIG_NET_9P_DEBUG
	if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
		char buf[150];

844
		p9_printfcall(buf, sizeof(buf), tc, m->client->dotu);
845 846 847 848 849
		printk(KERN_NOTICE "<<< %p %s\n", m, buf);
	}
#endif

	spin_lock_init(&req->lock);
850 851
	req->m = m;
	init_waitqueue_head(&req->wqueue);
852 853 854 855 856 857 858 859 860 861 862 863 864
	req->tag = n;
	req->tcall = tc;
	req->rcall = NULL;
	req->err = 0;
	req->flush = None;

	spin_lock(&m->lock);
	list_add_tail(&req->req_list, &m->unsent_req_list);
	spin_unlock(&m->lock);

	if (test_and_clear_bit(Wpending, &m->wsched))
		n = POLLOUT;
	else
865
		n = p9_fd_poll(m->client, NULL);
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901

	if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
		queue_work(p9_mux_wq, &m->wq);

	return req;
}

static int
p9_mux_flush_request(struct p9_conn *m, struct p9_req *req)
{
	struct p9_fcall *fc;
	struct p9_req *rreq, *rptr;

	P9_DPRINTK(P9_DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag);

	/* if a response was received for a request, do nothing */
	spin_lock(&req->lock);
	if (req->rcall || req->err) {
		spin_unlock(&req->lock);
		P9_DPRINTK(P9_DEBUG_MUX,
			"mux %p req %p response already received\n", m, req);
		return 0;
	}

	req->flush = Flushing;
	spin_unlock(&req->lock);

	spin_lock(&m->lock);
	/* if the request is not sent yet, just remove it from the list */
	list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) {
		if (rreq->tag == req->tag) {
			P9_DPRINTK(P9_DEBUG_MUX,
			   "mux %p req %p request is not sent yet\n", m, req);
			list_del(&rreq->req_list);
			req->flush = Flushed;
			spin_unlock(&m->lock);
902
			p9_conn_rpc_cb(req);
903 904 905 906 907 908 909
			return 0;
		}
	}
	spin_unlock(&m->lock);

	clear_thread_flag(TIF_SIGPENDING);
	fc = p9_create_tflush(req->tag);
910
	p9_send_request(m, fc);
911 912 913 914 915 916
	return 1;
}

/**
 * p9_fd_rpc- sends 9P request and waits until a response is available.
 *	The function can be interrupted.
917
 * @client: client instance
918 919
 * @tc: request to be sent
 * @rc: pointer where a pointer to the response is stored
920
 *
921
 */
922

923
int
924
p9_fd_rpc(struct p9_client *client, struct p9_fcall *tc, struct p9_fcall **rc)
925
{
926
	struct p9_trans_fd *p = client->trans;
927 928 929 930 931 932 933 934 935 936 937 938 939 940
	struct p9_conn *m = p->conn;
	int err, sigpending;
	unsigned long flags;
	struct p9_req *req;

	if (rc)
		*rc = NULL;

	sigpending = 0;
	if (signal_pending(current)) {
		sigpending = 1;
		clear_thread_flag(TIF_SIGPENDING);
	}

941
	req = p9_send_request(m, tc);
942 943 944 945 946 947
	if (IS_ERR(req)) {
		err = PTR_ERR(req);
		P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err);
		return err;
	}

948 949 950 951
	err = wait_event_interruptible(req->wqueue, req->rcall != NULL ||
								req->err < 0);
	if (req->err < 0)
		err = req->err;
952

953
	if (err == -ERESTARTSYS && client->status == Connected
954 955 956 957 958
							&& m->err == 0) {
		if (p9_mux_flush_request(m, req)) {
			/* wait until we get response of the flush message */
			do {
				clear_thread_flag(TIF_SIGPENDING);
959 960 961 962 963
				err = wait_event_interruptible(req->wqueue,
					req->rcall || req->err);
			} while (!req->rcall && !req->err &&
					err == -ERESTARTSYS &&
					client->status == Connected && !m->err);
964 965 966 967 968 969 970 971 972 973 974 975 976

			err = -ERESTARTSYS;
		}
		sigpending = 1;
	}

	if (sigpending) {
		spin_lock_irqsave(&current->sighand->siglock, flags);
		recalc_sigpending();
		spin_unlock_irqrestore(&current->sighand->siglock, flags);
	}

	if (rc)
977
		*rc = req->rcall;
978
	else
979
		kfree(req->rcall);
980 981 982 983 984 985 986 987

	p9_mux_free_request(m, req);
	if (err > 0)
		err = -EIO;

	return err;
}

988
/**
989
 * parse_options - parse mount options into session structure
990
 * @options: options string passed from mount
991
 * @opts: transport-specific structure to parse options into
992
 *
993
 * Returns 0 upon success, -ERRNO upon failure
994
 */
995

996
static int parse_opts(char *params, struct p9_fd_opts *opts)
997
{
998 999 1000
	char *p;
	substring_t args[MAX_OPT_ARGS];
	int option;
1001
	char *options;
1002
	int ret;
1003

1004 1005 1006
	opts->port = P9_PORT;
	opts->rfd = ~0;
	opts->wfd = ~0;
1007

1008 1009 1010 1011 1012 1013 1014 1015 1016
	if (!params)
		return 0;

	options = kstrdup(params, GFP_KERNEL);
	if (!options) {
		P9_DPRINTK(P9_DEBUG_ERROR,
				"failed to allocate copy of option string\n");
		return -ENOMEM;
	}
1017

1018 1019
	while ((p = strsep(&options, ",")) != NULL) {
		int token;
1020
		int r;
1021 1022 1023
		if (!*p)
			continue;
		token = match_token(p, tokens, args);
1024 1025
		r = match_int(&args[0], &option);
		if (r < 0) {
1026 1027
			P9_DPRINTK(P9_DEBUG_ERROR,
			 "integer field, but no integer?\n");
1028
			ret = r;
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
			continue;
		}
		switch (token) {
		case Opt_port:
			opts->port = option;
			break;
		case Opt_rfdno:
			opts->rfd = option;
			break;
		case Opt_wfdno:
			opts->wfd = option;
			break;
		default:
			continue;
		}
1044
	}
1045 1046
	kfree(options);
	return 0;
1047 1048
}

1049
static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
1050
{
1051 1052 1053 1054
	struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
					   GFP_KERNEL);
	if (!ts)
		return -ENOMEM;
1055

1056 1057 1058 1059 1060 1061 1062 1063 1064
	ts->rd = fget(rfd);
	ts->wr = fget(wfd);
	if (!ts->rd || !ts->wr) {
		if (ts->rd)
			fput(ts->rd);
		if (ts->wr)
			fput(ts->wr);
		kfree(ts);
		return -EIO;
1065 1066
	}

1067 1068
	client->trans = ts;
	client->status = Connected;
1069

1070
	return 0;
1071 1072
}

1073
static int p9_socket_open(struct p9_client *client, struct socket *csocket)
1074 1075 1076 1077
{
	int fd, ret;

	csocket->sk->sk_allocation = GFP_NOIO;
1078
	fd = sock_map_fd(csocket, 0);
1079 1080 1081 1082 1083
	if (fd < 0) {
		P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to map fd\n");
		return fd;
	}

1084
	ret = p9_fd_open(client, fd, fd);
1085 1086 1087 1088 1089 1090
	if (ret < 0) {
		P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n");
		sockfd_put(csocket);
		return ret;
	}

1091
	((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK;
1092 1093 1094 1095 1096

	return 0;
}

/**
1097 1098
 * p9_mux_destroy - cancels all pending requests and frees mux resources
 * @m: mux to destroy
1099 1100
 *
 */
1101

1102
static void p9_conn_destroy(struct p9_conn *m)
1103
{
1104 1105
	P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
		m->mux_list.prev, m->mux_list.next);
1106

1107 1108 1109
	p9_mux_poll_stop(m);
	cancel_work_sync(&m->rq);
	cancel_work_sync(&m->wq);
1110

1111
	p9_conn_cancel(m, -ECONNRESET);
1112

1113 1114
	m->client = NULL;
	kfree(m);
1115 1116 1117
}

/**
Eric Van Hensbergen's avatar