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