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_pgio_res *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                           __u32 *op_status)
 486{
 487        enum nfs_stat status;
 488        int error;
 489
 490        error = decode_stat(xdr, &status);
 491        if (unlikely(error))
 492                goto out;
 493        if (op_status)
 494                *op_status = status;
 495        if (status != NFS_OK)
 496                goto out_default;
 497        error = decode_fattr(xdr, result);
 498out:
 499        return error;
 500out_default:
 501        return nfs_stat_to_errno(status);
 502}
 503
 504/*
 505 * 2.3.10.  diropargs
 506 *
 507 *      struct diropargs {
 508 *              fhandle  dir;
 509 *              filename name;
 510 *      };
 511 */
 512static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
 513                             const char *name, u32 length)
 514{
 515        encode_fhandle(xdr, fh);
 516        encode_filename(xdr, name, length);
 517}
 518
 519/*
 520 * 2.3.11.  diropres
 521 *
 522 *      union diropres switch (stat status) {
 523 *      case NFS_OK:
 524 *              struct {
 525 *                      fhandle file;
 526 *                      fattr   attributes;
 527 *              } diropok;
 528 *      default:
 529 *              void;
 530 *      };
 531 */
 532static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
 533{
 534        int error;
 535
 536        error = decode_fhandle(xdr, result->fh);
 537        if (unlikely(error))
 538                goto out;
 539        error = decode_fattr(xdr, result->fattr);
 540out:
 541        return error;
 542}
 543
 544static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
 545{
 546        enum nfs_stat status;
 547        int error;
 548
 549        error = decode_stat(xdr, &status);
 550        if (unlikely(error))
 551                goto out;
 552        if (status != NFS_OK)
 553                goto out_default;
 554        error = decode_diropok(xdr, result);
 555out:
 556        return error;
 557out_default:
 558        return nfs_stat_to_errno(status);
 559}
 560
 561
 562/*
 563 * NFSv2 XDR encode functions
 564 *
 565 * NFSv2 argument types are defined in section 2.2 of RFC 1094:
 566 * "NFS: Network File System Protocol Specification".
 567 */
 568
 569static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
 570                                 struct xdr_stream *xdr,
 571                                 const void *data)
 572{
 573        const struct nfs_fh *fh = data;
 574
 575        encode_fhandle(xdr, fh);
 576}
 577
 578/*
 579 * 2.2.3.  sattrargs
 580 *
 581 *      struct sattrargs {
 582 *              fhandle file;
 583 *              sattr attributes;
 584 *      };
 585 */
 586static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
 587                                   struct xdr_stream *xdr,
 588                                   const void *data)
 589{
 590        const struct nfs_sattrargs *args = data;
 591
 592        encode_fhandle(xdr, args->fh);
 593        encode_sattr(xdr, args->sattr);
 594}
 595
 596static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
 597                                   struct xdr_stream *xdr,
 598                                   const void *data)
 599{
 600        const struct nfs_diropargs *args = data;
 601
 602        encode_diropargs(xdr, args->fh, args->name, args->len);
 603}
 604
 605static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
 606                                      struct xdr_stream *xdr,
 607                                      const void *data)
 608{
 609        const struct nfs_readlinkargs *args = data;
 610
 611        encode_fhandle(xdr, args->fh);
 612        prepare_reply_buffer(req, args->pages, args->pgbase,
 613                                        args->pglen, NFS_readlinkres_sz);
 614}
 615
 616/*
 617 * 2.2.7.  readargs
 618 *
 619 *      struct readargs {
 620 *              fhandle file;
 621 *              unsigned offset;
 622 *              unsigned count;
 623 *              unsigned totalcount;
 624 *      };
 625 */
 626static void encode_readargs(struct xdr_stream *xdr,
 627                            const struct nfs_pgio_args *args)
 628{
 629        u32 offset = args->offset;
 630        u32 count = args->count;
 631        __be32 *p;
 632
 633        encode_fhandle(xdr, args->fh);
 634
 635        p = xdr_reserve_space(xdr, 4 + 4 + 4);
 636        *p++ = cpu_to_be32(offset);
 637        *p++ = cpu_to_be32(count);
 638        *p = cpu_to_be32(count);
 639}
 640
 641static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
 642                                  struct xdr_stream *xdr,
 643                                  const void *data)
 644{
 645        const struct nfs_pgio_args *args = data;
 646
 647        encode_readargs(xdr, args);
 648        prepare_reply_buffer(req, args->pages, args->pgbase,
 649                                        args->count, NFS_readres_sz);
 650        req->rq_rcv_buf.flags |= XDRBUF_READ;
 651}
 652
 653/*
 654 * 2.2.9.  writeargs
 655 *
 656 *      struct writeargs {
 657 *              fhandle file;
 658 *              unsigned beginoffset;
 659 *              unsigned offset;
 660 *              unsigned totalcount;
 661 *              nfsdata data;
 662 *      };
 663 */
 664static void encode_writeargs(struct xdr_stream *xdr,
 665                             const struct nfs_pgio_args *args)
 666{
 667        u32 offset = args->offset;
 668        u32 count = args->count;
 669        __be32 *p;
 670
 671        encode_fhandle(xdr, args->fh);
 672
 673        p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
 674        *p++ = cpu_to_be32(offset);
 675        *p++ = cpu_to_be32(offset);
 676        *p++ = cpu_to_be32(count);
 677
 678        /* nfsdata */
 679        *p = cpu_to_be32(count);
 680        xdr_write_pages(xdr, args->pages, args->pgbase, count);
 681}
 682
 683static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
 684                                   struct xdr_stream *xdr,
 685                                   const void *data)
 686{
 687        const struct nfs_pgio_args *args = data;
 688
 689        encode_writeargs(xdr, args);
 690        xdr->buf->flags |= XDRBUF_WRITE;
 691}
 692
 693/*
 694 * 2.2.10.  createargs
 695 *
 696 *      struct createargs {
 697 *              diropargs where;
 698 *              sattr attributes;
 699 *      };
 700 */
 701static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
 702                                    struct xdr_stream *xdr,
 703                                    const void *data)
 704{
 705        const struct nfs_createargs *args = data;
 706
 707        encode_diropargs(xdr, args->fh, args->name, args->len);
 708        encode_sattr(xdr, args->sattr);
 709}
 710
 711static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
 712                                    struct xdr_stream *xdr,
 713                                    const void *data)
 714{
 715        const struct nfs_removeargs *args = data;
 716
 717        encode_diropargs(xdr, args->fh, args->name.name, args->name.len);
 718}
 719
 720/*
 721 * 2.2.12.  renameargs
 722 *
 723 *      struct renameargs {
 724 *              diropargs from;
 725 *              diropargs to;
 726 *      };
 727 */
 728static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
 729                                    struct xdr_stream *xdr,
 730                                    const void *data)
 731{
 732        const struct nfs_renameargs *args = data;
 733        const struct qstr *old = args->old_name;
 734        const struct qstr *new = args->new_name;
 735
 736        encode_diropargs(xdr, args->old_dir, old->name, old->len);
 737        encode_diropargs(xdr, args->new_dir, new->name, new->len);
 738}
 739
 740/*
 741 * 2.2.13.  linkargs
 742 *
 743 *      struct linkargs {
 744 *              fhandle from;
 745 *              diropargs to;
 746 *      };
 747 */
 748static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
 749                                  struct xdr_stream *xdr,
 750                                  const void *data)
 751{
 752        const struct nfs_linkargs *args = data;
 753
 754        encode_fhandle(xdr, args->fromfh);
 755        encode_diropargs(xdr, args->tofh, args->toname, args->tolen);
 756}
 757
 758/*
 759 * 2.2.14.  symlinkargs
 760 *
 761 *      struct symlinkargs {
 762 *              diropargs from;
 763 *              path to;
 764 *              sattr attributes;
 765 *      };
 766 */
 767static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
 768                                     struct xdr_stream *xdr,
 769                                     const void *data)
 770{
 771        const struct nfs_symlinkargs *args = data;
 772
 773        encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
 774        encode_path(xdr, args->pages, args->pathlen);
 775        encode_sattr(xdr, args->sattr);
 776}
 777
 778/*
 779 * 2.2.17.  readdirargs
 780 *
 781 *      struct readdirargs {
 782 *              fhandle dir;
 783 *              nfscookie cookie;
 784 *              unsigned count;
 785 *      };
 786 */
 787static void encode_readdirargs(struct xdr_stream *xdr,
 788                               const struct nfs_readdirargs *args)
 789{
 790        __be32 *p;
 791
 792        encode_fhandle(xdr, args->fh);
 793
 794        p = xdr_reserve_space(xdr, 4 + 4);
 795        *p++ = cpu_to_be32(args->cookie);
 796        *p = cpu_to_be32(args->count);
 797}
 798
 799static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
 800                                     struct xdr_stream *xdr,
 801                                     const void *data)
 802{
 803        const struct nfs_readdirargs *args = data;
 804
 805        encode_readdirargs(xdr, args);
 806        prepare_reply_buffer(req, args->pages, 0,
 807                                        args->count, NFS_readdirres_sz);
 808}
 809
 810/*
 811 * NFSv2 XDR decode functions
 812 *
 813 * NFSv2 result types are defined in section 2.2 of RFC 1094:
 814 * "NFS: Network File System Protocol Specification".
 815 */
 816
 817static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
 818                             void *__unused)
 819{
 820        enum nfs_stat status;
 821        int error;
 822
 823        error = decode_stat(xdr, &status);
 824        if (unlikely(error))
 825                goto out;
 826        if (status != NFS_OK)
 827                goto out_default;
 828out:
 829        return error;
 830out_default:
 831        return nfs_stat_to_errno(status);
 832}
 833
 834static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
 835                                 void *result)
 836{
 837        return decode_attrstat(xdr, result, NULL);
 838}
 839
 840static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
 841                                 void *result)
 842{
 843        return decode_diropres(xdr, result);
 844}
 845
 846/*
 847 * 2.2.6.  readlinkres
 848 *
 849 *      union readlinkres switch (stat status) {
 850 *      case NFS_OK:
 851 *              path data;
 852 *      default:
 853 *              void;
 854 *      };
 855 */
 856static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
 857                                    struct xdr_stream *xdr, void *__unused)
 858{
 859        enum nfs_stat status;
 860        int error;
 861
 862        error = decode_stat(xdr, &status);
 863        if (unlikely(error))
 864                goto out;
 865        if (status != NFS_OK)
 866                goto out_default;
 867        error = decode_path(xdr);
 868out:
 869        return error;
 870out_default:
 871        return nfs_stat_to_errno(status);
 872}
 873
 874/*
 875 * 2.2.7.  readres
 876 *
 877 *      union readres switch (stat status) {
 878 *      case NFS_OK:
 879 *              fattr attributes;
 880 *              nfsdata data;
 881 *      default:
 882 *              void;
 883 *      };
 884 */
 885static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
 886                                void *data)
 887{
 888        struct nfs_pgio_res *result = data;
 889        enum nfs_stat status;
 890        int error;
 891
 892        error = decode_stat(xdr, &status);
 893        if (unlikely(error))
 894                goto out;
 895        result->op_status = status;
 896        if (status != NFS_OK)
 897                goto out_default;
 898        error = decode_fattr(xdr, result->fattr);
 899        if (unlikely(error))
 900                goto out;
 901        error = decode_nfsdata(xdr, result);
 902out:
 903        return error;
 904out_default:
 905        return nfs_stat_to_errno(status);
 906}
 907
 908static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
 909                                 void *data)
 910{
 911        struct nfs_pgio_res *result = data;
 912
 913        /* All NFSv2 writes are "file sync" writes */
 914        result->verf->committed = NFS_FILE_SYNC;
 915        return decode_attrstat(xdr, result->fattr, &result->op_status);
 916}
 917
 918/**
 919 * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
 920 *                      the local page cache.
 921 * @xdr: XDR stream where entry resides
 922 * @entry: buffer to fill in with entry data
 923 * @plus: boolean indicating whether this should be a readdirplus entry
 924 *
 925 * Returns zero if successful, otherwise a negative errno value is
 926 * returned.
 927 *
 928 * This function is not invoked during READDIR reply decoding, but
 929 * rather whenever an application invokes the getdents(2) system call
 930 * on a directory already in our cache.
 931 *
 932 * 2.2.17.  entry
 933 *
 934 *      struct entry {
 935 *              unsigned        fileid;
 936 *              filename        name;
 937 *              nfscookie       cookie;
 938 *              entry           *nextentry;
 939 *      };
 940 */
 941int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
 942                       bool plus)
 943{
 944        __be32 *p;
 945        int error;
 946
 947        p = xdr_inline_decode(xdr, 4);
 948        if (unlikely(p == NULL))
 949                goto out_overflow;
 950        if (*p++ == xdr_zero) {
 951                p = xdr_inline_decode(xdr, 4);
 952                if (unlikely(p == NULL))
 953                        goto out_overflow;
 954                if (*p++ == xdr_zero)
 955                        return -EAGAIN;
 956                entry->eof = 1;
 957                return -EBADCOOKIE;
 958        }
 959
 960        p = xdr_inline_decode(xdr, 4);
 961        if (unlikely(p == NULL))
 962                goto out_overflow;
 963        entry->ino = be32_to_cpup(p);
 964
 965        error = decode_filename_inline(xdr, &entry->name, &entry->len);
 966        if (unlikely(error))
 967                return error;
 968
 969        /*
 970         * The type (size and byte order) of nfscookie isn't defined in
 971         * RFC 1094.  This implementation assumes that it's an XDR uint32.
 972         */
 973        entry->prev_cookie = entry->cookie;
 974        p = xdr_inline_decode(xdr, 4);
 975        if (unlikely(p == NULL))
 976                goto out_overflow;
 977        entry->cookie = be32_to_cpup(p);
 978
 979        entry->d_type = DT_UNKNOWN;
 980
 981        return 0;
 982
 983out_overflow:
 984        print_overflow_msg(__func__, xdr);
 985        return -EAGAIN;
 986}
 987
 988/*
 989 * 2.2.17.  readdirres
 990 *
 991 *      union readdirres switch (stat status) {
 992 *      case NFS_OK:
 993 *              struct {
 994 *                      entry *entries;
 995 *                      bool eof;
 996 *              } readdirok;
 997 *      default:
 998 *              void;
 999 *      };
1000 *
1001 * Read the directory contents into the page cache, but don't
1002 * touch them.  The actual decoding is done by nfs2_decode_dirent()
1003 * during subsequent nfs_readdir() calls.
1004 */
1005static int decode_readdirok(struct xdr_stream *xdr)
1006{
1007        return xdr_read_pages(xdr, xdr->buf->page_len);
1008}
1009
1010static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
1011                                   struct xdr_stream *xdr, void *__unused)
1012{
1013        enum nfs_stat status;
1014        int error;
1015
1016        error = decode_stat(xdr, &status);
1017        if (unlikely(error))
1018                goto out;
1019        if (status != NFS_OK)
1020                goto out_default;
1021        error = decode_readdirok(xdr);
1022out:
1023        return error;
1024out_default:
1025        return nfs_stat_to_errno(status);
1026}
1027
1028/*
1029 * 2.2.18.  statfsres
1030 *
1031 *      union statfsres (stat status) {
1032 *      case NFS_OK:
1033 *              struct {
1034 *                      unsigned tsize;
1035 *                      unsigned bsize;
1036 *                      unsigned blocks;
1037 *                      unsigned bfree;
1038 *                      unsigned bavail;
1039 *              } info;
1040 *      default:
1041 *              void;
1042 *      };
1043 */
1044static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
1045{
1046        __be32 *p;
1047
1048        p = xdr_inline_decode(xdr, NFS_info_sz << 2);
1049        if (unlikely(p == NULL))
1050                goto out_overflow;
1051        result->tsize  = be32_to_cpup(p++);
1052        result->bsize  = be32_to_cpup(p++);
1053        result->blocks = be32_to_cpup(p++);
1054        result->bfree  = be32_to_cpup(p++);
1055        result->bavail = be32_to_cpup(p);
1056        return 0;
1057out_overflow:
1058        print_overflow_msg(__func__, xdr);
1059        return -EIO;
1060}
1061
1062static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
1063                                  void *result)
1064{
1065        enum nfs_stat status;
1066        int error;
1067
1068        error = decode_stat(xdr, &status);
1069        if (unlikely(error))
1070                goto out;
1071        if (status != NFS_OK)
1072                goto out_default;
1073        error = decode_info(xdr, result);
1074out:
1075        return error;
1076out_default:
1077        return nfs_stat_to_errno(status);
1078}
1079
1080
1081/*
1082 * We need to translate between nfs status return values and
1083 * the local errno values which may not be the same.
1084 */
1085static const struct {
1086        int stat;
1087        int errno;
1088} nfs_errtbl[] = {
1089        { NFS_OK,               0               },
1090        { NFSERR_PERM,          -EPERM          },
1091        { NFSERR_NOENT,         -ENOENT         },
1092        { NFSERR_IO,            -errno_NFSERR_IO},
1093        { NFSERR_NXIO,          -ENXIO          },
1094/*      { NFSERR_EAGAIN,        -EAGAIN         }, */
1095        { NFSERR_ACCES,         -EACCES         },
1096        { NFSERR_EXIST,         -EEXIST         },
1097        { NFSERR_XDEV,          -EXDEV          },
1098        { NFSERR_NODEV,         -ENODEV         },
1099        { NFSERR_NOTDIR,        -ENOTDIR        },
1100        { NFSERR_ISDIR,         -EISDIR         },
1101        { NFSERR_INVAL,         -EINVAL         },
1102        { NFSERR_FBIG,          -EFBIG          },
1103        { NFSERR_NOSPC,         -ENOSPC         },
1104        { NFSERR_ROFS,          -EROFS          },
1105        { NFSERR_MLINK,         -EMLINK         },
1106        { NFSERR_NAMETOOLONG,   -ENAMETOOLONG   },
1107        { NFSERR_NOTEMPTY,      -ENOTEMPTY      },
1108        { NFSERR_DQUOT,         -EDQUOT         },
1109        { NFSERR_STALE,         -ESTALE         },
1110        { NFSERR_REMOTE,        -EREMOTE        },
1111#ifdef EWFLUSH
1112        { NFSERR_WFLUSH,        -EWFLUSH        },
1113#endif
1114        { NFSERR_BADHANDLE,     -EBADHANDLE     },
1115        { NFSERR_NOT_SYNC,      -ENOTSYNC       },
1116        { NFSERR_BAD_COOKIE,    -EBADCOOKIE     },
1117        { NFSERR_NOTSUPP,       -ENOTSUPP       },
1118        { NFSERR_TOOSMALL,      -ETOOSMALL      },
1119        { NFSERR_SERVERFAULT,   -EREMOTEIO      },
1120        { NFSERR_BADTYPE,       -EBADTYPE       },
1121        { NFSERR_JUKEBOX,       -EJUKEBOX       },
1122        { -1,                   -EIO            }
1123};
1124
1125/**
1126 * nfs_stat_to_errno - convert an NFS status code to a local errno
1127 * @status: NFS status code to convert
1128 *
1129 * Returns a local errno value, or -EIO if the NFS status code is
1130 * not recognized.  This function is used jointly by NFSv2 and NFSv3.
1131 */
1132static int nfs_stat_to_errno(enum nfs_stat status)
1133{
1134        int i;
1135
1136        for (i = 0; nfs_errtbl[i].stat != -1; i++) {
1137                if (nfs_errtbl[i].stat == (int)status)
1138                        return nfs_errtbl[i].errno;
1139        }
1140        dprintk("NFS: Unrecognized nfs status value: %u\n", status);
1141        return nfs_errtbl[i].errno;
1142}
1143
1144#define PROC(proc, argtype, restype, timer)                             \
1145[NFSPROC_##proc] = {                                                    \
1146        .p_proc     =  NFSPROC_##proc,                                  \
1147        .p_encode   =  nfs2_xdr_enc_##argtype,                          \
1148        .p_decode   =  nfs2_xdr_dec_##restype,                          \
1149        .p_arglen   =  NFS_##argtype##_sz,                              \
1150        .p_replen   =  NFS_##restype##_sz,                              \
1151        .p_timer    =  timer,                                           \
1152        .p_statidx  =  NFSPROC_##proc,                                  \
1153        .p_name     =  #proc,                                           \
1154        }
1155const struct rpc_procinfo nfs_procedures[] = {
1156        PROC(GETATTR,   fhandle,        attrstat,       1),
1157        PROC(SETATTR,   sattrargs,      attrstat,       0),
1158        PROC(LOOKUP,    diropargs,      diropres,       2),
1159        PROC(READLINK,  readlinkargs,   readlinkres,    3),
1160        PROC(READ,      readargs,       readres,        3),
1161        PROC(WRITE,     writeargs,      writeres,       4),
1162        PROC(CREATE,    createargs,     diropres,       0),
1163        PROC(REMOVE,    removeargs,     stat,           0),
1164        PROC(RENAME,    renameargs,     stat,           0),
1165        PROC(LINK,      linkargs,       stat,           0),
1166        PROC(SYMLINK,   symlinkargs,    stat,           0),
1167        PROC(MKDIR,     createargs,     diropres,       0),
1168        PROC(RMDIR,     diropargs,      stat,           0),
1169        PROC(READDIR,   readdirargs,    readdirres,     3),
1170        PROC(STATFS,    fhandle,        statfsres,      0),
1171};
1172
1173static unsigned int nfs_version2_counts[ARRAY_SIZE(nfs_procedures)];
1174const struct rpc_version nfs_version2 = {
1175        .number                 = 2,
1176        .nrprocs                = ARRAY_SIZE(nfs_procedures),
1177        .procs                  = nfs_procedures,
1178        .counts                 = nfs_version2_counts,
1179};
1180