linux/fs/nfs/nfs2xdr.c
<<
>>
Prefs
   1/*
   2 * linux/fs/nfs/nfs2xdr.c
   3 *
   4 * XDR functions to encode/decode NFS RPC arguments and results.
   5 *
   6 * Copyright (C) 1992, 1993, 1994  Rick Sladkey
   7 * Copyright (C) 1996 Olaf Kirch
   8 * 04 Aug 1998  Ion Badulescu <ionut@cs.columbia.edu>
   9 *              FIFO's need special handling in NFSv2
  10 */
  11
  12#include <linux/param.h>
  13#include <linux/time.h>
  14#include <linux/mm.h>
  15#include <linux/errno.h>
  16#include <linux/string.h>
  17#include <linux/in.h>
  18#include <linux/pagemap.h>
  19#include <linux/proc_fs.h>
  20#include <linux/sunrpc/clnt.h>
  21#include <linux/nfs.h>
  22#include <linux/nfs2.h>
  23#include <linux/nfs_fs.h>
  24#include "internal.h"
  25
  26#define NFSDBG_FACILITY         NFSDBG_XDR
  27
  28/* Mapping from NFS error code to "errno" error code. */
  29#define errno_NFSERR_IO         EIO
  30
  31/*
  32 * Declare the space requirements for NFS arguments and replies as
  33 * number of 32bit-words
  34 */
  35#define NFS_fhandle_sz          (8)
  36#define NFS_sattr_sz            (8)
  37#define NFS_filename_sz         (1+(NFS2_MAXNAMLEN>>2))
  38#define NFS_path_sz             (1+(NFS2_MAXPATHLEN>>2))
  39#define NFS_fattr_sz            (17)
  40#define NFS_info_sz             (5)
  41#define NFS_entry_sz            (NFS_filename_sz+3)
  42
  43#define NFS_diropargs_sz        (NFS_fhandle_sz+NFS_filename_sz)
  44#define NFS_removeargs_sz       (NFS_fhandle_sz+NFS_filename_sz)
  45#define NFS_sattrargs_sz        (NFS_fhandle_sz+NFS_sattr_sz)
  46#define NFS_readlinkargs_sz     (NFS_fhandle_sz)
  47#define NFS_readargs_sz         (NFS_fhandle_sz+3)
  48#define NFS_writeargs_sz        (NFS_fhandle_sz+4)
  49#define NFS_createargs_sz       (NFS_diropargs_sz+NFS_sattr_sz)
  50#define NFS_renameargs_sz       (NFS_diropargs_sz+NFS_diropargs_sz)
  51#define NFS_linkargs_sz         (NFS_fhandle_sz+NFS_diropargs_sz)
  52#define NFS_symlinkargs_sz      (NFS_diropargs_sz+1+NFS_sattr_sz)
  53#define NFS_readdirargs_sz      (NFS_fhandle_sz+2)
  54
  55#define NFS_attrstat_sz         (1+NFS_fattr_sz)
  56#define NFS_diropres_sz         (1+NFS_fhandle_sz+NFS_fattr_sz)
  57#define NFS_readlinkres_sz      (2)
  58#define NFS_readres_sz          (1+NFS_fattr_sz+1)
  59#define NFS_writeres_sz         (NFS_attrstat_sz)
  60#define NFS_stat_sz             (1)
  61#define NFS_readdirres_sz       (1)
  62#define NFS_statfsres_sz        (1+NFS_info_sz)
  63
  64static int nfs_stat_to_errno(enum nfs_stat);
  65
  66/*
  67 * While encoding arguments, set up the reply buffer in advance to
  68 * receive reply data directly into the page cache.
  69 */
  70static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
  71                                 unsigned int base, unsigned int len,
  72                                 unsigned int bufsize)
  73{
  74        struct rpc_auth *auth = req->rq_cred->cr_auth;
  75        unsigned int replen;
  76
  77        replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
  78        xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
  79}
  80
  81/*
  82 * Handle decode buffer overflows out-of-line.
  83 */
  84static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
  85{
  86        dprintk("NFS: %s prematurely hit the end of our receive buffer. "
  87                "Remaining buffer length is %tu words.\n",
  88                func, xdr->end - xdr->p);
  89}
  90
  91
  92/*
  93 * Encode/decode NFSv2 basic data types
  94 *
  95 * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
  96 * "NFS: Network File System Protocol Specification".
  97 *
  98 * Not all basic data types have their own encoding and decoding
  99 * functions.  For run-time efficiency, some data types are encoded
 100 * or decoded inline.
 101 */
 102
 103/*
 104 *      typedef opaque  nfsdata<>;
 105 */
 106static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_readres *result)
 107{
 108        u32 recvd, count;
 109        __be32 *p;
 110
 111        p = xdr_inline_decode(xdr, 4);
 112        if (unlikely(p == NULL))
 113                goto out_overflow;
 114        count = be32_to_cpup(p);
 115        recvd = xdr_read_pages(xdr, count);
 116        if (unlikely(count > recvd))
 117                goto out_cheating;
 118out:
 119        result->eof = 0;        /* NFSv2 does not pass EOF flag on the wire. */
 120        result->count = count;
 121        return count;
 122out_cheating:
 123        dprintk("NFS: server cheating in read result: "
 124                "count %u > recvd %u\n", count, recvd);
 125        count = recvd;
 126        goto out;
 127out_overflow:
 128        print_overflow_msg(__func__, xdr);
 129        return -EIO;
 130}
 131
 132/*
 133 *      enum stat {
 134 *              NFS_OK = 0,
 135 *              NFSERR_PERM = 1,
 136 *              NFSERR_NOENT = 2,
 137 *              NFSERR_IO = 5,
 138 *              NFSERR_NXIO = 6,
 139 *              NFSERR_ACCES = 13,
 140 *              NFSERR_EXIST = 17,
 141 *              NFSERR_NODEV = 19,
 142 *              NFSERR_NOTDIR = 20,
 143 *              NFSERR_ISDIR = 21,
 144 *              NFSERR_FBIG = 27,
 145 *              NFSERR_NOSPC = 28,
 146 *              NFSERR_ROFS = 30,
 147 *              NFSERR_NAMETOOLONG = 63,
 148 *              NFSERR_NOTEMPTY = 66,
 149 *              NFSERR_DQUOT = 69,
 150 *              NFSERR_STALE = 70,
 151 *              NFSERR_WFLUSH = 99
 152 *      };
 153 */
 154static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
 155{
 156        __be32 *p;
 157
 158        p = xdr_inline_decode(xdr, 4);
 159        if (unlikely(p == NULL))
 160                goto out_overflow;
 161        *status = be32_to_cpup(p);
 162        return 0;
 163out_overflow:
 164        print_overflow_msg(__func__, xdr);
 165        return -EIO;
 166}
 167
 168/*
 169 * 2.3.2.  ftype
 170 *
 171 *      enum ftype {
 172 *              NFNON = 0,
 173 *              NFREG = 1,
 174 *              NFDIR = 2,
 175 *              NFBLK = 3,
 176 *              NFCHR = 4,
 177 *              NFLNK = 5
 178 *      };
 179 *
 180 */
 181static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
 182{
 183        *type = be32_to_cpup(p++);
 184        if (unlikely(*type > NF2FIFO))
 185                *type = NFBAD;
 186        return p;
 187}
 188
 189/*
 190 * 2.3.3.  fhandle
 191 *
 192 *      typedef opaque fhandle[FHSIZE];
 193 */
 194static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
 195{
 196        __be32 *p;
 197
 198        p = xdr_reserve_space(xdr, NFS2_FHSIZE);
 199        memcpy(p, fh->data, NFS2_FHSIZE);
 200}
 201
 202static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
 203{
 204        __be32 *p;
 205
 206        p = xdr_inline_decode(xdr, NFS2_FHSIZE);
 207        if (unlikely(p == NULL))
 208                goto out_overflow;
 209        fh->size = NFS2_FHSIZE;
 210        memcpy(fh->data, p, NFS2_FHSIZE);
 211        return 0;
 212out_overflow:
 213        print_overflow_msg(__func__, xdr);
 214        return -EIO;
 215}
 216
 217/*
 218 * 2.3.4.  timeval
 219 *
 220 *      struct timeval {
 221 *              unsigned int seconds;
 222 *              unsigned int useconds;
 223 *      };
 224 */
 225static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
 226{
 227        *p++ = cpu_to_be32(timep->tv_sec);
 228        if (timep->tv_nsec != 0)
 229                *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
 230        else
 231                *p++ = cpu_to_be32(0);
 232        return p;
 233}
 234
 235/*
 236 * Passing the invalid value useconds=1000000 is a Sun convention for
 237 * "set to current server time".  It's needed to make permissions checks
 238 * for the "touch" program across v2 mounts to Solaris and Irix servers
 239 * work correctly.  See description of sattr in section 6.1 of "NFS
 240 * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
 241 */
 242static __be32 *xdr_encode_current_server_time(__be32 *p,
 243                                              const struct timespec *timep)
 244{
 245        *p++ = cpu_to_be32(timep->tv_sec);
 246        *p++ = cpu_to_be32(1000000);
 247        return p;
 248}
 249
 250static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
 251{
 252        timep->tv_sec = be32_to_cpup(p++);
 253        timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
 254        return p;
 255}
 256
 257/*
 258 * 2.3.5.  fattr
 259 *
 260 *      struct fattr {
 261 *              ftype           type;
 262 *              unsigned int    mode;
 263 *              unsigned int    nlink;
 264 *              unsigned int    uid;
 265 *              unsigned int    gid;
 266 *              unsigned int    size;
 267 *              unsigned int    blocksize;
 268 *              unsigned int    rdev;
 269 *              unsigned int    blocks;
 270 *              unsigned int    fsid;
 271 *              unsigned int    fileid;
 272 *              timeval         atime;
 273 *              timeval         mtime;
 274 *              timeval         ctime;
 275 *      };
 276 *
 277 */
 278static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
 279{
 280        u32 rdev, type;
 281        __be32 *p;
 282
 283        p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
 284        if (unlikely(p == NULL))
 285                goto out_overflow;
 286
 287        fattr->valid |= NFS_ATTR_FATTR_V2;
 288
 289        p = xdr_decode_ftype(p, &type);
 290
 291        fattr->mode = be32_to_cpup(p++);
 292        fattr->nlink = be32_to_cpup(p++);
 293        fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++));
 294        if (!uid_valid(fattr->uid))
 295                goto out_uid;
 296        fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++));
 297        if (!gid_valid(fattr->gid))
 298                goto out_gid;
 299                
 300        fattr->size = be32_to_cpup(p++);
 301        fattr->du.nfs2.blocksize = be32_to_cpup(p++);
 302
 303        rdev = be32_to_cpup(p++);
 304        fattr->rdev = new_decode_dev(rdev);
 305        if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
 306                fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
 307                fattr->rdev = 0;
 308        }
 309
 310        fattr->du.nfs2.blocks = be32_to_cpup(p++);
 311        fattr->fsid.major = be32_to_cpup(p++);
 312        fattr->fsid.minor = 0;
 313        fattr->fileid = be32_to_cpup(p++);
 314
 315        p = xdr_decode_time(p, &fattr->atime);
 316        p = xdr_decode_time(p, &fattr->mtime);
 317        xdr_decode_time(p, &fattr->ctime);
 318        fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
 319
 320        return 0;
 321out_uid:
 322        dprintk("NFS: returned invalid uid\n");
 323        return -EINVAL;
 324out_gid:
 325        dprintk("NFS: returned invalid gid\n");
 326        return -EINVAL;
 327out_overflow:
 328        print_overflow_msg(__func__, xdr);
 329        return -EIO;
 330}
 331
 332/*
 333 * 2.3.6.  sattr
 334 *
 335 *      struct sattr {
 336 *              unsigned int    mode;
 337 *              unsigned int    uid;
 338 *              unsigned int    gid;
 339 *              unsigned int    size;
 340 *              timeval         atime;
 341 *              timeval         mtime;
 342 *      };
 343 */
 344
 345#define NFS2_SATTR_NOT_SET      (0xffffffff)
 346
 347static __be32 *xdr_time_not_set(__be32 *p)
 348{
 349        *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 350        *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 351        return p;
 352}
 353
 354static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
 355{
 356        __be32 *p;
 357
 358        p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
 359
 360        if (attr->ia_valid & ATTR_MODE)
 361                *p++ = cpu_to_be32(attr->ia_mode);
 362        else
 363                *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 364        if (attr->ia_valid & ATTR_UID)
 365                *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
 366        else
 367                *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 368        if (attr->ia_valid & ATTR_GID)
 369                *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
 370        else
 371                *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 372        if (attr->ia_valid & ATTR_SIZE)
 373                *p++ = cpu_to_be32((u32)attr->ia_size);
 374        else
 375                *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 376
 377        if (attr->ia_valid & ATTR_ATIME_SET)
 378                p = xdr_encode_time(p, &attr->ia_atime);
 379        else if (attr->ia_valid & ATTR_ATIME)
 380                p = xdr_encode_current_server_time(p, &attr->ia_atime);
 381        else
 382                p = xdr_time_not_set(p);
 383        if (attr->ia_valid & ATTR_MTIME_SET)
 384                xdr_encode_time(p, &attr->ia_mtime);
 385        else if (attr->ia_valid & ATTR_MTIME)
 386                xdr_encode_current_server_time(p, &attr->ia_mtime);
 387        else
 388                xdr_time_not_set(p);
 389}
 390
 391/*
 392 * 2.3.7.  filename
 393 *
 394 *      typedef string filename<MAXNAMLEN>;
 395 */
 396static void encode_filename(struct xdr_stream *xdr,
 397                            const char *name, u32 length)
 398{
 399        __be32 *p;
 400
 401        WARN_ON_ONCE(length > NFS2_MAXNAMLEN);
 402        p = xdr_reserve_space(xdr, 4 + length);
 403        xdr_encode_opaque(p, name, length);
 404}
 405
 406static int decode_filename_inline(struct xdr_stream *xdr,
 407                                  const char **name, u32 *length)
 408{
 409        __be32 *p;
 410        u32 count;
 411
 412        p = xdr_inline_decode(xdr, 4);
 413        if (unlikely(p == NULL))
 414                goto out_overflow;
 415        count = be32_to_cpup(p);
 416        if (count > NFS3_MAXNAMLEN)
 417                goto out_nametoolong;
 418        p = xdr_inline_decode(xdr, count);
 419        if (unlikely(p == NULL))
 420                goto out_overflow;
 421        *name = (const char *)p;
 422        *length = count;
 423        return 0;
 424out_nametoolong:
 425        dprintk("NFS: returned filename too long: %u\n", count);
 426        return -ENAMETOOLONG;
 427out_overflow:
 428        print_overflow_msg(__func__, xdr);
 429        return -EIO;
 430}
 431
 432/*
 433 * 2.3.8.  path
 434 *
 435 *      typedef string path<MAXPATHLEN>;
 436 */
 437static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
 438{
 439        __be32 *p;
 440
 441        p = xdr_reserve_space(xdr, 4);
 442        *p = cpu_to_be32(length);
 443        xdr_write_pages(xdr, pages, 0, length);
 444}
 445
 446static int decode_path(struct xdr_stream *xdr)
 447{
 448        u32 length, recvd;
 449        __be32 *p;
 450
 451        p = xdr_inline_decode(xdr, 4);
 452        if (unlikely(p == NULL))
 453                goto out_overflow;
 454        length = be32_to_cpup(p);
 455        if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
 456                goto out_size;
 457        recvd = xdr_read_pages(xdr, length);
 458        if (unlikely(length > recvd))
 459                goto out_cheating;
 460        xdr_terminate_string(xdr->buf, length);
 461        return 0;
 462out_size:
 463        dprintk("NFS: returned pathname too long: %u\n", length);
 464        return -ENAMETOOLONG;
 465out_cheating:
 466        dprintk("NFS: server cheating in pathname result: "
 467                "length %u > received %u\n", length, recvd);
 468        return -EIO;
 469out_overflow:
 470        print_overflow_msg(__func__, xdr);
 471        return -EIO;
 472}
 473
 474/*
 475 * 2.3.9.  attrstat
 476 *
 477 *      union attrstat switch (stat status) {
 478 *      case NFS_OK:
 479 *              fattr attributes;
 480 *      default:
 481 *              void;
 482 *      };
 483 */
 484static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result)
 485{
 486        enum nfs_stat status;
 487        int error;
 488
 489        error = decode_stat(xdr, &status);
 490        if (unlikely(error))
 491                goto out;
 492        if (status != NFS_OK)
 493                goto out_default;
 494        error = decode_fattr(xdr, result);
 495out:
 496        return error;
 497out_default:
 498        return nfs_stat_to_errno(status);
 499}
 500
 501/*
 502 * 2.3.10.  diropargs
 503 *
 504 *      struct diropargs {
 505 *              fhandle  dir;
 506 *              filename name;
 507 *      };
 508 */
 509static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
 510                             const char *name, u32 length)
 511{
 512        encode_fhandle(xdr, fh);
 513        encode_filename(xdr, name, length);
 514}
 515
 516/*
 517 * 2.3.11.  diropres
 518 *
 519 *      union diropres switch (stat status) {
 520 *      case NFS_OK:
 521 *              struct {
 522 *                      fhandle file;
 523 *                      fattr   attributes;
 524 *              } diropok;
 525 *      default:
 526 *              void;
 527 *      };
 528 */
 529static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
 530{
 531        int error;
 532
 533        error = decode_fhandle(xdr, result->fh);
 534        if (unlikely(error))
 535                goto out;
 536        error = decode_fattr(xdr, result->fattr);
 537out:
 538        return error;
 539}
 540
 541static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
 542{
 543        enum nfs_stat status;
 544        int error;
 545
 546        error = decode_stat(xdr, &status);
 547        if (unlikely(error))
 548                goto out;
 549        if (status != NFS_OK)
 550                goto out_default;
 551        error = decode_diropok(xdr, result);
 552out:
 553        return error;
 554out_default:
 555        return nfs_stat_to_errno(status);
 556}
 557
 558
 559/*
 560 * NFSv2 XDR encode functions
 561 *
 562 * NFSv2 argument types are defined in section 2.2 of RFC 1094:
 563 * "NFS: Network File System Protocol Specification".
 564 */
 565
 566static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
 567                                 struct xdr_stream *xdr,
 568                                 const struct nfs_fh *fh)
 569{
 570        encode_fhandle(xdr, fh);
 571}
 572
 573/*
 574 * 2.2.3.  sattrargs
 575 *
 576 *      struct sattrargs {
 577 *              fhandle file;
 578 *              sattr attributes;
 579 *      };
 580 */
 581static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
 582                                   struct xdr_stream *xdr,
 583                                   const struct nfs_sattrargs *args)
 584{
 585        encode_fhandle(xdr, args->fh);
 586        encode_sattr(xdr, args->sattr);
 587}
 588
 589static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
 590                                   struct xdr_stream *xdr,
 591                                   const struct nfs_diropargs *args)
 592{
 593        encode_diropargs(xdr, args->fh, args->name, args->len);
 594}
 595
 596static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
 597                                      struct xdr_stream *xdr,
 598                                      const struct nfs_readlinkargs *args)
 599{
 600        encode_fhandle(xdr, args->fh);
 601        prepare_reply_buffer(req, args->pages, args->pgbase,
 602                                        args->pglen, NFS_readlinkres_sz);
 603}
 604
 605/*
 606 * 2.2.7.  readargs
 607 *
 608 *      struct readargs {
 609 *              fhandle file;
 610 *              unsigned offset;
 611 *              unsigned count;
 612 *              unsigned totalcount;
 613 *      };
 614 */
 615static void encode_readargs(struct xdr_stream *xdr,
 616                            const struct nfs_readargs *args)
 617{
 618        u32 offset = args->offset;
 619        u32 count = args->count;
 620        __be32 *p;
 621
 622        encode_fhandle(xdr, args->fh);
 623
 624        p = xdr_reserve_space(xdr, 4 + 4 + 4);
 625        *p++ = cpu_to_be32(offset);
 626        *p++ = cpu_to_be32(count);
 627        *p = cpu_to_be32(count);
 628}
 629
 630static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
 631                                  struct xdr_stream *xdr,
 632                                  const struct nfs_readargs *args)
 633{
 634        encode_readargs(xdr, args);
 635        prepare_reply_buffer(req, args->pages, args->pgbase,
 636                                        args->count, NFS_readres_sz);
 637        req->rq_rcv_buf.flags |= XDRBUF_READ;
 638}
 639
 640/*
 641 * 2.2.9.  writeargs
 642 *
 643 *      struct writeargs {
 644 *              fhandle file;
 645 *              unsigned beginoffset;
 646 *              unsigned offset;
 647 *              unsigned totalcount;
 648 *              nfsdata data;
 649 *      };
 650 */
 651static void encode_writeargs(struct xdr_stream *xdr,
 652                             const struct nfs_writeargs *args)
 653{
 654        u32 offset = args->offset;
 655        u32 count = args->count;
 656        __be32 *p;
 657
 658        encode_fhandle(xdr, args->fh);
 659
 660        p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
 661        *p++ = cpu_to_be32(offset);
 662        *p++ = cpu_to_be32(offset);
 663        *p++ = cpu_to_be32(count);
 664
 665        /* nfsdata */
 666        *p = cpu_to_be32(count);
 667        xdr_write_pages(xdr, args->pages, args->pgbase, count);
 668}
 669
 670static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
 671                                   struct xdr_stream *xdr,
 672                                   const struct nfs_writeargs *args)
 673{
 674        encode_writeargs(xdr, args);
 675        xdr->buf->flags |= XDRBUF_WRITE;
 676}
 677
 678/*
 679 * 2.2.10.  createargs
 680 *
 681 *      struct createargs {
 682 *              diropargs where;
 683 *              sattr attributes;
 684 *      };
 685 */
 686static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
 687                                    struct xdr_stream *xdr,
 688                                    const struct nfs_createargs *args)
 689{
 690        encode_diropargs(xdr, args->fh, args->name, args->len);
 691        encode_sattr(xdr, args->sattr);
 692}
 693
 694static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
 695                                    struct xdr_stream *xdr,
 696                                    const struct nfs_removeargs *args)
 697{
 698        encode_diropargs(xdr, args->fh, args->name.name, args->name.len);
 699}
 700
 701/*
 702 * 2.2.12.  renameargs
 703 *
 704 *      struct renameargs {
 705 *              diropargs from;
 706 *              diropargs to;
 707 *      };
 708 */
 709static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
 710                                    struct xdr_stream *xdr,
 711                                    const struct nfs_renameargs *args)
 712{
 713        const struct qstr *old = args->old_name;
 714        const struct qstr *new = args->new_name;
 715
 716        encode_diropargs(xdr, args->old_dir, old->name, old->len);
 717        encode_diropargs(xdr, args->new_dir, new->name, new->len);
 718}
 719
 720/*
 721 * 2.2.13.  linkargs
 722 *
 723 *      struct linkargs {
 724 *              fhandle from;
 725 *              diropargs to;
 726 *      };
 727 */
 728static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
 729                                  struct xdr_stream *xdr,
 730                                  const struct nfs_linkargs *args)
 731{
 732        encode_fhandle(xdr, args->fromfh);
 733        encode_diropargs(xdr, args->tofh, args->toname, args->tolen);
 734}
 735
 736/*
 737 * 2.2.14.  symlinkargs
 738 *
 739 *      struct symlinkargs {
 740 *              diropargs from;
 741 *              path to;
 742 *              sattr attributes;
 743 *      };
 744 */
 745static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
 746                                     struct xdr_stream *xdr,
 747                                     const struct nfs_symlinkargs *args)
 748{
 749        encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
 750        encode_path(xdr, args->pages, args->pathlen);
 751        encode_sattr(xdr, args->sattr);
 752}
 753
 754/*
 755 * 2.2.17.  readdirargs
 756 *
 757 *      struct readdirargs {
 758 *              fhandle dir;
 759 *              nfscookie cookie;
 760 *              unsigned count;
 761 *      };
 762 */
 763static void encode_readdirargs(struct xdr_stream *xdr,
 764                               const struct nfs_readdirargs *args)
 765{
 766        __be32 *p;
 767
 768        encode_fhandle(xdr, args->fh);
 769
 770        p = xdr_reserve_space(xdr, 4 + 4);
 771        *p++ = cpu_to_be32(args->cookie);
 772        *p = cpu_to_be32(args->count);
 773}
 774
 775static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
 776                                     struct xdr_stream *xdr,
 777                                     const struct nfs_readdirargs *args)
 778{
 779        encode_readdirargs(xdr, args);
 780        prepare_reply_buffer(req, args->pages, 0,
 781                                        args->count, NFS_readdirres_sz);
 782}
 783
 784/*
 785 * NFSv2 XDR decode functions
 786 *
 787 * NFSv2 result types are defined in section 2.2 of RFC 1094:
 788 * "NFS: Network File System Protocol Specification".
 789 */
 790
 791static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
 792                             void *__unused)
 793{
 794        enum nfs_stat status;
 795        int error;
 796
 797        error = decode_stat(xdr, &status);
 798        if (unlikely(error))
 799                goto out;
 800        if (status != NFS_OK)
 801                goto out_default;
 802out:
 803        return error;
 804out_default:
 805        return nfs_stat_to_errno(status);
 806}
 807
 808static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
 809                                 struct nfs_fattr *result)
 810{
 811        return decode_attrstat(xdr, result);
 812}
 813
 814static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
 815                                 struct nfs_diropok *result)
 816{
 817        return decode_diropres(xdr, result);
 818}
 819
 820/*
 821 * 2.2.6.  readlinkres
 822 *
 823 *      union readlinkres switch (stat status) {
 824 *      case NFS_OK:
 825 *              path data;
 826 *      default:
 827 *              void;
 828 *      };
 829 */
 830static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
 831                                    struct xdr_stream *xdr, void *__unused)
 832{
 833        enum nfs_stat status;
 834        int error;
 835
 836        error = decode_stat(xdr, &status);
 837        if (unlikely(error))
 838                goto out;
 839        if (status != NFS_OK)
 840                goto out_default;
 841        error = decode_path(xdr);
 842out:
 843        return error;
 844out_default:
 845        return nfs_stat_to_errno(status);
 846}
 847
 848/*
 849 * 2.2.7.  readres
 850 *
 851 *      union readres switch (stat status) {
 852 *      case NFS_OK:
 853 *              fattr attributes;
 854 *              nfsdata data;
 855 *      default:
 856 *              void;
 857 *      };
 858 */
 859static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
 860                                struct nfs_readres *result)
 861{
 862        enum nfs_stat status;
 863        int error;
 864
 865        error = decode_stat(xdr, &status);
 866        if (unlikely(error))
 867                goto out;
 868        if (status != NFS_OK)
 869                goto out_default;
 870        error = decode_fattr(xdr, result->fattr);
 871        if (unlikely(error))
 872                goto out;
 873        error = decode_nfsdata(xdr, result);
 874out:
 875        return error;
 876out_default:
 877        return nfs_stat_to_errno(status);
 878}
 879
 880static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
 881                                 struct nfs_writeres *result)
 882{
 883        /* All NFSv2 writes are "file sync" writes */
 884        result->verf->committed = NFS_FILE_SYNC;
 885        return decode_attrstat(xdr, result->fattr);
 886}
 887
 888/**
 889 * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
 890 *                      the local page cache.
 891 * @xdr: XDR stream where entry resides
 892 * @entry: buffer to fill in with entry data
 893 * @plus: boolean indicating whether this should be a readdirplus entry
 894 *
 895 * Returns zero if successful, otherwise a negative errno value is
 896 * returned.
 897 *
 898 * This function is not invoked during READDIR reply decoding, but
 899 * rather whenever an application invokes the getdents(2) system call
 900 * on a directory already in our cache.
 901 *
 902 * 2.2.17.  entry
 903 *
 904 *      struct entry {
 905 *              unsigned        fileid;
 906 *              filename        name;
 907 *              nfscookie       cookie;
 908 *              entry           *nextentry;
 909 *      };
 910 */
 911int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
 912                       int plus)
 913{
 914        __be32 *p;
 915        int error;
 916
 917        p = xdr_inline_decode(xdr, 4);
 918        if (unlikely(p == NULL))
 919                goto out_overflow;
 920        if (*p++ == xdr_zero) {
 921                p = xdr_inline_decode(xdr, 4);
 922                if (unlikely(p == NULL))
 923                        goto out_overflow;
 924                if (*p++ == xdr_zero)
 925                        return -EAGAIN;
 926                entry->eof = 1;
 927                return -EBADCOOKIE;
 928        }
 929
 930        p = xdr_inline_decode(xdr, 4);
 931        if (unlikely(p == NULL))
 932                goto out_overflow;
 933        entry->ino = be32_to_cpup(p);
 934
 935        error = decode_filename_inline(xdr, &entry->name, &entry->len);
 936        if (unlikely(error))
 937                return error;
 938
 939        /*
 940         * The type (size and byte order) of nfscookie isn't defined in
 941         * RFC 1094.  This implementation assumes that it's an XDR uint32.
 942         */
 943        entry->prev_cookie = entry->cookie;
 944        p = xdr_inline_decode(xdr, 4);
 945        if (unlikely(p == NULL))
 946                goto out_overflow;
 947        entry->cookie = be32_to_cpup(p);
 948
 949        entry->d_type = DT_UNKNOWN;
 950
 951        return 0;
 952
 953out_overflow:
 954        print_overflow_msg(__func__, xdr);
 955        return -EAGAIN;
 956}
 957
 958/*
 959 * 2.2.17.  readdirres
 960 *
 961 *      union readdirres switch (stat status) {
 962 *      case NFS_OK:
 963 *              struct {
 964 *                      entry *entries;
 965 *                      bool eof;
 966 *              } readdirok;
 967 *      default:
 968 *              void;
 969 *      };
 970 *
 971 * Read the directory contents into the page cache, but don't
 972 * touch them.  The actual decoding is done by nfs2_decode_dirent()
 973 * during subsequent nfs_readdir() calls.
 974 */
 975static int decode_readdirok(struct xdr_stream *xdr)
 976{
 977        return xdr_read_pages(xdr, xdr->buf->page_len);
 978}
 979
 980static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
 981                                   struct xdr_stream *xdr, void *__unused)
 982{
 983        enum nfs_stat status;
 984        int error;
 985
 986        error = decode_stat(xdr, &status);
 987        if (unlikely(error))
 988                goto out;
 989        if (status != NFS_OK)
 990                goto out_default;
 991        error = decode_readdirok(xdr);
 992out:
 993        return error;
 994out_default:
 995        return nfs_stat_to_errno(status);
 996}
 997
 998/*
 999 * 2.2.18.  statfsres
1000 *
1001 *      union statfsres (stat status) {
1002 *      case NFS_OK:
1003 *              struct {
1004 *                      unsigned tsize;
1005 *                      unsigned bsize;
1006 *                      unsigned blocks;
1007 *                      unsigned bfree;
1008 *                      unsigned bavail;
1009 *              } info;
1010 *      default:
1011 *              void;
1012 *      };
1013 */
1014static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
1015{
1016        __be32 *p;
1017
1018        p = xdr_inline_decode(xdr, NFS_info_sz << 2);
1019        if (unlikely(p == NULL))
1020                goto out_overflow;
1021        result->tsize  = be32_to_cpup(p++);
1022        result->bsize  = be32_to_cpup(p++);
1023        result->blocks = be32_to_cpup(p++);
1024        result->bfree  = be32_to_cpup(p++);
1025        result->bavail = be32_to_cpup(p);
1026        return 0;
1027out_overflow:
1028        print_overflow_msg(__func__, xdr);
1029        return -EIO;
1030}
1031
1032static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
1033                                  struct nfs2_fsstat *result)
1034{
1035        enum nfs_stat status;
1036        int error;
1037
1038        error = decode_stat(xdr, &status);
1039        if (unlikely(error))
1040                goto out;
1041        if (status != NFS_OK)
1042                goto out_default;
1043        error = decode_info(xdr, result);
1044out:
1045        return error;
1046out_default:
1047        return nfs_stat_to_errno(status);
1048}
1049
1050
1051/*
1052 * We need to translate between nfs status return values and
1053 * the local errno values which may not be the same.
1054 */
1055static const struct {
1056        int stat;
1057        int errno;
1058} nfs_errtbl[] = {
1059        { NFS_OK,               0               },
1060        { NFSERR_PERM,          -EPERM          },
1061        { NFSERR_NOENT,         -ENOENT         },
1062        { NFSERR_IO,            -errno_NFSERR_IO},
1063        { NFSERR_NXIO,          -ENXIO          },
1064/*      { NFSERR_EAGAIN,        -EAGAIN         }, */
1065        { NFSERR_ACCES,         -EACCES         },
1066        { NFSERR_EXIST,         -EEXIST         },
1067        { NFSERR_XDEV,          -EXDEV          },
1068        { NFSERR_NODEV,         -ENODEV         },
1069        { NFSERR_NOTDIR,        -ENOTDIR        },
1070        { NFSERR_ISDIR,         -EISDIR         },
1071        { NFSERR_INVAL,         -EINVAL         },
1072        { NFSERR_FBIG,          -EFBIG          },
1073        { NFSERR_NOSPC,         -ENOSPC         },
1074        { NFSERR_ROFS,          -EROFS          },
1075        { NFSERR_MLINK,         -EMLINK         },
1076        { NFSERR_NAMETOOLONG,   -ENAMETOOLONG   },
1077        { NFSERR_NOTEMPTY,      -ENOTEMPTY      },
1078        { NFSERR_DQUOT,         -EDQUOT         },
1079        { NFSERR_STALE,         -ESTALE         },
1080        { NFSERR_REMOTE,        -EREMOTE        },
1081#ifdef EWFLUSH
1082        { NFSERR_WFLUSH,        -EWFLUSH        },
1083#endif
1084        { NFSERR_BADHANDLE,     -EBADHANDLE     },
1085        { NFSERR_NOT_SYNC,      -ENOTSYNC       },
1086        { NFSERR_BAD_COOKIE,    -EBADCOOKIE     },
1087        { NFSERR_NOTSUPP,       -ENOTSUPP       },
1088        { NFSERR_TOOSMALL,      -ETOOSMALL      },
1089        { NFSERR_SERVERFAULT,   -EREMOTEIO      },
1090        { NFSERR_BADTYPE,       -EBADTYPE       },
1091        { NFSERR_JUKEBOX,       -EJUKEBOX       },
1092        { -1,                   -EIO            }
1093};
1094
1095/**
1096 * nfs_stat_to_errno - convert an NFS status code to a local errno
1097 * @status: NFS status code to convert
1098 *
1099 * Returns a local errno value, or -EIO if the NFS status code is
1100 * not recognized.  This function is used jointly by NFSv2 and NFSv3.
1101 */
1102static int nfs_stat_to_errno(enum nfs_stat status)
1103{
1104        int i;
1105
1106        for (i = 0; nfs_errtbl[i].stat != -1; i++) {
1107                if (nfs_errtbl[i].stat == (int)status)
1108                        return nfs_errtbl[i].errno;
1109        }
1110        dprintk("NFS: Unrecognized nfs status value: %u\n", status);
1111        return nfs_errtbl[i].errno;
1112}
1113
1114#define PROC(proc, argtype, restype, timer)                             \
1115[NFSPROC_##proc] = {                                                    \
1116        .p_proc     =  NFSPROC_##proc,                                  \
1117        .p_encode   =  (kxdreproc_t)nfs2_xdr_enc_##argtype,             \
1118        .p_decode   =  (kxdrdproc_t)nfs2_xdr_dec_##restype,             \
1119        .p_arglen   =  NFS_##argtype##_sz,                              \
1120        .p_replen   =  NFS_##restype##_sz,                              \
1121        .p_timer    =  timer,                                           \
1122        .p_statidx  =  NFSPROC_##proc,                                  \
1123        .p_name     =  #proc,                                           \
1124        }
1125struct rpc_procinfo     nfs_procedures[] = {
1126        PROC(GETATTR,   fhandle,        attrstat,       1),
1127        PROC(SETATTR,   sattrargs,      attrstat,       0),
1128        PROC(LOOKUP,    diropargs,      diropres,       2),
1129        PROC(READLINK,  readlinkargs,   readlinkres,    3),
1130        PROC(READ,      readargs,       readres,        3),
1131        PROC(WRITE,     writeargs,      writeres,       4),
1132        PROC(CREATE,    createargs,     diropres,       0),
1133        PROC(REMOVE,    removeargs,     stat,           0),
1134        PROC(RENAME,    renameargs,     stat,           0),
1135        PROC(LINK,      linkargs,       stat,           0),
1136        PROC(SYMLINK,   symlinkargs,    stat,           0),
1137        PROC(MKDIR,     createargs,     diropres,       0),
1138        PROC(RMDIR,     diropargs,      stat,           0),
1139        PROC(READDIR,   readdirargs,    readdirres,     3),
1140        PROC(STATFS,    fhandle,        statfsres,      0),
1141};
1142
1143const struct rpc_version nfs_version2 = {
1144        .number                 = 2,
1145        .nrprocs                = ARRAY_SIZE(nfs_procedures),
1146        .procs                  = nfs_procedures
1147};
1148