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