xref: /linux/net/9p/client.c (revision 5499b45190237ca90dd2ac86395cf464fe1f4cc7)
1 /*
2  * net/9p/clnt.c
3  *
4  * 9P Client
5  *
6  *  Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
7  *  Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2
11  *  as published by the Free Software Foundation.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to:
20  *  Free Software Foundation
21  *  51 Franklin Street, Fifth Floor
22  *  Boston, MA  02111-1301  USA
23  *
24  */
25 
26 #include <linux/module.h>
27 #include <linux/errno.h>
28 #include <linux/fs.h>
29 #include <linux/poll.h>
30 #include <linux/idr.h>
31 #include <linux/mutex.h>
32 #include <linux/sched.h>
33 #include <linux/uaccess.h>
34 #include <net/9p/9p.h>
35 #include <linux/parser.h>
36 #include <net/9p/client.h>
37 #include <net/9p/transport.h>
38 #include "protocol.h"
39 
40 /*
41   * Client Option Parsing (code inspired by NFS code)
42   *  - a little lazy - parse all client options
43   */
44 
45 enum {
46 	Opt_msize,
47 	Opt_trans,
48 	Opt_legacy,
49 	Opt_err,
50 };
51 
52 static const match_table_t tokens = {
53 	{Opt_msize, "msize=%u"},
54 	{Opt_legacy, "noextend"},
55 	{Opt_trans, "trans=%s"},
56 	{Opt_err, NULL},
57 };
58 
59 static struct p9_req_t *
60 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
61 
62 /**
63  * parse_options - parse mount options into client structure
64  * @opts: options string passed from mount
65  * @clnt: existing v9fs client information
66  *
67  * Return 0 upon success, -ERRNO upon failure
68  */
69 
70 static int parse_opts(char *opts, struct p9_client *clnt)
71 {
72 	char *options, *tmp_options;
73 	char *p;
74 	substring_t args[MAX_OPT_ARGS];
75 	int option;
76 	int ret = 0;
77 
78 	clnt->dotu = 1;
79 	clnt->msize = 8192;
80 
81 	if (!opts)
82 		return 0;
83 
84 	tmp_options = kstrdup(opts, GFP_KERNEL);
85 	if (!tmp_options) {
86 		P9_DPRINTK(P9_DEBUG_ERROR,
87 				"failed to allocate copy of option string\n");
88 		return -ENOMEM;
89 	}
90 	options = tmp_options;
91 
92 	while ((p = strsep(&options, ",")) != NULL) {
93 		int token;
94 		if (!*p)
95 			continue;
96 		token = match_token(p, tokens, args);
97 		if (token < Opt_trans) {
98 			int r = match_int(&args[0], &option);
99 			if (r < 0) {
100 				P9_DPRINTK(P9_DEBUG_ERROR,
101 					"integer field, but no integer?\n");
102 				ret = r;
103 				continue;
104 			}
105 		}
106 		switch (token) {
107 		case Opt_msize:
108 			clnt->msize = option;
109 			break;
110 		case Opt_trans:
111 			clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
112 			if(clnt->trans_mod == NULL) {
113 				P9_DPRINTK(P9_DEBUG_ERROR,
114 				   "Could not find request transport: %s\n",
115 				   (char *) &args[0]);
116 				ret = -EINVAL;
117 				goto free_and_return;
118 			}
119 			break;
120 		case Opt_legacy:
121 			clnt->dotu = 0;
122 			break;
123 		default:
124 			continue;
125 		}
126 	}
127 
128 free_and_return:
129 	kfree(tmp_options);
130 	return ret;
131 }
132 
133 /**
134  * p9_tag_alloc - lookup/allocate a request by tag
135  * @c: client session to lookup tag within
136  * @tag: numeric id for transaction
137  *
138  * this is a simple array lookup, but will grow the
139  * request_slots as necessary to accomodate transaction
140  * ids which did not previously have a slot.
141  *
142  * this code relies on the client spinlock to manage locks, its
143  * possible we should switch to something else, but I'd rather
144  * stick with something low-overhead for the common case.
145  *
146  */
147 
148 static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
149 {
150 	unsigned long flags;
151 	int row, col;
152 	struct p9_req_t *req;
153 
154 	/* This looks up the original request by tag so we know which
155 	 * buffer to read the data into */
156 	tag++;
157 
158 	if (tag >= c->max_tag) {
159 		spin_lock_irqsave(&c->lock, flags);
160 		/* check again since original check was outside of lock */
161 		while (tag >= c->max_tag) {
162 			row = (tag / P9_ROW_MAXTAG);
163 			c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
164 					sizeof(struct p9_req_t), GFP_ATOMIC);
165 
166 			if (!c->reqs[row]) {
167 				printk(KERN_ERR "Couldn't grow tag array\n");
168 				spin_unlock_irqrestore(&c->lock, flags);
169 				return ERR_PTR(-ENOMEM);
170 			}
171 			for (col = 0; col < P9_ROW_MAXTAG; col++) {
172 				c->reqs[row][col].status = REQ_STATUS_IDLE;
173 				c->reqs[row][col].tc = NULL;
174 			}
175 			c->max_tag += P9_ROW_MAXTAG;
176 		}
177 		spin_unlock_irqrestore(&c->lock, flags);
178 	}
179 	row = tag / P9_ROW_MAXTAG;
180 	col = tag % P9_ROW_MAXTAG;
181 
182 	req = &c->reqs[row][col];
183 	if (!req->tc) {
184 		req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
185 		if (!req->wq) {
186 			printk(KERN_ERR "Couldn't grow tag array\n");
187 			return ERR_PTR(-ENOMEM);
188 		}
189 		init_waitqueue_head(req->wq);
190 		req->tc = kmalloc(sizeof(struct p9_fcall)+c->msize,
191 								GFP_KERNEL);
192 		req->rc = kmalloc(sizeof(struct p9_fcall)+c->msize,
193 								GFP_KERNEL);
194 		if ((!req->tc) || (!req->rc)) {
195 			printk(KERN_ERR "Couldn't grow tag array\n");
196 			kfree(req->tc);
197 			kfree(req->rc);
198 			kfree(req->wq);
199 			req->tc = req->rc = NULL;
200 			req->wq = NULL;
201 			return ERR_PTR(-ENOMEM);
202 		}
203 		req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
204 		req->tc->capacity = c->msize;
205 		req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
206 		req->rc->capacity = c->msize;
207 	}
208 
209 	p9pdu_reset(req->tc);
210 	p9pdu_reset(req->rc);
211 
212 	req->tc->tag = tag-1;
213 	req->status = REQ_STATUS_ALLOC;
214 
215 	return &c->reqs[row][col];
216 }
217 
218 /**
219  * p9_tag_lookup - lookup a request by tag
220  * @c: client session to lookup tag within
221  * @tag: numeric id for transaction
222  *
223  */
224 
225 struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
226 {
227 	int row, col;
228 
229 	/* This looks up the original request by tag so we know which
230 	 * buffer to read the data into */
231 	tag++;
232 
233 	BUG_ON(tag >= c->max_tag);
234 
235 	row = tag / P9_ROW_MAXTAG;
236 	col = tag % P9_ROW_MAXTAG;
237 
238 	return &c->reqs[row][col];
239 }
240 EXPORT_SYMBOL(p9_tag_lookup);
241 
242 /**
243  * p9_tag_init - setup tags structure and contents
244  * @c:  v9fs client struct
245  *
246  * This initializes the tags structure for each client instance.
247  *
248  */
249 
250 static int p9_tag_init(struct p9_client *c)
251 {
252 	int err = 0;
253 
254 	c->tagpool = p9_idpool_create();
255 	if (IS_ERR(c->tagpool)) {
256 		err = PTR_ERR(c->tagpool);
257 		c->tagpool = NULL;
258 		goto error;
259 	}
260 
261 	p9_idpool_get(c->tagpool); /* reserve tag 0 */
262 
263 	c->max_tag = 0;
264 error:
265 	return err;
266 }
267 
268 /**
269  * p9_tag_cleanup - cleans up tags structure and reclaims resources
270  * @c:  v9fs client struct
271  *
272  * This frees resources associated with the tags structure
273  *
274  */
275 static void p9_tag_cleanup(struct p9_client *c)
276 {
277 	int row, col;
278 
279 	/* check to insure all requests are idle */
280 	for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
281 		for (col = 0; col < P9_ROW_MAXTAG; col++) {
282 			if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
283 				P9_DPRINTK(P9_DEBUG_MUX,
284 				  "Attempting to cleanup non-free tag %d,%d\n",
285 				  row, col);
286 				/* TODO: delay execution of cleanup */
287 				return;
288 			}
289 		}
290 	}
291 
292 	if (c->tagpool)
293 		p9_idpool_destroy(c->tagpool);
294 
295 	/* free requests associated with tags */
296 	for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
297 		for (col = 0; col < P9_ROW_MAXTAG; col++) {
298 			kfree(c->reqs[row][col].wq);
299 			kfree(c->reqs[row][col].tc);
300 			kfree(c->reqs[row][col].rc);
301 		}
302 		kfree(c->reqs[row]);
303 	}
304 	c->max_tag = 0;
305 }
306 
307 /**
308  * p9_free_req - free a request and clean-up as necessary
309  * c: client state
310  * r: request to release
311  *
312  */
313 
314 static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
315 {
316 	int tag = r->tc->tag;
317 	P9_DPRINTK(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
318 
319 	r->status = REQ_STATUS_IDLE;
320 	if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
321 		p9_idpool_put(tag, c->tagpool);
322 }
323 
324 /**
325  * p9_client_cb - call back from transport to client
326  * c: client state
327  * req: request received
328  *
329  */
330 void p9_client_cb(struct p9_client *c, struct p9_req_t *req)
331 {
332 	P9_DPRINTK(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
333 	wake_up(req->wq);
334 	P9_DPRINTK(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
335 }
336 EXPORT_SYMBOL(p9_client_cb);
337 
338 /**
339  * p9_parse_header - parse header arguments out of a packet
340  * @pdu: packet to parse
341  * @size: size of packet
342  * @type: type of request
343  * @tag: tag of packet
344  * @rewind: set if we need to rewind offset afterwards
345  */
346 
347 int
348 p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
349 								int rewind)
350 {
351 	int8_t r_type;
352 	int16_t r_tag;
353 	int32_t r_size;
354 	int offset = pdu->offset;
355 	int err;
356 
357 	pdu->offset = 0;
358 	if (pdu->size == 0)
359 		pdu->size = 7;
360 
361 	err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag);
362 	if (err)
363 		goto rewind_and_exit;
364 
365 	pdu->size = r_size;
366 	pdu->id = r_type;
367 	pdu->tag = r_tag;
368 
369 	P9_DPRINTK(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n", pdu->size,
370 							pdu->id, pdu->tag);
371 
372 	if (type)
373 		*type = r_type;
374 	if (tag)
375 		*tag = r_tag;
376 	if (size)
377 		*size = r_size;
378 
379 
380 rewind_and_exit:
381 	if (rewind)
382 		pdu->offset = offset;
383 	return err;
384 }
385 EXPORT_SYMBOL(p9_parse_header);
386 
387 /**
388  * p9_check_errors - check 9p packet for error return and process it
389  * @c: current client instance
390  * @req: request to parse and check for error conditions
391  *
392  * returns error code if one is discovered, otherwise returns 0
393  *
394  * this will have to be more complicated if we have multiple
395  * error packet types
396  */
397 
398 static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
399 {
400 	int8_t type;
401 	int err;
402 
403 	err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
404 	if (err) {
405 		P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
406 		return err;
407 	}
408 
409 	if (type == P9_RERROR) {
410 		int ecode;
411 		char *ename;
412 
413 		err = p9pdu_readf(req->rc, c->dotu, "s?d", &ename, &ecode);
414 		if (err) {
415 			P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n",
416 									err);
417 			return err;
418 		}
419 
420 		if (c->dotu)
421 			err = -ecode;
422 
423 		if (!err || !IS_ERR_VALUE(err))
424 			err = p9_errstr2errno(ename, strlen(ename));
425 
426 		P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
427 
428 		kfree(ename);
429 	} else
430 		err = 0;
431 
432 	return err;
433 }
434 
435 /**
436  * p9_client_flush - flush (cancel) a request
437  * @c: client state
438  * @oldreq: request to cancel
439  *
440  * This sents a flush for a particular requests and links
441  * the flush request to the original request.  The current
442  * code only supports a single flush request although the protocol
443  * allows for multiple flush requests to be sent for a single request.
444  *
445  */
446 
447 static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
448 {
449 	struct p9_req_t *req;
450 	int16_t oldtag;
451 	int err;
452 
453 	err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1);
454 	if (err)
455 		return err;
456 
457 	P9_DPRINTK(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag);
458 
459 	req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag);
460 	if (IS_ERR(req))
461 		return PTR_ERR(req);
462 
463 
464 	/* if we haven't received a response for oldreq,
465 	   remove it from the list. */
466 	spin_lock(&c->lock);
467 	if (oldreq->status == REQ_STATUS_FLSH)
468 		list_del(&oldreq->req_list);
469 	spin_unlock(&c->lock);
470 
471 	p9_free_req(c, req);
472 	return 0;
473 }
474 
475 /**
476  * p9_client_rpc - issue a request and wait for a response
477  * @c: client session
478  * @type: type of request
479  * @fmt: protocol format string (see protocol.c)
480  *
481  * Returns request structure (which client must free using p9_free_req)
482  */
483 
484 static struct p9_req_t *
485 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
486 {
487 	va_list ap;
488 	int tag, err;
489 	struct p9_req_t *req;
490 	unsigned long flags;
491 	int sigpending;
492 
493 	P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
494 
495 	if (c->status != Connected)
496 		return ERR_PTR(-EIO);
497 
498 	if (signal_pending(current)) {
499 		sigpending = 1;
500 		clear_thread_flag(TIF_SIGPENDING);
501 	} else
502 		sigpending = 0;
503 
504 	tag = P9_NOTAG;
505 	if (type != P9_TVERSION) {
506 		tag = p9_idpool_get(c->tagpool);
507 		if (tag < 0)
508 			return ERR_PTR(-ENOMEM);
509 	}
510 
511 	req = p9_tag_alloc(c, tag);
512 	if (IS_ERR(req))
513 		return req;
514 
515 	/* marshall the data */
516 	p9pdu_prepare(req->tc, tag, type);
517 	va_start(ap, fmt);
518 	err = p9pdu_vwritef(req->tc, c->dotu, fmt, ap);
519 	va_end(ap);
520 	p9pdu_finalize(req->tc);
521 
522 	err = c->trans_mod->request(c, req);
523 	if (err < 0) {
524 		c->status = Disconnected;
525 		goto reterr;
526 	}
527 
528 	P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag);
529 	err = wait_event_interruptible(*req->wq,
530 						req->status >= REQ_STATUS_RCVD);
531 	P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d\n",
532 						req->wq, tag, err);
533 
534 	if (req->status == REQ_STATUS_ERROR) {
535 		P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
536 		err = req->t_err;
537 	}
538 
539 	if ((err == -ERESTARTSYS) && (c->status == Connected)) {
540 		P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
541 		sigpending = 1;
542 		clear_thread_flag(TIF_SIGPENDING);
543 
544 		if (c->trans_mod->cancel(c, req))
545 			p9_client_flush(c, req);
546 
547 		/* if we received the response anyway, don't signal error */
548 		if (req->status == REQ_STATUS_RCVD)
549 			err = 0;
550 	}
551 
552 	if (sigpending) {
553 		spin_lock_irqsave(&current->sighand->siglock, flags);
554 		recalc_sigpending();
555 		spin_unlock_irqrestore(&current->sighand->siglock, flags);
556 	}
557 
558 	if (err < 0)
559 		goto reterr;
560 
561 	err = p9_check_errors(c, req);
562 	if (!err) {
563 		P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
564 		return req;
565 	}
566 
567 reterr:
568 	P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
569 									err);
570 	p9_free_req(c, req);
571 	return ERR_PTR(err);
572 }
573 
574 static struct p9_fid *p9_fid_create(struct p9_client *clnt)
575 {
576 	int ret;
577 	struct p9_fid *fid;
578 	unsigned long flags;
579 
580 	P9_DPRINTK(P9_DEBUG_FID, "clnt %p\n", clnt);
581 	fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
582 	if (!fid)
583 		return ERR_PTR(-ENOMEM);
584 
585 	ret = p9_idpool_get(clnt->fidpool);
586 	if (ret < 0) {
587 		ret = -ENOSPC;
588 		goto error;
589 	}
590 	fid->fid = ret;
591 
592 	memset(&fid->qid, 0, sizeof(struct p9_qid));
593 	fid->mode = -1;
594 	fid->uid = current_fsuid();
595 	fid->clnt = clnt;
596 	fid->rdir = NULL;
597 	spin_lock_irqsave(&clnt->lock, flags);
598 	list_add(&fid->flist, &clnt->fidlist);
599 	spin_unlock_irqrestore(&clnt->lock, flags);
600 
601 	return fid;
602 
603 error:
604 	kfree(fid);
605 	return ERR_PTR(ret);
606 }
607 
608 static void p9_fid_destroy(struct p9_fid *fid)
609 {
610 	struct p9_client *clnt;
611 	unsigned long flags;
612 
613 	P9_DPRINTK(P9_DEBUG_FID, "fid %d\n", fid->fid);
614 	clnt = fid->clnt;
615 	p9_idpool_put(fid->fid, clnt->fidpool);
616 	spin_lock_irqsave(&clnt->lock, flags);
617 	list_del(&fid->flist);
618 	spin_unlock_irqrestore(&clnt->lock, flags);
619 	kfree(fid->rdir);
620 	kfree(fid);
621 }
622 
623 int p9_client_version(struct p9_client *c)
624 {
625 	int err = 0;
626 	struct p9_req_t *req;
627 	char *version;
628 	int msize;
629 
630 	P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n",
631 							c->msize, c->dotu);
632 	req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize,
633 				c->dotu ? "9P2000.u" : "9P2000");
634 	if (IS_ERR(req))
635 		return PTR_ERR(req);
636 
637 	err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version);
638 	if (err) {
639 		P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
640 		p9pdu_dump(1, req->rc);
641 		goto error;
642 	}
643 
644 	P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
645 	if (!memcmp(version, "9P2000.u", 8))
646 		c->dotu = 1;
647 	else if (!memcmp(version, "9P2000", 6))
648 		c->dotu = 0;
649 	else {
650 		err = -EREMOTEIO;
651 		goto error;
652 	}
653 
654 	if (msize < c->msize)
655 		c->msize = msize;
656 
657 error:
658 	kfree(version);
659 	p9_free_req(c, req);
660 
661 	return err;
662 }
663 EXPORT_SYMBOL(p9_client_version);
664 
665 struct p9_client *p9_client_create(const char *dev_name, char *options)
666 {
667 	int err;
668 	struct p9_client *clnt;
669 
670 	err = 0;
671 	clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
672 	if (!clnt)
673 		return ERR_PTR(-ENOMEM);
674 
675 	clnt->trans_mod = NULL;
676 	clnt->trans = NULL;
677 	spin_lock_init(&clnt->lock);
678 	INIT_LIST_HEAD(&clnt->fidlist);
679 
680 	p9_tag_init(clnt);
681 
682 	err = parse_opts(options, clnt);
683 	if (err < 0)
684 		goto free_client;
685 
686 	if (!clnt->trans_mod)
687 		clnt->trans_mod = v9fs_get_default_trans();
688 
689 	if (clnt->trans_mod == NULL) {
690 		err = -EPROTONOSUPPORT;
691 		P9_DPRINTK(P9_DEBUG_ERROR,
692 				"No transport defined or default transport\n");
693 		goto free_client;
694 	}
695 
696 	clnt->fidpool = p9_idpool_create();
697 	if (IS_ERR(clnt->fidpool)) {
698 		err = PTR_ERR(clnt->fidpool);
699 		clnt->fidpool = NULL;
700 		goto put_trans;
701 	}
702 
703 	P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n",
704 		clnt, clnt->trans_mod, clnt->msize, clnt->dotu);
705 
706 	err = clnt->trans_mod->create(clnt, dev_name, options);
707 	if (err)
708 		goto destroy_fidpool;
709 
710 	if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)
711 		clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;
712 
713 	err = p9_client_version(clnt);
714 	if (err)
715 		goto close_trans;
716 
717 	return clnt;
718 
719 close_trans:
720 	clnt->trans_mod->close(clnt);
721 destroy_fidpool:
722 	p9_idpool_destroy(clnt->fidpool);
723 put_trans:
724 	v9fs_put_trans(clnt->trans_mod);
725 free_client:
726 	kfree(clnt);
727 	return ERR_PTR(err);
728 }
729 EXPORT_SYMBOL(p9_client_create);
730 
731 void p9_client_destroy(struct p9_client *clnt)
732 {
733 	struct p9_fid *fid, *fidptr;
734 
735 	P9_DPRINTK(P9_DEBUG_MUX, "clnt %p\n", clnt);
736 
737 	if (clnt->trans_mod)
738 		clnt->trans_mod->close(clnt);
739 
740 	v9fs_put_trans(clnt->trans_mod);
741 
742 	list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
743 		p9_fid_destroy(fid);
744 
745 	if (clnt->fidpool)
746 		p9_idpool_destroy(clnt->fidpool);
747 
748 	p9_tag_cleanup(clnt);
749 
750 	kfree(clnt);
751 }
752 EXPORT_SYMBOL(p9_client_destroy);
753 
754 void p9_client_disconnect(struct p9_client *clnt)
755 {
756 	P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
757 	clnt->status = Disconnected;
758 }
759 EXPORT_SYMBOL(p9_client_disconnect);
760 
761 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
762 	char *uname, u32 n_uname, char *aname)
763 {
764 	int err;
765 	struct p9_req_t *req;
766 	struct p9_fid *fid;
767 	struct p9_qid qid;
768 
769 	P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
770 					afid ? afid->fid : -1, uname, aname);
771 	err = 0;
772 
773 	fid = p9_fid_create(clnt);
774 	if (IS_ERR(fid)) {
775 		err = PTR_ERR(fid);
776 		fid = NULL;
777 		goto error;
778 	}
779 
780 	req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid,
781 			afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
782 	if (IS_ERR(req)) {
783 		err = PTR_ERR(req);
784 		goto error;
785 	}
786 
787 	err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
788 	if (err) {
789 		p9pdu_dump(1, req->rc);
790 		p9_free_req(clnt, req);
791 		goto error;
792 	}
793 
794 	P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
795 					qid.type,
796 					(unsigned long long)qid.path,
797 					qid.version);
798 
799 	memmove(&fid->qid, &qid, sizeof(struct p9_qid));
800 
801 	p9_free_req(clnt, req);
802 	return fid;
803 
804 error:
805 	if (fid)
806 		p9_fid_destroy(fid);
807 	return ERR_PTR(err);
808 }
809 EXPORT_SYMBOL(p9_client_attach);
810 
811 struct p9_fid *
812 p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
813 {
814 	int err;
815 	struct p9_req_t *req;
816 	struct p9_qid qid;
817 	struct p9_fid *afid;
818 
819 	P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname);
820 	err = 0;
821 
822 	afid = p9_fid_create(clnt);
823 	if (IS_ERR(afid)) {
824 		err = PTR_ERR(afid);
825 		afid = NULL;
826 		goto error;
827 	}
828 
829 	req = p9_client_rpc(clnt, P9_TAUTH, "dss?d",
830 			afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
831 	if (IS_ERR(req)) {
832 		err = PTR_ERR(req);
833 		goto error;
834 	}
835 
836 	err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
837 	if (err) {
838 		p9pdu_dump(1, req->rc);
839 		p9_free_req(clnt, req);
840 		goto error;
841 	}
842 
843 	P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n",
844 					qid.type,
845 					(unsigned long long)qid.path,
846 					qid.version);
847 
848 	memmove(&afid->qid, &qid, sizeof(struct p9_qid));
849 	p9_free_req(clnt, req);
850 	return afid;
851 
852 error:
853 	if (afid)
854 		p9_fid_destroy(afid);
855 	return ERR_PTR(err);
856 }
857 EXPORT_SYMBOL(p9_client_auth);
858 
859 struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
860 	int clone)
861 {
862 	int err;
863 	struct p9_client *clnt;
864 	struct p9_fid *fid;
865 	struct p9_qid *wqids;
866 	struct p9_req_t *req;
867 	int16_t nwqids, count;
868 
869 	err = 0;
870 	clnt = oldfid->clnt;
871 	if (clone) {
872 		fid = p9_fid_create(clnt);
873 		if (IS_ERR(fid)) {
874 			err = PTR_ERR(fid);
875 			fid = NULL;
876 			goto error;
877 		}
878 
879 		fid->uid = oldfid->uid;
880 	} else
881 		fid = oldfid;
882 
883 
884 	P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %d wname[0] %s\n",
885 		oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
886 
887 	req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
888 								nwname, wnames);
889 	if (IS_ERR(req)) {
890 		err = PTR_ERR(req);
891 		goto error;
892 	}
893 
894 	err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids);
895 	if (err) {
896 		p9pdu_dump(1, req->rc);
897 		p9_free_req(clnt, req);
898 		goto clunk_fid;
899 	}
900 	p9_free_req(clnt, req);
901 
902 	P9_DPRINTK(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
903 
904 	if (nwqids != nwname) {
905 		err = -ENOENT;
906 		goto clunk_fid;
907 	}
908 
909 	for (count = 0; count < nwqids; count++)
910 		P9_DPRINTK(P9_DEBUG_9P, "<<<     [%d] %x.%llx.%x\n",
911 			count, wqids[count].type,
912 			(unsigned long long)wqids[count].path,
913 			wqids[count].version);
914 
915 	if (nwname)
916 		memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
917 	else
918 		fid->qid = oldfid->qid;
919 
920 	return fid;
921 
922 clunk_fid:
923 	p9_client_clunk(fid);
924 	fid = NULL;
925 
926 error:
927 	if (fid && (fid != oldfid))
928 		p9_fid_destroy(fid);
929 
930 	return ERR_PTR(err);
931 }
932 EXPORT_SYMBOL(p9_client_walk);
933 
934 int p9_client_open(struct p9_fid *fid, int mode)
935 {
936 	int err;
937 	struct p9_client *clnt;
938 	struct p9_req_t *req;
939 	struct p9_qid qid;
940 	int iounit;
941 
942 	P9_DPRINTK(P9_DEBUG_9P, ">>> TOPEN fid %d mode %d\n", fid->fid, mode);
943 	err = 0;
944 	clnt = fid->clnt;
945 
946 	if (fid->mode != -1)
947 		return -EINVAL;
948 
949 	req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
950 	if (IS_ERR(req)) {
951 		err = PTR_ERR(req);
952 		goto error;
953 	}
954 
955 	err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
956 	if (err) {
957 		p9pdu_dump(1, req->rc);
958 		goto free_and_error;
959 	}
960 
961 	P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n",
962 				qid.type,
963 				(unsigned long long)qid.path,
964 				qid.version, iounit);
965 
966 	fid->mode = mode;
967 	fid->iounit = iounit;
968 
969 free_and_error:
970 	p9_free_req(clnt, req);
971 error:
972 	return err;
973 }
974 EXPORT_SYMBOL(p9_client_open);
975 
976 int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
977 		     char *extension)
978 {
979 	int err;
980 	struct p9_client *clnt;
981 	struct p9_req_t *req;
982 	struct p9_qid qid;
983 	int iounit;
984 
985 	P9_DPRINTK(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
986 						fid->fid, name, perm, mode);
987 	err = 0;
988 	clnt = fid->clnt;
989 
990 	if (fid->mode != -1)
991 		return -EINVAL;
992 
993 	req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
994 				mode, extension);
995 	if (IS_ERR(req)) {
996 		err = PTR_ERR(req);
997 		goto error;
998 	}
999 
1000 	err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
1001 	if (err) {
1002 		p9pdu_dump(1, req->rc);
1003 		goto free_and_error;
1004 	}
1005 
1006 	P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
1007 				qid.type,
1008 				(unsigned long long)qid.path,
1009 				qid.version, iounit);
1010 
1011 	fid->mode = mode;
1012 	fid->iounit = iounit;
1013 
1014 free_and_error:
1015 	p9_free_req(clnt, req);
1016 error:
1017 	return err;
1018 }
1019 EXPORT_SYMBOL(p9_client_fcreate);
1020 
1021 int p9_client_clunk(struct p9_fid *fid)
1022 {
1023 	int err;
1024 	struct p9_client *clnt;
1025 	struct p9_req_t *req;
1026 
1027 	P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
1028 	err = 0;
1029 	clnt = fid->clnt;
1030 
1031 	req = p9_client_rpc(clnt, P9_TCLUNK, "d", fid->fid);
1032 	if (IS_ERR(req)) {
1033 		err = PTR_ERR(req);
1034 		goto error;
1035 	}
1036 
1037 	P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
1038 
1039 	p9_free_req(clnt, req);
1040 	p9_fid_destroy(fid);
1041 
1042 error:
1043 	return err;
1044 }
1045 EXPORT_SYMBOL(p9_client_clunk);
1046 
1047 int p9_client_remove(struct p9_fid *fid)
1048 {
1049 	int err;
1050 	struct p9_client *clnt;
1051 	struct p9_req_t *req;
1052 
1053 	P9_DPRINTK(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid);
1054 	err = 0;
1055 	clnt = fid->clnt;
1056 
1057 	req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid);
1058 	if (IS_ERR(req)) {
1059 		err = PTR_ERR(req);
1060 		goto error;
1061 	}
1062 
1063 	P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
1064 
1065 	p9_free_req(clnt, req);
1066 	p9_fid_destroy(fid);
1067 
1068 error:
1069 	return err;
1070 }
1071 EXPORT_SYMBOL(p9_client_remove);
1072 
1073 int
1074 p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1075 								u32 count)
1076 {
1077 	int err, rsize, total;
1078 	struct p9_client *clnt;
1079 	struct p9_req_t *req;
1080 	char *dataptr;
1081 
1082 	P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid,
1083 					(long long unsigned) offset, count);
1084 	err = 0;
1085 	clnt = fid->clnt;
1086 	total = 0;
1087 
1088 	rsize = fid->iounit;
1089 	if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1090 		rsize = clnt->msize - P9_IOHDRSZ;
1091 
1092 	if (count < rsize)
1093 		rsize = count;
1094 
1095 	req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, rsize);
1096 	if (IS_ERR(req)) {
1097 		err = PTR_ERR(req);
1098 		goto error;
1099 	}
1100 
1101 	err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr);
1102 	if (err) {
1103 		p9pdu_dump(1, req->rc);
1104 		goto free_and_error;
1105 	}
1106 
1107 	P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1108 
1109 	if (data) {
1110 		memmove(data, dataptr, count);
1111 	}
1112 
1113 	if (udata) {
1114 		err = copy_to_user(udata, dataptr, count);
1115 		if (err) {
1116 			err = -EFAULT;
1117 			goto free_and_error;
1118 		}
1119 	}
1120 
1121 	p9_free_req(clnt, req);
1122 	return count;
1123 
1124 free_and_error:
1125 	p9_free_req(clnt, req);
1126 error:
1127 	return err;
1128 }
1129 EXPORT_SYMBOL(p9_client_read);
1130 
1131 int
1132 p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1133 							u64 offset, u32 count)
1134 {
1135 	int err, rsize, total;
1136 	struct p9_client *clnt;
1137 	struct p9_req_t *req;
1138 
1139 	P9_DPRINTK(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n",
1140 				fid->fid, (long long unsigned) offset, count);
1141 	err = 0;
1142 	clnt = fid->clnt;
1143 	total = 0;
1144 
1145 	rsize = fid->iounit;
1146 	if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1147 		rsize = clnt->msize - P9_IOHDRSZ;
1148 
1149 	if (count < rsize)
1150 		rsize = count;
1151 	if (data)
1152 		req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid, offset,
1153 								rsize, data);
1154 	else
1155 		req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid, offset,
1156 								rsize, udata);
1157 	if (IS_ERR(req)) {
1158 		err = PTR_ERR(req);
1159 		goto error;
1160 	}
1161 
1162 	err = p9pdu_readf(req->rc, clnt->dotu, "d", &count);
1163 	if (err) {
1164 		p9pdu_dump(1, req->rc);
1165 		goto free_and_error;
1166 	}
1167 
1168 	P9_DPRINTK(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
1169 
1170 	p9_free_req(clnt, req);
1171 	return count;
1172 
1173 free_and_error:
1174 	p9_free_req(clnt, req);
1175 error:
1176 	return err;
1177 }
1178 EXPORT_SYMBOL(p9_client_write);
1179 
1180 struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1181 {
1182 	int err;
1183 	struct p9_client *clnt;
1184 	struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
1185 	struct p9_req_t *req;
1186 	u16 ignored;
1187 
1188 	P9_DPRINTK(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
1189 
1190 	if (!ret)
1191 		return ERR_PTR(-ENOMEM);
1192 
1193 	err = 0;
1194 	clnt = fid->clnt;
1195 
1196 	req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid);
1197 	if (IS_ERR(req)) {
1198 		err = PTR_ERR(req);
1199 		goto error;
1200 	}
1201 
1202 	err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret);
1203 	if (err) {
1204 		p9pdu_dump(1, req->rc);
1205 		p9_free_req(clnt, req);
1206 		goto error;
1207 	}
1208 
1209 	P9_DPRINTK(P9_DEBUG_9P,
1210 		"<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
1211 		"<<<    mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
1212 		"<<<    name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
1213 		"<<<    uid=%d gid=%d n_muid=%d\n",
1214 		ret->size, ret->type, ret->dev, ret->qid.type,
1215 		(unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
1216 		ret->atime, ret->mtime, (unsigned long long)ret->length,
1217 		ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
1218 		ret->n_uid, ret->n_gid, ret->n_muid);
1219 
1220 	p9_free_req(clnt, req);
1221 	return ret;
1222 
1223 error:
1224 	kfree(ret);
1225 	return ERR_PTR(err);
1226 }
1227 EXPORT_SYMBOL(p9_client_stat);
1228 
1229 static int p9_client_statsize(struct p9_wstat *wst, int optional)
1230 {
1231 	int ret;
1232 
1233 	/* NOTE: size shouldn't include its own length */
1234 	/* size[2] type[2] dev[4] qid[13] */
1235 	/* mode[4] atime[4] mtime[4] length[8]*/
1236 	/* name[s] uid[s] gid[s] muid[s] */
1237 	ret = 2+4+13+4+4+4+8+2+2+2+2;
1238 
1239 	if (wst->name)
1240 		ret += strlen(wst->name);
1241 	if (wst->uid)
1242 		ret += strlen(wst->uid);
1243 	if (wst->gid)
1244 		ret += strlen(wst->gid);
1245 	if (wst->muid)
1246 		ret += strlen(wst->muid);
1247 
1248 	if (optional) {
1249 		ret += 2+4+4+4;	/* extension[s] n_uid[4] n_gid[4] n_muid[4] */
1250 		if (wst->extension)
1251 			ret += strlen(wst->extension);
1252 	}
1253 
1254 	return ret;
1255 }
1256 
1257 int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
1258 {
1259 	int err;
1260 	struct p9_req_t *req;
1261 	struct p9_client *clnt;
1262 
1263 	err = 0;
1264 	clnt = fid->clnt;
1265 	wst->size = p9_client_statsize(wst, clnt->dotu);
1266 	P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
1267 	P9_DPRINTK(P9_DEBUG_9P,
1268 		"     sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
1269 		"     mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
1270 		"     name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
1271 		"     uid=%d gid=%d n_muid=%d\n",
1272 		wst->size, wst->type, wst->dev, wst->qid.type,
1273 		(unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
1274 		wst->atime, wst->mtime, (unsigned long long)wst->length,
1275 		wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
1276 		wst->n_uid, wst->n_gid, wst->n_muid);
1277 
1278 	req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
1279 	if (IS_ERR(req)) {
1280 		err = PTR_ERR(req);
1281 		goto error;
1282 	}
1283 
1284 	P9_DPRINTK(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
1285 
1286 	p9_free_req(clnt, req);
1287 error:
1288 	return err;
1289 }
1290 EXPORT_SYMBOL(p9_client_wstat);
1291