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