]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - net/9p/client.c
fs/9p: Cleanup option parsing in 9p
[karo-tx-linux.git] / net / 9p / client.c
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/slab.h>
33 #include <linux/sched.h>
34 #include <linux/uaccess.h>
35 #include <net/9p/9p.h>
36 #include <linux/parser.h>
37 #include <net/9p/client.h>
38 #include <net/9p/transport.h>
39 #include "protocol.h"
40
41 /*
42   * Client Option Parsing (code inspired by NFS code)
43   *  - a little lazy - parse all client options
44   */
45
46 enum {
47         Opt_msize,
48         Opt_trans,
49         Opt_legacy,
50         Opt_version,
51         Opt_err,
52 };
53
54 static const match_table_t tokens = {
55         {Opt_msize, "msize=%u"},
56         {Opt_legacy, "noextend"},
57         {Opt_trans, "trans=%s"},
58         {Opt_version, "version=%s"},
59         {Opt_err, NULL},
60 };
61
62 inline int p9_is_proto_dotl(struct p9_client *clnt)
63 {
64         return clnt->proto_version == p9_proto_2000L;
65 }
66 EXPORT_SYMBOL(p9_is_proto_dotl);
67
68 inline int p9_is_proto_dotu(struct p9_client *clnt)
69 {
70         return clnt->proto_version == p9_proto_2000u;
71 }
72 EXPORT_SYMBOL(p9_is_proto_dotu);
73
74 /* Interpret mount option for protocol version */
75 static int get_protocol_version(char *s)
76 {
77         int version = -EINVAL;
78
79         if (!strcmp(s, "9p2000")) {
80                 version = p9_proto_legacy;
81                 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n");
82         } else if (!strcmp(s, "9p2000.u")) {
83                 version = p9_proto_2000u;
84                 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n");
85         } else if (!strcmp(s, "9p2000.L")) {
86                 version = p9_proto_2000L;
87                 P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n");
88         } else
89                 printk(KERN_INFO "9p: Unknown protocol version %s.\n", s);
90
91         return version;
92 }
93
94 /**
95  * parse_options - parse mount options into client structure
96  * @opts: options string passed from mount
97  * @clnt: existing v9fs client information
98  *
99  * Return 0 upon success, -ERRNO upon failure
100  */
101
102 static int parse_opts(char *opts, struct p9_client *clnt)
103 {
104         char *options, *tmp_options;
105         char *p;
106         substring_t args[MAX_OPT_ARGS];
107         int option;
108         char *s;
109         int ret = 0;
110
111         clnt->proto_version = p9_proto_2000u;
112         clnt->msize = 8192;
113
114         if (!opts)
115                 return 0;
116
117         tmp_options = kstrdup(opts, GFP_KERNEL);
118         if (!tmp_options) {
119                 P9_DPRINTK(P9_DEBUG_ERROR,
120                                 "failed to allocate copy of option string\n");
121                 return -ENOMEM;
122         }
123         options = tmp_options;
124
125         while ((p = strsep(&options, ",")) != NULL) {
126                 int token, r;
127                 if (!*p)
128                         continue;
129                 token = match_token(p, tokens, args);
130                 switch (token) {
131                 case Opt_msize:
132                         r = match_int(&args[0], &option);
133                         if (r < 0) {
134                                 P9_DPRINTK(P9_DEBUG_ERROR,
135                                            "integer field, but no integer?\n");
136                                 ret = r;
137                                 continue;
138                         }
139                         clnt->msize = option;
140                         break;
141                 case Opt_trans:
142                         s = match_strdup(&args[0]);
143                         if (!s) {
144                                 ret = -ENOMEM;
145                                 P9_DPRINTK(P9_DEBUG_ERROR,
146                                         "problem allocating copy of trans arg\n");
147                                 goto free_and_return;
148                          }
149                         clnt->trans_mod = v9fs_get_trans_by_name(s);
150                         if (clnt->trans_mod == NULL) {
151                                 printk(KERN_INFO
152                                         "9p: Could not find "
153                                         "request transport: %s\n", s);
154                                 ret = -EINVAL;
155                                 kfree(s);
156                                 goto free_and_return;
157                         }
158                         kfree(s);
159                         break;
160                 case Opt_legacy:
161                         clnt->proto_version = p9_proto_legacy;
162                         break;
163                 case Opt_version:
164                         s = match_strdup(&args[0]);
165                         if (!s) {
166                                 ret = -ENOMEM;
167                                 P9_DPRINTK(P9_DEBUG_ERROR,
168                                         "problem allocating copy of version arg\n");
169                                 goto free_and_return;
170                         }
171                         ret = get_protocol_version(s);
172                         if (ret == -EINVAL) {
173                                 kfree(s);
174                                 goto free_and_return;
175                         }
176                         kfree(s);
177                         clnt->proto_version = ret;
178                         break;
179                 default:
180                         continue;
181                 }
182         }
183
184 free_and_return:
185         kfree(tmp_options);
186         return ret;
187 }
188
189 /**
190  * p9_tag_alloc - lookup/allocate a request by tag
191  * @c: client session to lookup tag within
192  * @tag: numeric id for transaction
193  *
194  * this is a simple array lookup, but will grow the
195  * request_slots as necessary to accommodate transaction
196  * ids which did not previously have a slot.
197  *
198  * this code relies on the client spinlock to manage locks, its
199  * possible we should switch to something else, but I'd rather
200  * stick with something low-overhead for the common case.
201  *
202  */
203
204 static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag, int max_size)
205 {
206         unsigned long flags;
207         int row, col;
208         struct p9_req_t *req;
209         int alloc_msize = min(c->msize, max_size);
210
211         /* This looks up the original request by tag so we know which
212          * buffer to read the data into */
213         tag++;
214
215         if (tag >= c->max_tag) {
216                 spin_lock_irqsave(&c->lock, flags);
217                 /* check again since original check was outside of lock */
218                 while (tag >= c->max_tag) {
219                         row = (tag / P9_ROW_MAXTAG);
220                         c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
221                                         sizeof(struct p9_req_t), GFP_ATOMIC);
222
223                         if (!c->reqs[row]) {
224                                 printk(KERN_ERR "Couldn't grow tag array\n");
225                                 spin_unlock_irqrestore(&c->lock, flags);
226                                 return ERR_PTR(-ENOMEM);
227                         }
228                         for (col = 0; col < P9_ROW_MAXTAG; col++) {
229                                 c->reqs[row][col].status = REQ_STATUS_IDLE;
230                                 c->reqs[row][col].tc = NULL;
231                         }
232                         c->max_tag += P9_ROW_MAXTAG;
233                 }
234                 spin_unlock_irqrestore(&c->lock, flags);
235         }
236         row = tag / P9_ROW_MAXTAG;
237         col = tag % P9_ROW_MAXTAG;
238
239         req = &c->reqs[row][col];
240         if (!req->tc) {
241                 req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_NOFS);
242                 if (!req->wq) {
243                         printk(KERN_ERR "Couldn't grow tag array\n");
244                         return ERR_PTR(-ENOMEM);
245                 }
246                 init_waitqueue_head(req->wq);
247                 req->tc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
248                                   GFP_NOFS);
249                 req->rc = kmalloc(sizeof(struct p9_fcall) + alloc_msize,
250                                   GFP_NOFS);
251                 if ((!req->tc) || (!req->rc)) {
252                         printk(KERN_ERR "Couldn't grow tag array\n");
253                         kfree(req->tc);
254                         kfree(req->rc);
255                         kfree(req->wq);
256                         req->tc = req->rc = NULL;
257                         req->wq = NULL;
258                         return ERR_PTR(-ENOMEM);
259                 }
260                 req->tc->capacity = alloc_msize;
261                 req->rc->capacity = alloc_msize;
262                 req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
263                 req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
264         }
265
266         p9pdu_reset(req->tc);
267         p9pdu_reset(req->rc);
268
269         req->tc->tag = tag-1;
270         req->status = REQ_STATUS_ALLOC;
271
272         return &c->reqs[row][col];
273 }
274
275 /**
276  * p9_tag_lookup - lookup a request by tag
277  * @c: client session to lookup tag within
278  * @tag: numeric id for transaction
279  *
280  */
281
282 struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
283 {
284         int row, col;
285
286         /* This looks up the original request by tag so we know which
287          * buffer to read the data into */
288         tag++;
289
290         if(tag >= c->max_tag) 
291                 return NULL;
292
293         row = tag / P9_ROW_MAXTAG;
294         col = tag % P9_ROW_MAXTAG;
295
296         return &c->reqs[row][col];
297 }
298 EXPORT_SYMBOL(p9_tag_lookup);
299
300 /**
301  * p9_tag_init - setup tags structure and contents
302  * @c:  v9fs client struct
303  *
304  * This initializes the tags structure for each client instance.
305  *
306  */
307
308 static int p9_tag_init(struct p9_client *c)
309 {
310         int err = 0;
311
312         c->tagpool = p9_idpool_create();
313         if (IS_ERR(c->tagpool)) {
314                 err = PTR_ERR(c->tagpool);
315                 goto error;
316         }
317         err = p9_idpool_get(c->tagpool); /* reserve tag 0 */
318         if (err < 0) {
319                 p9_idpool_destroy(c->tagpool);
320                 goto error;
321         }
322         c->max_tag = 0;
323 error:
324         return err;
325 }
326
327 /**
328  * p9_tag_cleanup - cleans up tags structure and reclaims resources
329  * @c:  v9fs client struct
330  *
331  * This frees resources associated with the tags structure
332  *
333  */
334 static void p9_tag_cleanup(struct p9_client *c)
335 {
336         int row, col;
337
338         /* check to insure all requests are idle */
339         for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
340                 for (col = 0; col < P9_ROW_MAXTAG; col++) {
341                         if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
342                                 P9_DPRINTK(P9_DEBUG_MUX,
343                                   "Attempting to cleanup non-free tag %d,%d\n",
344                                   row, col);
345                                 /* TODO: delay execution of cleanup */
346                                 return;
347                         }
348                 }
349         }
350
351         if (c->tagpool) {
352                 p9_idpool_put(0, c->tagpool); /* free reserved tag 0 */
353                 p9_idpool_destroy(c->tagpool);
354         }
355
356         /* free requests associated with tags */
357         for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
358                 for (col = 0; col < P9_ROW_MAXTAG; col++) {
359                         kfree(c->reqs[row][col].wq);
360                         kfree(c->reqs[row][col].tc);
361                         kfree(c->reqs[row][col].rc);
362                 }
363                 kfree(c->reqs[row]);
364         }
365         c->max_tag = 0;
366 }
367
368 /**
369  * p9_free_req - free a request and clean-up as necessary
370  * c: client state
371  * r: request to release
372  *
373  */
374
375 static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
376 {
377         int tag = r->tc->tag;
378         P9_DPRINTK(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
379
380         r->status = REQ_STATUS_IDLE;
381         if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
382                 p9_idpool_put(tag, c->tagpool);
383 }
384
385 /**
386  * p9_client_cb - call back from transport to client
387  * c: client state
388  * req: request received
389  *
390  */
391 void p9_client_cb(struct p9_client *c, struct p9_req_t *req)
392 {
393         P9_DPRINTK(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
394         wake_up(req->wq);
395         P9_DPRINTK(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
396 }
397 EXPORT_SYMBOL(p9_client_cb);
398
399 /**
400  * p9_parse_header - parse header arguments out of a packet
401  * @pdu: packet to parse
402  * @size: size of packet
403  * @type: type of request
404  * @tag: tag of packet
405  * @rewind: set if we need to rewind offset afterwards
406  */
407
408 int
409 p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
410                                                                 int rewind)
411 {
412         int8_t r_type;
413         int16_t r_tag;
414         int32_t r_size;
415         int offset = pdu->offset;
416         int err;
417
418         pdu->offset = 0;
419         if (pdu->size == 0)
420                 pdu->size = 7;
421
422         err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag);
423         if (err)
424                 goto rewind_and_exit;
425
426         pdu->size = r_size;
427         pdu->id = r_type;
428         pdu->tag = r_tag;
429
430         P9_DPRINTK(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n", pdu->size,
431                                                         pdu->id, pdu->tag);
432
433         if (type)
434                 *type = r_type;
435         if (tag)
436                 *tag = r_tag;
437         if (size)
438                 *size = r_size;
439
440
441 rewind_and_exit:
442         if (rewind)
443                 pdu->offset = offset;
444         return err;
445 }
446 EXPORT_SYMBOL(p9_parse_header);
447
448 /**
449  * p9_check_errors - check 9p packet for error return and process it
450  * @c: current client instance
451  * @req: request to parse and check for error conditions
452  *
453  * returns error code if one is discovered, otherwise returns 0
454  *
455  * this will have to be more complicated if we have multiple
456  * error packet types
457  */
458
459 static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
460 {
461         int8_t type;
462         int err;
463         int ecode;
464
465         err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
466         if (err) {
467                 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
468                 return err;
469         }
470
471         if (type != P9_RERROR && type != P9_RLERROR)
472                 return 0;
473
474         if (!p9_is_proto_dotl(c)) {
475                 char *ename;
476                 err = p9pdu_readf(req->rc, c->proto_version, "s?d",
477                                   &ename, &ecode);
478                 if (err)
479                         goto out_err;
480
481                 if (p9_is_proto_dotu(c))
482                         err = -ecode;
483
484                 if (!err || !IS_ERR_VALUE(err)) {
485                         err = p9_errstr2errno(ename, strlen(ename));
486
487                         P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
488                                    -ecode, ename);
489                 }
490                 kfree(ename);
491         } else {
492                 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
493                 err = -ecode;
494
495                 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
496         }
497
498         return err;
499
500 out_err:
501         P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
502
503         return err;
504 }
505
506 /**
507  * p9_check_zc_errors - check 9p packet for error return and process it
508  * @c: current client instance
509  * @req: request to parse and check for error conditions
510  * @in_hdrlen: Size of response protocol buffer.
511  *
512  * returns error code if one is discovered, otherwise returns 0
513  *
514  * this will have to be more complicated if we have multiple
515  * error packet types
516  */
517
518 static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req,
519                               char *uidata, int in_hdrlen, int kern_buf)
520 {
521         int err;
522         int ecode;
523         int8_t type;
524         char *ename = NULL;
525
526         err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
527         if (err) {
528                 P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
529                 return err;
530         }
531
532         if (type != P9_RERROR && type != P9_RLERROR)
533                 return 0;
534
535         if (!p9_is_proto_dotl(c)) {
536                 /* Error is reported in string format */
537                 uint16_t len;
538                 /* 7 = header size for RERROR, 2 is the size of string len; */
539                 int inline_len = in_hdrlen - (7 + 2);
540
541                 /* Read the size of error string */
542                 err = p9pdu_readf(req->rc, c->proto_version, "w", &len);
543                 if (err)
544                         goto out_err;
545
546                 ename = kmalloc(len + 1, GFP_NOFS);
547                 if (!ename) {
548                         err = -ENOMEM;
549                         goto out_err;
550                 }
551                 if (len <= inline_len) {
552                         /* We have error in protocol buffer itself */
553                         if (pdu_read(req->rc, ename, len)) {
554                                 err = -EFAULT;
555                                 goto out_free;
556
557                         }
558                 } else {
559                         /*
560                          *  Part of the data is in user space buffer.
561                          */
562                         if (pdu_read(req->rc, ename, inline_len)) {
563                                 err = -EFAULT;
564                                 goto out_free;
565
566                         }
567                         if (kern_buf) {
568                                 memcpy(ename + inline_len, uidata,
569                                        len - inline_len);
570                         } else {
571                                 err = copy_from_user(ename + inline_len,
572                                                      uidata, len - inline_len);
573                                 if (err) {
574                                         err = -EFAULT;
575                                         goto out_free;
576                                 }
577                         }
578                 }
579                 ename[len] = 0;
580                 if (p9_is_proto_dotu(c)) {
581                         /* For dotu we also have error code */
582                         err = p9pdu_readf(req->rc,
583                                           c->proto_version, "d", &ecode);
584                         if (err)
585                                 goto out_free;
586                         err = -ecode;
587                 }
588                 if (!err || !IS_ERR_VALUE(err)) {
589                         err = p9_errstr2errno(ename, strlen(ename));
590
591                         P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n",
592                                    -ecode, ename);
593                 }
594                 kfree(ename);
595         } else {
596                 err = p9pdu_readf(req->rc, c->proto_version, "d", &ecode);
597                 err = -ecode;
598
599                 P9_DPRINTK(P9_DEBUG_9P, "<<< RLERROR (%d)\n", -ecode);
600         }
601         return err;
602
603 out_free:
604         kfree(ename);
605 out_err:
606         P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", err);
607         return err;
608 }
609
610 static struct p9_req_t *
611 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
612
613 /**
614  * p9_client_flush - flush (cancel) a request
615  * @c: client state
616  * @oldreq: request to cancel
617  *
618  * This sents a flush for a particular request and links
619  * the flush request to the original request.  The current
620  * code only supports a single flush request although the protocol
621  * allows for multiple flush requests to be sent for a single request.
622  *
623  */
624
625 static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
626 {
627         struct p9_req_t *req;
628         int16_t oldtag;
629         int err;
630
631         err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1);
632         if (err)
633                 return err;
634
635         P9_DPRINTK(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag);
636
637         req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag);
638         if (IS_ERR(req))
639                 return PTR_ERR(req);
640
641
642         /* if we haven't received a response for oldreq,
643            remove it from the list. */
644         spin_lock(&c->lock);
645         if (oldreq->status == REQ_STATUS_FLSH)
646                 list_del(&oldreq->req_list);
647         spin_unlock(&c->lock);
648
649         p9_free_req(c, req);
650         return 0;
651 }
652
653 static struct p9_req_t *p9_client_prepare_req(struct p9_client *c,
654                                               int8_t type, int req_size,
655                                               const char *fmt, va_list ap)
656 {
657         int tag, err;
658         struct p9_req_t *req;
659
660         P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
661
662         /* we allow for any status other than disconnected */
663         if (c->status == Disconnected)
664                 return ERR_PTR(-EIO);
665
666         /* if status is begin_disconnected we allow only clunk request */
667         if ((c->status == BeginDisconnect) && (type != P9_TCLUNK))
668                 return ERR_PTR(-EIO);
669
670         tag = P9_NOTAG;
671         if (type != P9_TVERSION) {
672                 tag = p9_idpool_get(c->tagpool);
673                 if (tag < 0)
674                         return ERR_PTR(-ENOMEM);
675         }
676
677         req = p9_tag_alloc(c, tag, req_size);
678         if (IS_ERR(req))
679                 return req;
680
681         /* marshall the data */
682         p9pdu_prepare(req->tc, tag, type);
683         err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap);
684         if (err)
685                 goto reterr;
686         p9pdu_finalize(req->tc);
687         return req;
688 reterr:
689         p9_free_req(c, req);
690         return ERR_PTR(err);
691 }
692
693 /**
694  * p9_client_rpc - issue a request and wait for a response
695  * @c: client session
696  * @type: type of request
697  * @fmt: protocol format string (see protocol.c)
698  *
699  * Returns request structure (which client must free using p9_free_req)
700  */
701
702 static struct p9_req_t *
703 p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
704 {
705         va_list ap;
706         int sigpending, err;
707         unsigned long flags;
708         struct p9_req_t *req;
709
710         va_start(ap, fmt);
711         req = p9_client_prepare_req(c, type, c->msize, fmt, ap);
712         va_end(ap);
713         if (IS_ERR(req))
714                 return req;
715
716         if (signal_pending(current)) {
717                 sigpending = 1;
718                 clear_thread_flag(TIF_SIGPENDING);
719         } else
720                 sigpending = 0;
721
722         err = c->trans_mod->request(c, req);
723         if (err < 0) {
724                 if (err != -ERESTARTSYS && err != -EFAULT)
725                         c->status = Disconnected;
726                 goto reterr;
727         }
728         /* Wait for the response */
729         err = wait_event_interruptible(*req->wq,
730                                        req->status >= REQ_STATUS_RCVD);
731
732         if (req->status == REQ_STATUS_ERROR) {
733                 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
734                 err = req->t_err;
735         }
736         if ((err == -ERESTARTSYS) && (c->status == Connected)) {
737                 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
738                 sigpending = 1;
739                 clear_thread_flag(TIF_SIGPENDING);
740
741                 if (c->trans_mod->cancel(c, req))
742                         p9_client_flush(c, req);
743
744                 /* if we received the response anyway, don't signal error */
745                 if (req->status == REQ_STATUS_RCVD)
746                         err = 0;
747         }
748         if (sigpending) {
749                 spin_lock_irqsave(&current->sighand->siglock, flags);
750                 recalc_sigpending();
751                 spin_unlock_irqrestore(&current->sighand->siglock, flags);
752         }
753         if (err < 0)
754                 goto reterr;
755
756         err = p9_check_errors(c, req);
757         if (!err) {
758                 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
759                 return req;
760         }
761 reterr:
762         P9_DPRINTK(P9_DEBUG_MUX,
763                    "exit: client %p op %d error: %d\n", c, type, err);
764         p9_free_req(c, req);
765         return ERR_PTR(err);
766 }
767
768 /**
769  * p9_client_zc_rpc - issue a request and wait for a response
770  * @c: client session
771  * @type: type of request
772  * @uidata: user bffer that should be ued for zero copy read
773  * @uodata: user buffer that shoud be user for zero copy write
774  * @inlen: read buffer size
775  * @olen: write buffer size
776  * @hdrlen: reader header size, This is the size of response protocol data
777  * @fmt: protocol format string (see protocol.c)
778  *
779  * Returns request structure (which client must free using p9_free_req)
780  */
781 static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
782                                          char *uidata, char *uodata,
783                                          int inlen, int olen, int in_hdrlen,
784                                          int kern_buf, const char *fmt, ...)
785 {
786         va_list ap;
787         int sigpending, err;
788         unsigned long flags;
789         struct p9_req_t *req;
790
791         va_start(ap, fmt);
792         /*
793          * We allocate a inline protocol data of only 4k bytes.
794          * The actual content is passed in zero-copy fashion.
795          */
796         req = p9_client_prepare_req(c, type, P9_ZC_HDR_SZ, fmt, ap);
797         va_end(ap);
798         if (IS_ERR(req))
799                 return req;
800
801         if (signal_pending(current)) {
802                 sigpending = 1;
803                 clear_thread_flag(TIF_SIGPENDING);
804         } else
805                 sigpending = 0;
806
807         /* If we are called with KERNEL_DS force kern_buf */
808         if (segment_eq(get_fs(), KERNEL_DS))
809                 kern_buf = 1;
810
811         err = c->trans_mod->zc_request(c, req, uidata, uodata,
812                                        inlen, olen, in_hdrlen, kern_buf);
813         if (err < 0) {
814                 if (err == -EIO)
815                         c->status = Disconnected;
816                 goto reterr;
817         }
818         if (req->status == REQ_STATUS_ERROR) {
819                 P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
820                 err = req->t_err;
821         }
822         if ((err == -ERESTARTSYS) && (c->status == Connected)) {
823                 P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
824                 sigpending = 1;
825                 clear_thread_flag(TIF_SIGPENDING);
826
827                 if (c->trans_mod->cancel(c, req))
828                         p9_client_flush(c, req);
829
830                 /* if we received the response anyway, don't signal error */
831                 if (req->status == REQ_STATUS_RCVD)
832                         err = 0;
833         }
834         if (sigpending) {
835                 spin_lock_irqsave(&current->sighand->siglock, flags);
836                 recalc_sigpending();
837                 spin_unlock_irqrestore(&current->sighand->siglock, flags);
838         }
839         if (err < 0)
840                 goto reterr;
841
842         err = p9_check_zc_errors(c, req, uidata, in_hdrlen, kern_buf);
843         if (!err) {
844                 P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
845                 return req;
846         }
847 reterr:
848         P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
849                                                                         err);
850         p9_free_req(c, req);
851         return ERR_PTR(err);
852 }
853
854 static struct p9_fid *p9_fid_create(struct p9_client *clnt)
855 {
856         int ret;
857         struct p9_fid *fid;
858         unsigned long flags;
859
860         P9_DPRINTK(P9_DEBUG_FID, "clnt %p\n", clnt);
861         fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
862         if (!fid)
863                 return ERR_PTR(-ENOMEM);
864
865         ret = p9_idpool_get(clnt->fidpool);
866         if (ret < 0) {
867                 ret = -ENOSPC;
868                 goto error;
869         }
870         fid->fid = ret;
871
872         memset(&fid->qid, 0, sizeof(struct p9_qid));
873         fid->mode = -1;
874         fid->uid = current_fsuid();
875         fid->clnt = clnt;
876         fid->rdir = NULL;
877         spin_lock_irqsave(&clnt->lock, flags);
878         list_add(&fid->flist, &clnt->fidlist);
879         spin_unlock_irqrestore(&clnt->lock, flags);
880
881         return fid;
882
883 error:
884         kfree(fid);
885         return ERR_PTR(ret);
886 }
887
888 static void p9_fid_destroy(struct p9_fid *fid)
889 {
890         struct p9_client *clnt;
891         unsigned long flags;
892
893         P9_DPRINTK(P9_DEBUG_FID, "fid %d\n", fid->fid);
894         clnt = fid->clnt;
895         p9_idpool_put(fid->fid, clnt->fidpool);
896         spin_lock_irqsave(&clnt->lock, flags);
897         list_del(&fid->flist);
898         spin_unlock_irqrestore(&clnt->lock, flags);
899         kfree(fid->rdir);
900         kfree(fid);
901 }
902
903 static int p9_client_version(struct p9_client *c)
904 {
905         int err = 0;
906         struct p9_req_t *req;
907         char *version;
908         int msize;
909
910         P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d protocol %d\n",
911                                                 c->msize, c->proto_version);
912
913         switch (c->proto_version) {
914         case p9_proto_2000L:
915                 req = p9_client_rpc(c, P9_TVERSION, "ds",
916                                         c->msize, "9P2000.L");
917                 break;
918         case p9_proto_2000u:
919                 req = p9_client_rpc(c, P9_TVERSION, "ds",
920                                         c->msize, "9P2000.u");
921                 break;
922         case p9_proto_legacy:
923                 req = p9_client_rpc(c, P9_TVERSION, "ds",
924                                         c->msize, "9P2000");
925                 break;
926         default:
927                 return -EINVAL;
928                 break;
929         }
930
931         if (IS_ERR(req))
932                 return PTR_ERR(req);
933
934         err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version);
935         if (err) {
936                 P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
937                 P9_DUMP_PKT(1, req->rc);
938                 goto error;
939         }
940
941         P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
942         if (!strncmp(version, "9P2000.L", 8))
943                 c->proto_version = p9_proto_2000L;
944         else if (!strncmp(version, "9P2000.u", 8))
945                 c->proto_version = p9_proto_2000u;
946         else if (!strncmp(version, "9P2000", 6))
947                 c->proto_version = p9_proto_legacy;
948         else {
949                 err = -EREMOTEIO;
950                 goto error;
951         }
952
953         if (msize < c->msize)
954                 c->msize = msize;
955
956 error:
957         kfree(version);
958         p9_free_req(c, req);
959
960         return err;
961 }
962
963 struct p9_client *p9_client_create(const char *dev_name, char *options)
964 {
965         int err;
966         struct p9_client *clnt;
967
968         err = 0;
969         clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
970         if (!clnt)
971                 return ERR_PTR(-ENOMEM);
972
973         clnt->trans_mod = NULL;
974         clnt->trans = NULL;
975         spin_lock_init(&clnt->lock);
976         INIT_LIST_HEAD(&clnt->fidlist);
977
978         err = p9_tag_init(clnt);
979         if (err < 0)
980                 goto free_client;
981
982         err = parse_opts(options, clnt);
983         if (err < 0)
984                 goto destroy_tagpool;
985
986         if (!clnt->trans_mod)
987                 clnt->trans_mod = v9fs_get_default_trans();
988
989         if (clnt->trans_mod == NULL) {
990                 err = -EPROTONOSUPPORT;
991                 P9_DPRINTK(P9_DEBUG_ERROR,
992                                 "No transport defined or default transport\n");
993                 goto destroy_tagpool;
994         }
995
996         clnt->fidpool = p9_idpool_create();
997         if (IS_ERR(clnt->fidpool)) {
998                 err = PTR_ERR(clnt->fidpool);
999                 goto put_trans;
1000         }
1001
1002         P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
1003                 clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
1004
1005         err = clnt->trans_mod->create(clnt, dev_name, options);
1006         if (err)
1007                 goto destroy_fidpool;
1008
1009         if (clnt->msize > clnt->trans_mod->maxsize)
1010                 clnt->msize = clnt->trans_mod->maxsize;
1011
1012         err = p9_client_version(clnt);
1013         if (err)
1014                 goto close_trans;
1015
1016         return clnt;
1017
1018 close_trans:
1019         clnt->trans_mod->close(clnt);
1020 destroy_fidpool:
1021         p9_idpool_destroy(clnt->fidpool);
1022 put_trans:
1023         v9fs_put_trans(clnt->trans_mod);
1024 destroy_tagpool:
1025         p9_idpool_destroy(clnt->tagpool);
1026 free_client:
1027         kfree(clnt);
1028         return ERR_PTR(err);
1029 }
1030 EXPORT_SYMBOL(p9_client_create);
1031
1032 void p9_client_destroy(struct p9_client *clnt)
1033 {
1034         struct p9_fid *fid, *fidptr;
1035
1036         P9_DPRINTK(P9_DEBUG_MUX, "clnt %p\n", clnt);
1037
1038         if (clnt->trans_mod)
1039                 clnt->trans_mod->close(clnt);
1040
1041         v9fs_put_trans(clnt->trans_mod);
1042
1043         list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) {
1044                 printk(KERN_INFO "Found fid %d not clunked\n", fid->fid);
1045                 p9_fid_destroy(fid);
1046         }
1047
1048         if (clnt->fidpool)
1049                 p9_idpool_destroy(clnt->fidpool);
1050
1051         p9_tag_cleanup(clnt);
1052
1053         kfree(clnt);
1054 }
1055 EXPORT_SYMBOL(p9_client_destroy);
1056
1057 void p9_client_disconnect(struct p9_client *clnt)
1058 {
1059         P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
1060         clnt->status = Disconnected;
1061 }
1062 EXPORT_SYMBOL(p9_client_disconnect);
1063
1064 void p9_client_begin_disconnect(struct p9_client *clnt)
1065 {
1066         P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
1067         clnt->status = BeginDisconnect;
1068 }
1069 EXPORT_SYMBOL(p9_client_begin_disconnect);
1070
1071 struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
1072         char *uname, u32 n_uname, char *aname)
1073 {
1074         int err;
1075         struct p9_req_t *req;
1076         struct p9_fid *fid;
1077         struct p9_qid qid;
1078
1079         P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
1080                                         afid ? afid->fid : -1, uname, aname);
1081         err = 0;
1082
1083         fid = p9_fid_create(clnt);
1084         if (IS_ERR(fid)) {
1085                 err = PTR_ERR(fid);
1086                 fid = NULL;
1087                 goto error;
1088         }
1089
1090         req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid,
1091                         afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
1092         if (IS_ERR(req)) {
1093                 err = PTR_ERR(req);
1094                 goto error;
1095         }
1096
1097         err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid);
1098         if (err) {
1099                 P9_DUMP_PKT(1, req->rc);
1100                 p9_free_req(clnt, req);
1101                 goto error;
1102         }
1103
1104         P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
1105                                         qid.type,
1106                                         (unsigned long long)qid.path,
1107                                         qid.version);
1108
1109         memmove(&fid->qid, &qid, sizeof(struct p9_qid));
1110
1111         p9_free_req(clnt, req);
1112         return fid;
1113
1114 error:
1115         if (fid)
1116                 p9_fid_destroy(fid);
1117         return ERR_PTR(err);
1118 }
1119 EXPORT_SYMBOL(p9_client_attach);
1120
1121 struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
1122                 char **wnames, int clone)
1123 {
1124         int err;
1125         struct p9_client *clnt;
1126         struct p9_fid *fid;
1127         struct p9_qid *wqids;
1128         struct p9_req_t *req;
1129         uint16_t nwqids, count;
1130
1131         err = 0;
1132         wqids = NULL;
1133         clnt = oldfid->clnt;
1134         if (clone) {
1135                 fid = p9_fid_create(clnt);
1136                 if (IS_ERR(fid)) {
1137                         err = PTR_ERR(fid);
1138                         fid = NULL;
1139                         goto error;
1140                 }
1141
1142                 fid->uid = oldfid->uid;
1143         } else
1144                 fid = oldfid;
1145
1146
1147         P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %ud wname[0] %s\n",
1148                 oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
1149
1150         req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
1151                                                                 nwname, wnames);
1152         if (IS_ERR(req)) {
1153                 err = PTR_ERR(req);
1154                 goto error;
1155         }
1156
1157         err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids);
1158         if (err) {
1159                 P9_DUMP_PKT(1, req->rc);
1160                 p9_free_req(clnt, req);
1161                 goto clunk_fid;
1162         }
1163         p9_free_req(clnt, req);
1164
1165         P9_DPRINTK(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
1166
1167         if (nwqids != nwname) {
1168                 err = -ENOENT;
1169                 goto clunk_fid;
1170         }
1171
1172         for (count = 0; count < nwqids; count++)
1173                 P9_DPRINTK(P9_DEBUG_9P, "<<<     [%d] %x.%llx.%x\n",
1174                         count, wqids[count].type,
1175                         (unsigned long long)wqids[count].path,
1176                         wqids[count].version);
1177
1178         if (nwname)
1179                 memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
1180         else
1181                 fid->qid = oldfid->qid;
1182
1183         kfree(wqids);
1184         return fid;
1185
1186 clunk_fid:
1187         kfree(wqids);
1188         p9_client_clunk(fid);
1189         fid = NULL;
1190
1191 error:
1192         if (fid && (fid != oldfid))
1193                 p9_fid_destroy(fid);
1194
1195         return ERR_PTR(err);
1196 }
1197 EXPORT_SYMBOL(p9_client_walk);
1198
1199 int p9_client_open(struct p9_fid *fid, int mode)
1200 {
1201         int err;
1202         struct p9_client *clnt;
1203         struct p9_req_t *req;
1204         struct p9_qid qid;
1205         int iounit;
1206
1207         clnt = fid->clnt;
1208         P9_DPRINTK(P9_DEBUG_9P, ">>> %s fid %d mode %d\n",
1209                 p9_is_proto_dotl(clnt) ? "TLOPEN" : "TOPEN", fid->fid, mode);
1210         err = 0;
1211
1212         if (fid->mode != -1)
1213                 return -EINVAL;
1214
1215         if (p9_is_proto_dotl(clnt))
1216                 req = p9_client_rpc(clnt, P9_TLOPEN, "dd", fid->fid, mode);
1217         else
1218                 req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
1219         if (IS_ERR(req)) {
1220                 err = PTR_ERR(req);
1221                 goto error;
1222         }
1223
1224         err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1225         if (err) {
1226                 P9_DUMP_PKT(1, req->rc);
1227                 goto free_and_error;
1228         }
1229
1230         P9_DPRINTK(P9_DEBUG_9P, "<<< %s qid %x.%llx.%x iounit %x\n",
1231                 p9_is_proto_dotl(clnt) ? "RLOPEN" : "ROPEN",  qid.type,
1232                 (unsigned long long)qid.path, qid.version, iounit);
1233
1234         fid->mode = mode;
1235         fid->iounit = iounit;
1236
1237 free_and_error:
1238         p9_free_req(clnt, req);
1239 error:
1240         return err;
1241 }
1242 EXPORT_SYMBOL(p9_client_open);
1243
1244 int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
1245                 gid_t gid, struct p9_qid *qid)
1246 {
1247         int err = 0;
1248         struct p9_client *clnt;
1249         struct p9_req_t *req;
1250         int iounit;
1251
1252         P9_DPRINTK(P9_DEBUG_9P,
1253                         ">>> TLCREATE fid %d name %s flags %d mode %d gid %d\n",
1254                         ofid->fid, name, flags, mode, gid);
1255         clnt = ofid->clnt;
1256
1257         if (ofid->mode != -1)
1258                 return -EINVAL;
1259
1260         req = p9_client_rpc(clnt, P9_TLCREATE, "dsddd", ofid->fid, name, flags,
1261                         mode, gid);
1262         if (IS_ERR(req)) {
1263                 err = PTR_ERR(req);
1264                 goto error;
1265         }
1266
1267         err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", qid, &iounit);
1268         if (err) {
1269                 P9_DUMP_PKT(1, req->rc);
1270                 goto free_and_error;
1271         }
1272
1273         P9_DPRINTK(P9_DEBUG_9P, "<<< RLCREATE qid %x.%llx.%x iounit %x\n",
1274                         qid->type,
1275                         (unsigned long long)qid->path,
1276                         qid->version, iounit);
1277
1278         ofid->mode = mode;
1279         ofid->iounit = iounit;
1280
1281 free_and_error:
1282         p9_free_req(clnt, req);
1283 error:
1284         return err;
1285 }
1286 EXPORT_SYMBOL(p9_client_create_dotl);
1287
1288 int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
1289                      char *extension)
1290 {
1291         int err;
1292         struct p9_client *clnt;
1293         struct p9_req_t *req;
1294         struct p9_qid qid;
1295         int iounit;
1296
1297         P9_DPRINTK(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
1298                                                 fid->fid, name, perm, mode);
1299         err = 0;
1300         clnt = fid->clnt;
1301
1302         if (fid->mode != -1)
1303                 return -EINVAL;
1304
1305         req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
1306                                 mode, extension);
1307         if (IS_ERR(req)) {
1308                 err = PTR_ERR(req);
1309                 goto error;
1310         }
1311
1312         err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit);
1313         if (err) {
1314                 P9_DUMP_PKT(1, req->rc);
1315                 goto free_and_error;
1316         }
1317
1318         P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
1319                                 qid.type,
1320                                 (unsigned long long)qid.path,
1321                                 qid.version, iounit);
1322
1323         fid->mode = mode;
1324         fid->iounit = iounit;
1325
1326 free_and_error:
1327         p9_free_req(clnt, req);
1328 error:
1329         return err;
1330 }
1331 EXPORT_SYMBOL(p9_client_fcreate);
1332
1333 int p9_client_symlink(struct p9_fid *dfid, char *name, char *symtgt, gid_t gid,
1334                 struct p9_qid *qid)
1335 {
1336         int err = 0;
1337         struct p9_client *clnt;
1338         struct p9_req_t *req;
1339
1340         P9_DPRINTK(P9_DEBUG_9P, ">>> TSYMLINK dfid %d name %s  symtgt %s\n",
1341                         dfid->fid, name, symtgt);
1342         clnt = dfid->clnt;
1343
1344         req = p9_client_rpc(clnt, P9_TSYMLINK, "dssd", dfid->fid, name, symtgt,
1345                         gid);
1346         if (IS_ERR(req)) {
1347                 err = PTR_ERR(req);
1348                 goto error;
1349         }
1350
1351         err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1352         if (err) {
1353                 P9_DUMP_PKT(1, req->rc);
1354                 goto free_and_error;
1355         }
1356
1357         P9_DPRINTK(P9_DEBUG_9P, "<<< RSYMLINK qid %x.%llx.%x\n",
1358                         qid->type, (unsigned long long)qid->path, qid->version);
1359
1360 free_and_error:
1361         p9_free_req(clnt, req);
1362 error:
1363         return err;
1364 }
1365 EXPORT_SYMBOL(p9_client_symlink);
1366
1367 int p9_client_link(struct p9_fid *dfid, struct p9_fid *oldfid, char *newname)
1368 {
1369         struct p9_client *clnt;
1370         struct p9_req_t *req;
1371
1372         P9_DPRINTK(P9_DEBUG_9P, ">>> TLINK dfid %d oldfid %d newname %s\n",
1373                         dfid->fid, oldfid->fid, newname);
1374         clnt = dfid->clnt;
1375         req = p9_client_rpc(clnt, P9_TLINK, "dds", dfid->fid, oldfid->fid,
1376                         newname);
1377         if (IS_ERR(req))
1378                 return PTR_ERR(req);
1379
1380         P9_DPRINTK(P9_DEBUG_9P, "<<< RLINK\n");
1381         p9_free_req(clnt, req);
1382         return 0;
1383 }
1384 EXPORT_SYMBOL(p9_client_link);
1385
1386 int p9_client_fsync(struct p9_fid *fid, int datasync)
1387 {
1388         int err;
1389         struct p9_client *clnt;
1390         struct p9_req_t *req;
1391
1392         P9_DPRINTK(P9_DEBUG_9P, ">>> TFSYNC fid %d datasync:%d\n",
1393                         fid->fid, datasync);
1394         err = 0;
1395         clnt = fid->clnt;
1396
1397         req = p9_client_rpc(clnt, P9_TFSYNC, "dd", fid->fid, datasync);
1398         if (IS_ERR(req)) {
1399                 err = PTR_ERR(req);
1400                 goto error;
1401         }
1402
1403         P9_DPRINTK(P9_DEBUG_9P, "<<< RFSYNC fid %d\n", fid->fid);
1404
1405         p9_free_req(clnt, req);
1406
1407 error:
1408         return err;
1409 }
1410 EXPORT_SYMBOL(p9_client_fsync);
1411
1412 int p9_client_clunk(struct p9_fid *fid)
1413 {
1414         int err;
1415         struct p9_client *clnt;
1416         struct p9_req_t *req;
1417
1418         if (!fid) {
1419                 P9_EPRINTK(KERN_WARNING, "Trying to clunk with NULL fid\n");
1420                 dump_stack();
1421                 return 0;
1422         }
1423
1424         P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
1425         err = 0;
1426         clnt = fid->clnt;
1427
1428         req = p9_client_rpc(clnt, P9_TCLUNK, "d", fid->fid);
1429         if (IS_ERR(req)) {
1430                 err = PTR_ERR(req);
1431                 goto error;
1432         }
1433
1434         P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
1435
1436         p9_free_req(clnt, req);
1437 error:
1438         /*
1439          * Fid is not valid even after a failed clunk
1440          */
1441         p9_fid_destroy(fid);
1442         return err;
1443 }
1444 EXPORT_SYMBOL(p9_client_clunk);
1445
1446 int p9_client_remove(struct p9_fid *fid)
1447 {
1448         int err;
1449         struct p9_client *clnt;
1450         struct p9_req_t *req;
1451
1452         P9_DPRINTK(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid);
1453         err = 0;
1454         clnt = fid->clnt;
1455
1456         req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid);
1457         if (IS_ERR(req)) {
1458                 err = PTR_ERR(req);
1459                 goto error;
1460         }
1461
1462         P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
1463
1464         p9_free_req(clnt, req);
1465 error:
1466         p9_fid_destroy(fid);
1467         return err;
1468 }
1469 EXPORT_SYMBOL(p9_client_remove);
1470
1471 int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
1472 {
1473         int err = 0;
1474         struct p9_req_t *req;
1475         struct p9_client *clnt;
1476
1477         P9_DPRINTK(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
1478                    dfid->fid, name, flags);
1479
1480         clnt = dfid->clnt;
1481         req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
1482         if (IS_ERR(req)) {
1483                 err = PTR_ERR(req);
1484                 goto error;
1485         }
1486         P9_DPRINTK(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
1487
1488         p9_free_req(clnt, req);
1489 error:
1490         return err;
1491 }
1492 EXPORT_SYMBOL(p9_client_unlinkat);
1493
1494 int
1495 p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
1496                                                                 u32 count)
1497 {
1498         char *dataptr;
1499         int kernel_buf = 0;
1500         struct p9_req_t *req;
1501         struct p9_client *clnt;
1502         int err, rsize, non_zc = 0;
1503
1504
1505         P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n",
1506                    fid->fid, (long long unsigned) offset, count);
1507         err = 0;
1508         clnt = fid->clnt;
1509
1510         rsize = fid->iounit;
1511         if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1512                 rsize = clnt->msize - P9_IOHDRSZ;
1513
1514         if (count < rsize)
1515                 rsize = count;
1516
1517         /* Don't bother zerocopy for small IO (< 1024) */
1518         if (clnt->trans_mod->zc_request && rsize > 1024) {
1519                 char *indata;
1520                 if (data) {
1521                         kernel_buf = 1;
1522                         indata = data;
1523                 } else
1524                         indata = (char *)udata;
1525                 /*
1526                  * response header len is 11
1527                  * PDU Header(7) + IO Size (4)
1528                  */
1529                 req = p9_client_zc_rpc(clnt, P9_TREAD, indata, NULL, rsize, 0,
1530                                        11, kernel_buf, "dqd", fid->fid,
1531                                        offset, rsize);
1532         } else {
1533                 non_zc = 1;
1534                 req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset,
1535                                     rsize);
1536         }
1537         if (IS_ERR(req)) {
1538                 err = PTR_ERR(req);
1539                 goto error;
1540         }
1541
1542         err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
1543         if (err) {
1544                 P9_DUMP_PKT(1, req->rc);
1545                 goto free_and_error;
1546         }
1547
1548         P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
1549         P9_DUMP_PKT(1, req->rc);
1550
1551         if (non_zc) {
1552                 if (data) {
1553                         memmove(data, dataptr, count);
1554                 } else {
1555                         err = copy_to_user(udata, dataptr, count);
1556                         if (err) {
1557                                 err = -EFAULT;
1558                                 goto free_and_error;
1559                         }
1560                 }
1561         }
1562         p9_free_req(clnt, req);
1563         return count;
1564
1565 free_and_error:
1566         p9_free_req(clnt, req);
1567 error:
1568         return err;
1569 }
1570 EXPORT_SYMBOL(p9_client_read);
1571
1572 int
1573 p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
1574                                                         u64 offset, u32 count)
1575 {
1576         int err, rsize;
1577         int kernel_buf = 0;
1578         struct p9_client *clnt;
1579         struct p9_req_t *req;
1580
1581         P9_DPRINTK(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n",
1582                                 fid->fid, (long long unsigned) offset, count);
1583         err = 0;
1584         clnt = fid->clnt;
1585
1586         rsize = fid->iounit;
1587         if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1588                 rsize = clnt->msize - P9_IOHDRSZ;
1589
1590         if (count < rsize)
1591                 rsize = count;
1592
1593         /* Don't bother zerocopy for small IO (< 1024) */
1594         if (clnt->trans_mod->zc_request && rsize > 1024) {
1595                 char *odata;
1596                 if (data) {
1597                         kernel_buf = 1;
1598                         odata = data;
1599                 } else
1600                         odata = (char *)udata;
1601                 req = p9_client_zc_rpc(clnt, P9_TWRITE, NULL, odata, 0, rsize,
1602                                        P9_ZC_HDR_SZ, kernel_buf, "dqd",
1603                                        fid->fid, offset, rsize);
1604         } else {
1605                 if (data)
1606                         req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid,
1607                                             offset, rsize, data);
1608                 else
1609                         req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid,
1610                                             offset, rsize, udata);
1611         }
1612         if (IS_ERR(req)) {
1613                 err = PTR_ERR(req);
1614                 goto error;
1615         }
1616
1617         err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count);
1618         if (err) {
1619                 P9_DUMP_PKT(1, req->rc);
1620                 goto free_and_error;
1621         }
1622
1623         P9_DPRINTK(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
1624
1625         p9_free_req(clnt, req);
1626         return count;
1627
1628 free_and_error:
1629         p9_free_req(clnt, req);
1630 error:
1631         return err;
1632 }
1633 EXPORT_SYMBOL(p9_client_write);
1634
1635 struct p9_wstat *p9_client_stat(struct p9_fid *fid)
1636 {
1637         int err;
1638         struct p9_client *clnt;
1639         struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
1640         struct p9_req_t *req;
1641         u16 ignored;
1642
1643         P9_DPRINTK(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
1644
1645         if (!ret)
1646                 return ERR_PTR(-ENOMEM);
1647
1648         err = 0;
1649         clnt = fid->clnt;
1650
1651         req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid);
1652         if (IS_ERR(req)) {
1653                 err = PTR_ERR(req);
1654                 goto error;
1655         }
1656
1657         err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret);
1658         if (err) {
1659                 P9_DUMP_PKT(1, req->rc);
1660                 p9_free_req(clnt, req);
1661                 goto error;
1662         }
1663
1664         P9_DPRINTK(P9_DEBUG_9P,
1665                 "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
1666                 "<<<    mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
1667                 "<<<    name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
1668                 "<<<    uid=%d gid=%d n_muid=%d\n",
1669                 ret->size, ret->type, ret->dev, ret->qid.type,
1670                 (unsigned long long)ret->qid.path, ret->qid.version, ret->mode,
1671                 ret->atime, ret->mtime, (unsigned long long)ret->length,
1672                 ret->name, ret->uid, ret->gid, ret->muid, ret->extension,
1673                 ret->n_uid, ret->n_gid, ret->n_muid);
1674
1675         p9_free_req(clnt, req);
1676         return ret;
1677
1678 error:
1679         kfree(ret);
1680         return ERR_PTR(err);
1681 }
1682 EXPORT_SYMBOL(p9_client_stat);
1683
1684 struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
1685                                                         u64 request_mask)
1686 {
1687         int err;
1688         struct p9_client *clnt;
1689         struct p9_stat_dotl *ret = kmalloc(sizeof(struct p9_stat_dotl),
1690                                                                 GFP_KERNEL);
1691         struct p9_req_t *req;
1692
1693         P9_DPRINTK(P9_DEBUG_9P, ">>> TGETATTR fid %d, request_mask %lld\n",
1694                                                         fid->fid, request_mask);
1695
1696         if (!ret)
1697                 return ERR_PTR(-ENOMEM);
1698
1699         err = 0;
1700         clnt = fid->clnt;
1701
1702         req = p9_client_rpc(clnt, P9_TGETATTR, "dq", fid->fid, request_mask);
1703         if (IS_ERR(req)) {
1704                 err = PTR_ERR(req);
1705                 goto error;
1706         }
1707
1708         err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
1709         if (err) {
1710                 P9_DUMP_PKT(1, req->rc);
1711                 p9_free_req(clnt, req);
1712                 goto error;
1713         }
1714
1715         P9_DPRINTK(P9_DEBUG_9P,
1716                 "<<< RGETATTR st_result_mask=%lld\n"
1717                 "<<< qid=%x.%llx.%x\n"
1718                 "<<< st_mode=%8.8x st_nlink=%llu\n"
1719                 "<<< st_uid=%d st_gid=%d\n"
1720                 "<<< st_rdev=%llx st_size=%llx st_blksize=%llu st_blocks=%llu\n"
1721                 "<<< st_atime_sec=%lld st_atime_nsec=%lld\n"
1722                 "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n"
1723                 "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n"
1724                 "<<< st_btime_sec=%lld st_btime_nsec=%lld\n"
1725                 "<<< st_gen=%lld st_data_version=%lld",
1726                 ret->st_result_mask, ret->qid.type, ret->qid.path,
1727                 ret->qid.version, ret->st_mode, ret->st_nlink, ret->st_uid,
1728                 ret->st_gid, ret->st_rdev, ret->st_size, ret->st_blksize,
1729                 ret->st_blocks, ret->st_atime_sec, ret->st_atime_nsec,
1730                 ret->st_mtime_sec, ret->st_mtime_nsec, ret->st_ctime_sec,
1731                 ret->st_ctime_nsec, ret->st_btime_sec, ret->st_btime_nsec,
1732                 ret->st_gen, ret->st_data_version);
1733
1734         p9_free_req(clnt, req);
1735         return ret;
1736
1737 error:
1738         kfree(ret);
1739         return ERR_PTR(err);
1740 }
1741 EXPORT_SYMBOL(p9_client_getattr_dotl);
1742
1743 static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
1744 {
1745         int ret;
1746
1747         /* NOTE: size shouldn't include its own length */
1748         /* size[2] type[2] dev[4] qid[13] */
1749         /* mode[4] atime[4] mtime[4] length[8]*/
1750         /* name[s] uid[s] gid[s] muid[s] */
1751         ret = 2+4+13+4+4+4+8+2+2+2+2;
1752
1753         if (wst->name)
1754                 ret += strlen(wst->name);
1755         if (wst->uid)
1756                 ret += strlen(wst->uid);
1757         if (wst->gid)
1758                 ret += strlen(wst->gid);
1759         if (wst->muid)
1760                 ret += strlen(wst->muid);
1761
1762         if ((proto_version == p9_proto_2000u) ||
1763                 (proto_version == p9_proto_2000L)) {
1764                 ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */
1765                 if (wst->extension)
1766                         ret += strlen(wst->extension);
1767         }
1768
1769         return ret;
1770 }
1771
1772 int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
1773 {
1774         int err;
1775         struct p9_req_t *req;
1776         struct p9_client *clnt;
1777
1778         err = 0;
1779         clnt = fid->clnt;
1780         wst->size = p9_client_statsize(wst, clnt->proto_version);
1781         P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
1782         P9_DPRINTK(P9_DEBUG_9P,
1783                 "     sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
1784                 "     mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
1785                 "     name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
1786                 "     uid=%d gid=%d n_muid=%d\n",
1787                 wst->size, wst->type, wst->dev, wst->qid.type,
1788                 (unsigned long long)wst->qid.path, wst->qid.version, wst->mode,
1789                 wst->atime, wst->mtime, (unsigned long long)wst->length,
1790                 wst->name, wst->uid, wst->gid, wst->muid, wst->extension,
1791                 wst->n_uid, wst->n_gid, wst->n_muid);
1792
1793         req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, wst->size+2, wst);
1794         if (IS_ERR(req)) {
1795                 err = PTR_ERR(req);
1796                 goto error;
1797         }
1798
1799         P9_DPRINTK(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
1800
1801         p9_free_req(clnt, req);
1802 error:
1803         return err;
1804 }
1805 EXPORT_SYMBOL(p9_client_wstat);
1806
1807 int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
1808 {
1809         int err;
1810         struct p9_req_t *req;
1811         struct p9_client *clnt;
1812
1813         err = 0;
1814         clnt = fid->clnt;
1815         P9_DPRINTK(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid);
1816         P9_DPRINTK(P9_DEBUG_9P,
1817                 "    valid=%x mode=%x uid=%d gid=%d size=%lld\n"
1818                 "    atime_sec=%lld atime_nsec=%lld\n"
1819                 "    mtime_sec=%lld mtime_nsec=%lld\n",
1820                 p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid,
1821                 p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
1822                 p9attr->mtime_sec, p9attr->mtime_nsec);
1823
1824         req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr);
1825
1826         if (IS_ERR(req)) {
1827                 err = PTR_ERR(req);
1828                 goto error;
1829         }
1830         P9_DPRINTK(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
1831         p9_free_req(clnt, req);
1832 error:
1833         return err;
1834 }
1835 EXPORT_SYMBOL(p9_client_setattr);
1836
1837 int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
1838 {
1839         int err;
1840         struct p9_req_t *req;
1841         struct p9_client *clnt;
1842
1843         err = 0;
1844         clnt = fid->clnt;
1845
1846         P9_DPRINTK(P9_DEBUG_9P, ">>> TSTATFS fid %d\n", fid->fid);
1847
1848         req = p9_client_rpc(clnt, P9_TSTATFS, "d", fid->fid);
1849         if (IS_ERR(req)) {
1850                 err = PTR_ERR(req);
1851                 goto error;
1852         }
1853
1854         err = p9pdu_readf(req->rc, clnt->proto_version, "ddqqqqqqd", &sb->type,
1855                 &sb->bsize, &sb->blocks, &sb->bfree, &sb->bavail,
1856                 &sb->files, &sb->ffree, &sb->fsid, &sb->namelen);
1857         if (err) {
1858                 P9_DUMP_PKT(1, req->rc);
1859                 p9_free_req(clnt, req);
1860                 goto error;
1861         }
1862
1863         P9_DPRINTK(P9_DEBUG_9P, "<<< RSTATFS fid %d type 0x%lx bsize %ld "
1864                 "blocks %llu bfree %llu bavail %llu files %llu ffree %llu "
1865                 "fsid %llu namelen %ld\n",
1866                 fid->fid, (long unsigned int)sb->type, (long int)sb->bsize,
1867                 sb->blocks, sb->bfree, sb->bavail, sb->files,  sb->ffree,
1868                 sb->fsid, (long int)sb->namelen);
1869
1870         p9_free_req(clnt, req);
1871 error:
1872         return err;
1873 }
1874 EXPORT_SYMBOL(p9_client_statfs);
1875
1876 int p9_client_rename(struct p9_fid *fid,
1877                      struct p9_fid *newdirfid, const char *name)
1878 {
1879         int err;
1880         struct p9_req_t *req;
1881         struct p9_client *clnt;
1882
1883         err = 0;
1884         clnt = fid->clnt;
1885
1886         P9_DPRINTK(P9_DEBUG_9P, ">>> TRENAME fid %d newdirfid %d name %s\n",
1887                         fid->fid, newdirfid->fid, name);
1888
1889         req = p9_client_rpc(clnt, P9_TRENAME, "dds", fid->fid,
1890                         newdirfid->fid, name);
1891         if (IS_ERR(req)) {
1892                 err = PTR_ERR(req);
1893                 goto error;
1894         }
1895
1896         P9_DPRINTK(P9_DEBUG_9P, "<<< RRENAME fid %d\n", fid->fid);
1897
1898         p9_free_req(clnt, req);
1899 error:
1900         return err;
1901 }
1902 EXPORT_SYMBOL(p9_client_rename);
1903
1904 int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
1905                        struct p9_fid *newdirfid, const char *new_name)
1906 {
1907         int err;
1908         struct p9_req_t *req;
1909         struct p9_client *clnt;
1910
1911         err = 0;
1912         clnt = olddirfid->clnt;
1913
1914         P9_DPRINTK(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
1915                    " newdirfid %d new name %s\n", olddirfid->fid, old_name,
1916                    newdirfid->fid, new_name);
1917
1918         req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
1919                             old_name, newdirfid->fid, new_name);
1920         if (IS_ERR(req)) {
1921                 err = PTR_ERR(req);
1922                 goto error;
1923         }
1924
1925         P9_DPRINTK(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
1926                    newdirfid->fid, new_name);
1927
1928         p9_free_req(clnt, req);
1929 error:
1930         return err;
1931 }
1932 EXPORT_SYMBOL(p9_client_renameat);
1933
1934 /*
1935  * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
1936  */
1937 struct p9_fid *p9_client_xattrwalk(struct p9_fid *file_fid,
1938                                 const char *attr_name, u64 *attr_size)
1939 {
1940         int err;
1941         struct p9_req_t *req;
1942         struct p9_client *clnt;
1943         struct p9_fid *attr_fid;
1944
1945         err = 0;
1946         clnt = file_fid->clnt;
1947         attr_fid = p9_fid_create(clnt);
1948         if (IS_ERR(attr_fid)) {
1949                 err = PTR_ERR(attr_fid);
1950                 attr_fid = NULL;
1951                 goto error;
1952         }
1953         P9_DPRINTK(P9_DEBUG_9P,
1954                 ">>> TXATTRWALK file_fid %d, attr_fid %d name %s\n",
1955                 file_fid->fid, attr_fid->fid, attr_name);
1956
1957         req = p9_client_rpc(clnt, P9_TXATTRWALK, "dds",
1958                         file_fid->fid, attr_fid->fid, attr_name);
1959         if (IS_ERR(req)) {
1960                 err = PTR_ERR(req);
1961                 goto error;
1962         }
1963         err = p9pdu_readf(req->rc, clnt->proto_version, "q", attr_size);
1964         if (err) {
1965                 P9_DUMP_PKT(1, req->rc);
1966                 p9_free_req(clnt, req);
1967                 goto clunk_fid;
1968         }
1969         p9_free_req(clnt, req);
1970         P9_DPRINTK(P9_DEBUG_9P, "<<<  RXATTRWALK fid %d size %llu\n",
1971                 attr_fid->fid, *attr_size);
1972         return attr_fid;
1973 clunk_fid:
1974         p9_client_clunk(attr_fid);
1975         attr_fid = NULL;
1976 error:
1977         if (attr_fid && (attr_fid != file_fid))
1978                 p9_fid_destroy(attr_fid);
1979
1980         return ERR_PTR(err);
1981 }
1982 EXPORT_SYMBOL_GPL(p9_client_xattrwalk);
1983
1984 int p9_client_xattrcreate(struct p9_fid *fid, const char *name,
1985                         u64 attr_size, int flags)
1986 {
1987         int err;
1988         struct p9_req_t *req;
1989         struct p9_client *clnt;
1990
1991         P9_DPRINTK(P9_DEBUG_9P,
1992                 ">>> TXATTRCREATE fid %d name  %s size %lld flag %d\n",
1993                 fid->fid, name, (long long)attr_size, flags);
1994         err = 0;
1995         clnt = fid->clnt;
1996         req = p9_client_rpc(clnt, P9_TXATTRCREATE, "dsqd",
1997                         fid->fid, name, attr_size, flags);
1998         if (IS_ERR(req)) {
1999                 err = PTR_ERR(req);
2000                 goto error;
2001         }
2002         P9_DPRINTK(P9_DEBUG_9P, "<<< RXATTRCREATE fid %d\n", fid->fid);
2003         p9_free_req(clnt, req);
2004 error:
2005         return err;
2006 }
2007 EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
2008
2009 int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
2010 {
2011         int err, rsize, non_zc = 0;
2012         struct p9_client *clnt;
2013         struct p9_req_t *req;
2014         char *dataptr;
2015
2016         P9_DPRINTK(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
2017                                 fid->fid, (long long unsigned) offset, count);
2018
2019         err = 0;
2020         clnt = fid->clnt;
2021
2022         rsize = fid->iounit;
2023         if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ)
2024                 rsize = clnt->msize - P9_READDIRHDRSZ;
2025
2026         if (count < rsize)
2027                 rsize = count;
2028
2029         /* Don't bother zerocopy for small IO (< 1024) */
2030         if (clnt->trans_mod->zc_request && rsize > 1024) {
2031                 /*
2032                  * response header len is 11
2033                  * PDU Header(7) + IO Size (4)
2034                  */
2035                 req = p9_client_zc_rpc(clnt, P9_TREADDIR, data, NULL, rsize, 0,
2036                                        11, 1, "dqd", fid->fid, offset, rsize);
2037         } else {
2038                 non_zc = 1;
2039                 req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid,
2040                                     offset, rsize);
2041         }
2042         if (IS_ERR(req)) {
2043                 err = PTR_ERR(req);
2044                 goto error;
2045         }
2046
2047         err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
2048         if (err) {
2049                 P9_DUMP_PKT(1, req->rc);
2050                 goto free_and_error;
2051         }
2052
2053         P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
2054
2055         if (non_zc)
2056                 memmove(data, dataptr, count);
2057
2058         p9_free_req(clnt, req);
2059         return count;
2060
2061 free_and_error:
2062         p9_free_req(clnt, req);
2063 error:
2064         return err;
2065 }
2066 EXPORT_SYMBOL(p9_client_readdir);
2067
2068 int p9_client_mknod_dotl(struct p9_fid *fid, char *name, int mode,
2069                         dev_t rdev, gid_t gid, struct p9_qid *qid)
2070 {
2071         int err;
2072         struct p9_client *clnt;
2073         struct p9_req_t *req;
2074
2075         err = 0;
2076         clnt = fid->clnt;
2077         P9_DPRINTK(P9_DEBUG_9P, ">>> TMKNOD fid %d name %s mode %d major %d "
2078                 "minor %d\n", fid->fid, name, mode, MAJOR(rdev), MINOR(rdev));
2079         req = p9_client_rpc(clnt, P9_TMKNOD, "dsdddd", fid->fid, name, mode,
2080                 MAJOR(rdev), MINOR(rdev), gid);
2081         if (IS_ERR(req))
2082                 return PTR_ERR(req);
2083
2084         err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
2085         if (err) {
2086                 P9_DUMP_PKT(1, req->rc);
2087                 goto error;
2088         }
2089         P9_DPRINTK(P9_DEBUG_9P, "<<< RMKNOD qid %x.%llx.%x\n", qid->type,
2090                                 (unsigned long long)qid->path, qid->version);
2091
2092 error:
2093         p9_free_req(clnt, req);
2094         return err;
2095
2096 }
2097 EXPORT_SYMBOL(p9_client_mknod_dotl);
2098
2099 int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
2100                                 gid_t gid, struct p9_qid *qid)
2101 {
2102         int err;
2103         struct p9_client *clnt;
2104         struct p9_req_t *req;
2105
2106         err = 0;
2107         clnt = fid->clnt;
2108         P9_DPRINTK(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
2109                  fid->fid, name, mode, gid);
2110         req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode,
2111                 gid);
2112         if (IS_ERR(req))
2113                 return PTR_ERR(req);
2114
2115         err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
2116         if (err) {
2117                 P9_DUMP_PKT(1, req->rc);
2118                 goto error;
2119         }
2120         P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
2121                                 (unsigned long long)qid->path, qid->version);
2122
2123 error:
2124         p9_free_req(clnt, req);
2125         return err;
2126
2127 }
2128 EXPORT_SYMBOL(p9_client_mkdir_dotl);
2129
2130 int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status)
2131 {
2132         int err;
2133         struct p9_client *clnt;
2134         struct p9_req_t *req;
2135
2136         err = 0;
2137         clnt = fid->clnt;
2138         P9_DPRINTK(P9_DEBUG_9P, ">>> TLOCK fid %d type %i flags %d "
2139                         "start %lld length %lld proc_id %d client_id %s\n",
2140                         fid->fid, flock->type, flock->flags, flock->start,
2141                         flock->length, flock->proc_id, flock->client_id);
2142
2143         req = p9_client_rpc(clnt, P9_TLOCK, "dbdqqds", fid->fid, flock->type,
2144                                 flock->flags, flock->start, flock->length,
2145                                         flock->proc_id, flock->client_id);
2146
2147         if (IS_ERR(req))
2148                 return PTR_ERR(req);
2149
2150         err = p9pdu_readf(req->rc, clnt->proto_version, "b", status);
2151         if (err) {
2152                 P9_DUMP_PKT(1, req->rc);
2153                 goto error;
2154         }
2155         P9_DPRINTK(P9_DEBUG_9P, "<<< RLOCK status %i\n", *status);
2156 error:
2157         p9_free_req(clnt, req);
2158         return err;
2159
2160 }
2161 EXPORT_SYMBOL(p9_client_lock_dotl);
2162
2163 int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *glock)
2164 {
2165         int err;
2166         struct p9_client *clnt;
2167         struct p9_req_t *req;
2168
2169         err = 0;
2170         clnt = fid->clnt;
2171         P9_DPRINTK(P9_DEBUG_9P, ">>> TGETLOCK fid %d, type %i start %lld "
2172                 "length %lld proc_id %d client_id %s\n", fid->fid, glock->type,
2173                 glock->start, glock->length, glock->proc_id, glock->client_id);
2174
2175         req = p9_client_rpc(clnt, P9_TGETLOCK, "dbqqds", fid->fid,  glock->type,
2176                 glock->start, glock->length, glock->proc_id, glock->client_id);
2177
2178         if (IS_ERR(req))
2179                 return PTR_ERR(req);
2180
2181         err = p9pdu_readf(req->rc, clnt->proto_version, "bqqds", &glock->type,
2182                         &glock->start, &glock->length, &glock->proc_id,
2183                         &glock->client_id);
2184         if (err) {
2185                 P9_DUMP_PKT(1, req->rc);
2186                 goto error;
2187         }
2188         P9_DPRINTK(P9_DEBUG_9P, "<<< RGETLOCK type %i start %lld length %lld "
2189                 "proc_id %d client_id %s\n", glock->type, glock->start,
2190                 glock->length, glock->proc_id, glock->client_id);
2191 error:
2192         p9_free_req(clnt, req);
2193         return err;
2194 }
2195 EXPORT_SYMBOL(p9_client_getlock_dotl);
2196
2197 int p9_client_readlink(struct p9_fid *fid, char **target)
2198 {
2199         int err;
2200         struct p9_client *clnt;
2201         struct p9_req_t *req;
2202
2203         err = 0;
2204         clnt = fid->clnt;
2205         P9_DPRINTK(P9_DEBUG_9P, ">>> TREADLINK fid %d\n", fid->fid);
2206
2207         req = p9_client_rpc(clnt, P9_TREADLINK, "d", fid->fid);
2208         if (IS_ERR(req))
2209                 return PTR_ERR(req);
2210
2211         err = p9pdu_readf(req->rc, clnt->proto_version, "s", target);
2212         if (err) {
2213                 P9_DUMP_PKT(1, req->rc);
2214                 goto error;
2215         }
2216         P9_DPRINTK(P9_DEBUG_9P, "<<< RREADLINK target %s\n", *target);
2217 error:
2218         p9_free_req(clnt, req);
2219         return err;
2220 }
2221 EXPORT_SYMBOL(p9_client_readlink);