linux/fs/nfsd/nfs4xdr.c
<<
>>
Prefs
   1/*
   2 *  Server-side XDR for NFSv4
   3 *
   4 *  Copyright (c) 2002 The Regents of the University of Michigan.
   5 *  All rights reserved.
   6 *
   7 *  Kendrick Smith <kmsmith@umich.edu>
   8 *  Andy Adamson   <andros@umich.edu>
   9 *
  10 *  Redistribution and use in source and binary forms, with or without
  11 *  modification, are permitted provided that the following conditions
  12 *  are met:
  13 *
  14 *  1. Redistributions of source code must retain the above copyright
  15 *     notice, this list of conditions and the following disclaimer.
  16 *  2. Redistributions in binary form must reproduce the above copyright
  17 *     notice, this list of conditions and the following disclaimer in the
  18 *     documentation and/or other materials provided with the distribution.
  19 *  3. Neither the name of the University nor the names of its
  20 *     contributors may be used to endorse or promote products derived
  21 *     from this software without specific prior written permission.
  22 *
  23 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  24 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  25 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  30 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34 */
  35
  36#include <linux/file.h>
  37#include <linux/slab.h>
  38#include <linux/namei.h>
  39#include <linux/statfs.h>
  40#include <linux/utsname.h>
  41#include <linux/pagemap.h>
  42#include <linux/sunrpc/svcauth_gss.h>
  43#include <linux/sunrpc/addr.h>
  44
  45#include "idmap.h"
  46#include "acl.h"
  47#include "xdr4.h"
  48#include "vfs.h"
  49#include "state.h"
  50#include "cache.h"
  51#include "netns.h"
  52#include "pnfs.h"
  53#include "filecache.h"
  54
  55#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
  56#include <linux/security.h>
  57#endif
  58
  59
  60#define NFSDDBG_FACILITY                NFSDDBG_XDR
  61
  62const u32 nfsd_suppattrs[3][3] = {
  63        {NFSD4_SUPPORTED_ATTRS_WORD0,
  64         NFSD4_SUPPORTED_ATTRS_WORD1,
  65         NFSD4_SUPPORTED_ATTRS_WORD2},
  66
  67        {NFSD4_1_SUPPORTED_ATTRS_WORD0,
  68         NFSD4_1_SUPPORTED_ATTRS_WORD1,
  69         NFSD4_1_SUPPORTED_ATTRS_WORD2},
  70
  71        {NFSD4_1_SUPPORTED_ATTRS_WORD0,
  72         NFSD4_1_SUPPORTED_ATTRS_WORD1,
  73         NFSD4_2_SUPPORTED_ATTRS_WORD2},
  74};
  75
  76/*
  77 * As per referral draft, the fsid for a referral MUST be different from the fsid of the containing
  78 * directory in order to indicate to the client that a filesystem boundary is present
  79 * We use a fixed fsid for a referral
  80 */
  81#define NFS4_REFERRAL_FSID_MAJOR        0x8000000ULL
  82#define NFS4_REFERRAL_FSID_MINOR        0x8000000ULL
  83
  84static __be32
  85check_filename(char *str, int len)
  86{
  87        int i;
  88
  89        if (len == 0)
  90                return nfserr_inval;
  91        if (isdotent(str, len))
  92                return nfserr_badname;
  93        for (i = 0; i < len; i++)
  94                if (str[i] == '/')
  95                        return nfserr_badname;
  96        return 0;
  97}
  98
  99#define DECODE_HEAD                             \
 100        __be32 *p;                              \
 101        __be32 status
 102#define DECODE_TAIL                             \
 103        status = 0;                             \
 104out:                                            \
 105        return status;                          \
 106xdr_error:                                      \
 107        dprintk("NFSD: xdr error (%s:%d)\n",    \
 108                        __FILE__, __LINE__);    \
 109        status = nfserr_bad_xdr;                \
 110        goto out
 111
 112#define READMEM(x,nbytes) do {                  \
 113        x = (char *)p;                          \
 114        p += XDR_QUADLEN(nbytes);               \
 115} while (0)
 116#define SAVEMEM(x,nbytes) do {                  \
 117        if (!(x = (p==argp->tmp || p == argp->tmpp) ? \
 118                savemem(argp, p, nbytes) :      \
 119                (char *)p)) {                   \
 120                dprintk("NFSD: xdr error (%s:%d)\n", \
 121                                __FILE__, __LINE__); \
 122                goto xdr_error;                 \
 123                }                               \
 124        p += XDR_QUADLEN(nbytes);               \
 125} while (0)
 126#define COPYMEM(x,nbytes) do {                  \
 127        memcpy((x), p, nbytes);                 \
 128        p += XDR_QUADLEN(nbytes);               \
 129} while (0)
 130
 131/* READ_BUF, read_buf(): nbytes must be <= PAGE_SIZE */
 132#define READ_BUF(nbytes)  do {                  \
 133        if (nbytes <= (u32)((char *)argp->end - (char *)argp->p)) {     \
 134                p = argp->p;                    \
 135                argp->p += XDR_QUADLEN(nbytes); \
 136        } else if (!(p = read_buf(argp, nbytes))) { \
 137                dprintk("NFSD: xdr error (%s:%d)\n", \
 138                                __FILE__, __LINE__); \
 139                goto xdr_error;                 \
 140        }                                       \
 141} while (0)
 142
 143static void next_decode_page(struct nfsd4_compoundargs *argp)
 144{
 145        argp->p = page_address(argp->pagelist[0]);
 146        argp->pagelist++;
 147        if (argp->pagelen < PAGE_SIZE) {
 148                argp->end = argp->p + XDR_QUADLEN(argp->pagelen);
 149                argp->pagelen = 0;
 150        } else {
 151                argp->end = argp->p + (PAGE_SIZE>>2);
 152                argp->pagelen -= PAGE_SIZE;
 153        }
 154}
 155
 156static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
 157{
 158        /* We want more bytes than seem to be available.
 159         * Maybe we need a new page, maybe we have just run out
 160         */
 161        unsigned int avail = (char *)argp->end - (char *)argp->p;
 162        __be32 *p;
 163
 164        if (argp->pagelen == 0) {
 165                struct kvec *vec = &argp->rqstp->rq_arg.tail[0];
 166
 167                if (!argp->tail) {
 168                        argp->tail = true;
 169                        avail = vec->iov_len;
 170                        argp->p = vec->iov_base;
 171                        argp->end = vec->iov_base + avail;
 172                }
 173
 174                if (avail < nbytes)
 175                        return NULL;
 176
 177                p = argp->p;
 178                argp->p += XDR_QUADLEN(nbytes);
 179                return p;
 180        }
 181
 182        if (avail + argp->pagelen < nbytes)
 183                return NULL;
 184        if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
 185                return NULL;
 186        /* ok, we can do it with the current plus the next page */
 187        if (nbytes <= sizeof(argp->tmp))
 188                p = argp->tmp;
 189        else {
 190                kfree(argp->tmpp);
 191                p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
 192                if (!p)
 193                        return NULL;
 194                
 195        }
 196        /*
 197         * The following memcpy is safe because read_buf is always
 198         * called with nbytes > avail, and the two cases above both
 199         * guarantee p points to at least nbytes bytes.
 200         */
 201        memcpy(p, argp->p, avail);
 202        next_decode_page(argp);
 203        memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
 204        argp->p += XDR_QUADLEN(nbytes - avail);
 205        return p;
 206}
 207
 208static unsigned int compoundargs_bytes_left(struct nfsd4_compoundargs *argp)
 209{
 210        unsigned int this = (char *)argp->end - (char *)argp->p;
 211
 212        return this + argp->pagelen;
 213}
 214
 215static int zero_clientid(clientid_t *clid)
 216{
 217        return (clid->cl_boot == 0) && (clid->cl_id == 0);
 218}
 219
 220/**
 221 * svcxdr_tmpalloc - allocate memory to be freed after compound processing
 222 * @argp: NFSv4 compound argument structure
 223 * @len: length of buffer to allocate
 224 *
 225 * Allocates a buffer of size @len to be freed when processing the compound
 226 * operation described in @argp finishes.
 227 */
 228static void *
 229svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
 230{
 231        struct svcxdr_tmpbuf *tb;
 232
 233        tb = kmalloc(sizeof(*tb) + len, GFP_KERNEL);
 234        if (!tb)
 235                return NULL;
 236        tb->next = argp->to_free;
 237        argp->to_free = tb;
 238        return tb->buf;
 239}
 240
 241/*
 242 * For xdr strings that need to be passed to other kernel api's
 243 * as null-terminated strings.
 244 *
 245 * Note null-terminating in place usually isn't safe since the
 246 * buffer might end on a page boundary.
 247 */
 248static char *
 249svcxdr_dupstr(struct nfsd4_compoundargs *argp, void *buf, u32 len)
 250{
 251        char *p = svcxdr_tmpalloc(argp, len + 1);
 252
 253        if (!p)
 254                return NULL;
 255        memcpy(p, buf, len);
 256        p[len] = '\0';
 257        return p;
 258}
 259
 260/**
 261 * savemem - duplicate a chunk of memory for later processing
 262 * @argp: NFSv4 compound argument structure to be freed with
 263 * @p: pointer to be duplicated
 264 * @nbytes: length to be duplicated
 265 *
 266 * Returns a pointer to a copy of @nbytes bytes of memory at @p
 267 * that are preserved until processing of the NFSv4 compound
 268 * operation described by @argp finishes.
 269 */
 270static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
 271{
 272        void *ret;
 273
 274        ret = svcxdr_tmpalloc(argp, nbytes);
 275        if (!ret)
 276                return NULL;
 277        memcpy(ret, p, nbytes);
 278        return ret;
 279}
 280
 281static __be32
 282nfsd4_decode_time(struct nfsd4_compoundargs *argp, struct timespec64 *tv)
 283{
 284        DECODE_HEAD;
 285
 286        READ_BUF(12);
 287        p = xdr_decode_hyper(p, &tv->tv_sec);
 288        tv->tv_nsec = be32_to_cpup(p++);
 289        if (tv->tv_nsec >= (u32)1000000000)
 290                return nfserr_inval;
 291
 292        DECODE_TAIL;
 293}
 294
 295static __be32
 296nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
 297{
 298        u32 bmlen;
 299        DECODE_HEAD;
 300
 301        bmval[0] = 0;
 302        bmval[1] = 0;
 303        bmval[2] = 0;
 304
 305        READ_BUF(4);
 306        bmlen = be32_to_cpup(p++);
 307        if (bmlen > 1000)
 308                goto xdr_error;
 309
 310        READ_BUF(bmlen << 2);
 311        if (bmlen > 0)
 312                bmval[0] = be32_to_cpup(p++);
 313        if (bmlen > 1)
 314                bmval[1] = be32_to_cpup(p++);
 315        if (bmlen > 2)
 316                bmval[2] = be32_to_cpup(p++);
 317
 318        DECODE_TAIL;
 319}
 320
 321static __be32
 322nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
 323                   struct iattr *iattr, struct nfs4_acl **acl,
 324                   struct xdr_netobj *label, int *umask)
 325{
 326        int expected_len, len = 0;
 327        u32 dummy32;
 328        char *buf;
 329
 330        DECODE_HEAD;
 331        iattr->ia_valid = 0;
 332        if ((status = nfsd4_decode_bitmap(argp, bmval)))
 333                return status;
 334
 335        if (bmval[0] & ~NFSD_WRITEABLE_ATTRS_WORD0
 336            || bmval[1] & ~NFSD_WRITEABLE_ATTRS_WORD1
 337            || bmval[2] & ~NFSD_WRITEABLE_ATTRS_WORD2) {
 338                if (nfsd_attrs_supported(argp->minorversion, bmval))
 339                        return nfserr_inval;
 340                return nfserr_attrnotsupp;
 341        }
 342
 343        READ_BUF(4);
 344        expected_len = be32_to_cpup(p++);
 345
 346        if (bmval[0] & FATTR4_WORD0_SIZE) {
 347                READ_BUF(8);
 348                len += 8;
 349                p = xdr_decode_hyper(p, &iattr->ia_size);
 350                iattr->ia_valid |= ATTR_SIZE;
 351        }
 352        if (bmval[0] & FATTR4_WORD0_ACL) {
 353                u32 nace;
 354                struct nfs4_ace *ace;
 355
 356                READ_BUF(4); len += 4;
 357                nace = be32_to_cpup(p++);
 358
 359                if (nace > compoundargs_bytes_left(argp)/20)
 360                        /*
 361                         * Even with 4-byte names there wouldn't be
 362                         * space for that many aces; something fishy is
 363                         * going on:
 364                         */
 365                        return nfserr_fbig;
 366
 367                *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
 368                if (*acl == NULL)
 369                        return nfserr_jukebox;
 370
 371                (*acl)->naces = nace;
 372                for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) {
 373                        READ_BUF(16); len += 16;
 374                        ace->type = be32_to_cpup(p++);
 375                        ace->flag = be32_to_cpup(p++);
 376                        ace->access_mask = be32_to_cpup(p++);
 377                        dummy32 = be32_to_cpup(p++);
 378                        READ_BUF(dummy32);
 379                        len += XDR_QUADLEN(dummy32) << 2;
 380                        READMEM(buf, dummy32);
 381                        ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
 382                        status = nfs_ok;
 383                        if (ace->whotype != NFS4_ACL_WHO_NAMED)
 384                                ;
 385                        else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
 386                                status = nfsd_map_name_to_gid(argp->rqstp,
 387                                                buf, dummy32, &ace->who_gid);
 388                        else
 389                                status = nfsd_map_name_to_uid(argp->rqstp,
 390                                                buf, dummy32, &ace->who_uid);
 391                        if (status)
 392                                return status;
 393                }
 394        } else
 395                *acl = NULL;
 396        if (bmval[1] & FATTR4_WORD1_MODE) {
 397                READ_BUF(4);
 398                len += 4;
 399                iattr->ia_mode = be32_to_cpup(p++);
 400                iattr->ia_mode &= (S_IFMT | S_IALLUGO);
 401                iattr->ia_valid |= ATTR_MODE;
 402        }
 403        if (bmval[1] & FATTR4_WORD1_OWNER) {
 404                READ_BUF(4);
 405                len += 4;
 406                dummy32 = be32_to_cpup(p++);
 407                READ_BUF(dummy32);
 408                len += (XDR_QUADLEN(dummy32) << 2);
 409                READMEM(buf, dummy32);
 410                if ((status = nfsd_map_name_to_uid(argp->rqstp, buf, dummy32, &iattr->ia_uid)))
 411                        return status;
 412                iattr->ia_valid |= ATTR_UID;
 413        }
 414        if (bmval[1] & FATTR4_WORD1_OWNER_GROUP) {
 415                READ_BUF(4);
 416                len += 4;
 417                dummy32 = be32_to_cpup(p++);
 418                READ_BUF(dummy32);
 419                len += (XDR_QUADLEN(dummy32) << 2);
 420                READMEM(buf, dummy32);
 421                if ((status = nfsd_map_name_to_gid(argp->rqstp, buf, dummy32, &iattr->ia_gid)))
 422                        return status;
 423                iattr->ia_valid |= ATTR_GID;
 424        }
 425        if (bmval[1] & FATTR4_WORD1_TIME_ACCESS_SET) {
 426                READ_BUF(4);
 427                len += 4;
 428                dummy32 = be32_to_cpup(p++);
 429                switch (dummy32) {
 430                case NFS4_SET_TO_CLIENT_TIME:
 431                        len += 12;
 432                        status = nfsd4_decode_time(argp, &iattr->ia_atime);
 433                        if (status)
 434                                return status;
 435                        iattr->ia_valid |= (ATTR_ATIME | ATTR_ATIME_SET);
 436                        break;
 437                case NFS4_SET_TO_SERVER_TIME:
 438                        iattr->ia_valid |= ATTR_ATIME;
 439                        break;
 440                default:
 441                        goto xdr_error;
 442                }
 443        }
 444        if (bmval[1] & FATTR4_WORD1_TIME_MODIFY_SET) {
 445                READ_BUF(4);
 446                len += 4;
 447                dummy32 = be32_to_cpup(p++);
 448                switch (dummy32) {
 449                case NFS4_SET_TO_CLIENT_TIME:
 450                        len += 12;
 451                        status = nfsd4_decode_time(argp, &iattr->ia_mtime);
 452                        if (status)
 453                                return status;
 454                        iattr->ia_valid |= (ATTR_MTIME | ATTR_MTIME_SET);
 455                        break;
 456                case NFS4_SET_TO_SERVER_TIME:
 457                        iattr->ia_valid |= ATTR_MTIME;
 458                        break;
 459                default:
 460                        goto xdr_error;
 461                }
 462        }
 463
 464        label->len = 0;
 465        if (IS_ENABLED(CONFIG_NFSD_V4_SECURITY_LABEL) &&
 466            bmval[2] & FATTR4_WORD2_SECURITY_LABEL) {
 467                READ_BUF(4);
 468                len += 4;
 469                dummy32 = be32_to_cpup(p++); /* lfs: we don't use it */
 470                READ_BUF(4);
 471                len += 4;
 472                dummy32 = be32_to_cpup(p++); /* pi: we don't use it either */
 473                READ_BUF(4);
 474                len += 4;
 475                dummy32 = be32_to_cpup(p++);
 476                READ_BUF(dummy32);
 477                if (dummy32 > NFS4_MAXLABELLEN)
 478                        return nfserr_badlabel;
 479                len += (XDR_QUADLEN(dummy32) << 2);
 480                READMEM(buf, dummy32);
 481                label->len = dummy32;
 482                label->data = svcxdr_dupstr(argp, buf, dummy32);
 483                if (!label->data)
 484                        return nfserr_jukebox;
 485        }
 486        if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
 487                if (!umask)
 488                        goto xdr_error;
 489                READ_BUF(8);
 490                len += 8;
 491                dummy32 = be32_to_cpup(p++);
 492                iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO);
 493                dummy32 = be32_to_cpup(p++);
 494                *umask = dummy32 & S_IRWXUGO;
 495                iattr->ia_valid |= ATTR_MODE;
 496        }
 497        if (len != expected_len)
 498                goto xdr_error;
 499
 500        DECODE_TAIL;
 501}
 502
 503static __be32
 504nfsd4_decode_stateid(struct nfsd4_compoundargs *argp, stateid_t *sid)
 505{
 506        DECODE_HEAD;
 507
 508        READ_BUF(sizeof(stateid_t));
 509        sid->si_generation = be32_to_cpup(p++);
 510        COPYMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
 511
 512        DECODE_TAIL;
 513}
 514
 515static __be32
 516nfsd4_decode_access(struct nfsd4_compoundargs *argp, struct nfsd4_access *access)
 517{
 518        DECODE_HEAD;
 519
 520        READ_BUF(4);
 521        access->ac_req_access = be32_to_cpup(p++);
 522
 523        DECODE_TAIL;
 524}
 525
 526static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_cb_sec *cbs)
 527{
 528        DECODE_HEAD;
 529        struct user_namespace *userns = nfsd_user_namespace(argp->rqstp);
 530        u32 dummy, uid, gid;
 531        char *machine_name;
 532        int i;
 533        int nr_secflavs;
 534
 535        /* callback_sec_params4 */
 536        READ_BUF(4);
 537        nr_secflavs = be32_to_cpup(p++);
 538        if (nr_secflavs)
 539                cbs->flavor = (u32)(-1);
 540        else
 541                /* Is this legal? Be generous, take it to mean AUTH_NONE: */
 542                cbs->flavor = 0;
 543        for (i = 0; i < nr_secflavs; ++i) {
 544                READ_BUF(4);
 545                dummy = be32_to_cpup(p++);
 546                switch (dummy) {
 547                case RPC_AUTH_NULL:
 548                        /* Nothing to read */
 549                        if (cbs->flavor == (u32)(-1))
 550                                cbs->flavor = RPC_AUTH_NULL;
 551                        break;
 552                case RPC_AUTH_UNIX:
 553                        READ_BUF(8);
 554                        /* stamp */
 555                        dummy = be32_to_cpup(p++);
 556
 557                        /* machine name */
 558                        dummy = be32_to_cpup(p++);
 559                        READ_BUF(dummy);
 560                        SAVEMEM(machine_name, dummy);
 561
 562                        /* uid, gid */
 563                        READ_BUF(8);
 564                        uid = be32_to_cpup(p++);
 565                        gid = be32_to_cpup(p++);
 566
 567                        /* more gids */
 568                        READ_BUF(4);
 569                        dummy = be32_to_cpup(p++);
 570                        READ_BUF(dummy * 4);
 571                        if (cbs->flavor == (u32)(-1)) {
 572                                kuid_t kuid = make_kuid(userns, uid);
 573                                kgid_t kgid = make_kgid(userns, gid);
 574                                if (uid_valid(kuid) && gid_valid(kgid)) {
 575                                        cbs->uid = kuid;
 576                                        cbs->gid = kgid;
 577                                        cbs->flavor = RPC_AUTH_UNIX;
 578                                } else {
 579                                        dprintk("RPC_AUTH_UNIX with invalid"
 580                                                "uid or gid ignoring!\n");
 581                                }
 582                        }
 583                        break;
 584                case RPC_AUTH_GSS:
 585                        dprintk("RPC_AUTH_GSS callback secflavor "
 586                                "not supported!\n");
 587                        READ_BUF(8);
 588                        /* gcbp_service */
 589                        dummy = be32_to_cpup(p++);
 590                        /* gcbp_handle_from_server */
 591                        dummy = be32_to_cpup(p++);
 592                        READ_BUF(dummy);
 593                        p += XDR_QUADLEN(dummy);
 594                        /* gcbp_handle_from_client */
 595                        READ_BUF(4);
 596                        dummy = be32_to_cpup(p++);
 597                        READ_BUF(dummy);
 598                        break;
 599                default:
 600                        dprintk("Illegal callback secflavor\n");
 601                        return nfserr_inval;
 602                }
 603        }
 604        DECODE_TAIL;
 605}
 606
 607static __be32 nfsd4_decode_backchannel_ctl(struct nfsd4_compoundargs *argp, struct nfsd4_backchannel_ctl *bc)
 608{
 609        DECODE_HEAD;
 610
 611        READ_BUF(4);
 612        bc->bc_cb_program = be32_to_cpup(p++);
 613        nfsd4_decode_cb_sec(argp, &bc->bc_cb_sec);
 614
 615        DECODE_TAIL;
 616}
 617
 618static __be32 nfsd4_decode_bind_conn_to_session(struct nfsd4_compoundargs *argp, struct nfsd4_bind_conn_to_session *bcts)
 619{
 620        DECODE_HEAD;
 621
 622        READ_BUF(NFS4_MAX_SESSIONID_LEN + 8);
 623        COPYMEM(bcts->sessionid.data, NFS4_MAX_SESSIONID_LEN);
 624        bcts->dir = be32_to_cpup(p++);
 625        /* XXX: skipping ctsa_use_conn_in_rdma_mode.  Perhaps Tom Tucker
 626         * could help us figure out we should be using it. */
 627        DECODE_TAIL;
 628}
 629
 630static __be32
 631nfsd4_decode_close(struct nfsd4_compoundargs *argp, struct nfsd4_close *close)
 632{
 633        DECODE_HEAD;
 634
 635        READ_BUF(4);
 636        close->cl_seqid = be32_to_cpup(p++);
 637        return nfsd4_decode_stateid(argp, &close->cl_stateid);
 638
 639        DECODE_TAIL;
 640}
 641
 642
 643static __be32
 644nfsd4_decode_commit(struct nfsd4_compoundargs *argp, struct nfsd4_commit *commit)
 645{
 646        DECODE_HEAD;
 647
 648        READ_BUF(12);
 649        p = xdr_decode_hyper(p, &commit->co_offset);
 650        commit->co_count = be32_to_cpup(p++);
 651
 652        DECODE_TAIL;
 653}
 654
 655static __be32
 656nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create)
 657{
 658        DECODE_HEAD;
 659
 660        READ_BUF(4);
 661        create->cr_type = be32_to_cpup(p++);
 662        switch (create->cr_type) {
 663        case NF4LNK:
 664                READ_BUF(4);
 665                create->cr_datalen = be32_to_cpup(p++);
 666                READ_BUF(create->cr_datalen);
 667                create->cr_data = svcxdr_dupstr(argp, p, create->cr_datalen);
 668                if (!create->cr_data)
 669                        return nfserr_jukebox;
 670                break;
 671        case NF4BLK:
 672        case NF4CHR:
 673                READ_BUF(8);
 674                create->cr_specdata1 = be32_to_cpup(p++);
 675                create->cr_specdata2 = be32_to_cpup(p++);
 676                break;
 677        case NF4SOCK:
 678        case NF4FIFO:
 679        case NF4DIR:
 680        default:
 681                break;
 682        }
 683
 684        READ_BUF(4);
 685        create->cr_namelen = be32_to_cpup(p++);
 686        READ_BUF(create->cr_namelen);
 687        SAVEMEM(create->cr_name, create->cr_namelen);
 688        if ((status = check_filename(create->cr_name, create->cr_namelen)))
 689                return status;
 690
 691        status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
 692                                    &create->cr_acl, &create->cr_label,
 693                                    &create->cr_umask);
 694        if (status)
 695                goto out;
 696
 697        DECODE_TAIL;
 698}
 699
 700static inline __be32
 701nfsd4_decode_delegreturn(struct nfsd4_compoundargs *argp, struct nfsd4_delegreturn *dr)
 702{
 703        return nfsd4_decode_stateid(argp, &dr->dr_stateid);
 704}
 705
 706static inline __be32
 707nfsd4_decode_getattr(struct nfsd4_compoundargs *argp, struct nfsd4_getattr *getattr)
 708{
 709        return nfsd4_decode_bitmap(argp, getattr->ga_bmval);
 710}
 711
 712static __be32
 713nfsd4_decode_link(struct nfsd4_compoundargs *argp, struct nfsd4_link *link)
 714{
 715        DECODE_HEAD;
 716
 717        READ_BUF(4);
 718        link->li_namelen = be32_to_cpup(p++);
 719        READ_BUF(link->li_namelen);
 720        SAVEMEM(link->li_name, link->li_namelen);
 721        if ((status = check_filename(link->li_name, link->li_namelen)))
 722                return status;
 723
 724        DECODE_TAIL;
 725}
 726
 727static __be32
 728nfsd4_decode_lock(struct nfsd4_compoundargs *argp, struct nfsd4_lock *lock)
 729{
 730        DECODE_HEAD;
 731
 732        /*
 733        * type, reclaim(boolean), offset, length, new_lock_owner(boolean)
 734        */
 735        READ_BUF(28);
 736        lock->lk_type = be32_to_cpup(p++);
 737        if ((lock->lk_type < NFS4_READ_LT) || (lock->lk_type > NFS4_WRITEW_LT))
 738                goto xdr_error;
 739        lock->lk_reclaim = be32_to_cpup(p++);
 740        p = xdr_decode_hyper(p, &lock->lk_offset);
 741        p = xdr_decode_hyper(p, &lock->lk_length);
 742        lock->lk_is_new = be32_to_cpup(p++);
 743
 744        if (lock->lk_is_new) {
 745                READ_BUF(4);
 746                lock->lk_new_open_seqid = be32_to_cpup(p++);
 747                status = nfsd4_decode_stateid(argp, &lock->lk_new_open_stateid);
 748                if (status)
 749                        return status;
 750                READ_BUF(8 + sizeof(clientid_t));
 751                lock->lk_new_lock_seqid = be32_to_cpup(p++);
 752                COPYMEM(&lock->lk_new_clientid, sizeof(clientid_t));
 753                lock->lk_new_owner.len = be32_to_cpup(p++);
 754                READ_BUF(lock->lk_new_owner.len);
 755                READMEM(lock->lk_new_owner.data, lock->lk_new_owner.len);
 756        } else {
 757                status = nfsd4_decode_stateid(argp, &lock->lk_old_lock_stateid);
 758                if (status)
 759                        return status;
 760                READ_BUF(4);
 761                lock->lk_old_lock_seqid = be32_to_cpup(p++);
 762        }
 763
 764        DECODE_TAIL;
 765}
 766
 767static __be32
 768nfsd4_decode_lockt(struct nfsd4_compoundargs *argp, struct nfsd4_lockt *lockt)
 769{
 770        DECODE_HEAD;
 771                        
 772        READ_BUF(32);
 773        lockt->lt_type = be32_to_cpup(p++);
 774        if((lockt->lt_type < NFS4_READ_LT) || (lockt->lt_type > NFS4_WRITEW_LT))
 775                goto xdr_error;
 776        p = xdr_decode_hyper(p, &lockt->lt_offset);
 777        p = xdr_decode_hyper(p, &lockt->lt_length);
 778        COPYMEM(&lockt->lt_clientid, 8);
 779        lockt->lt_owner.len = be32_to_cpup(p++);
 780        READ_BUF(lockt->lt_owner.len);
 781        READMEM(lockt->lt_owner.data, lockt->lt_owner.len);
 782
 783        DECODE_TAIL;
 784}
 785
 786static __be32
 787nfsd4_decode_locku(struct nfsd4_compoundargs *argp, struct nfsd4_locku *locku)
 788{
 789        DECODE_HEAD;
 790
 791        READ_BUF(8);
 792        locku->lu_type = be32_to_cpup(p++);
 793        if ((locku->lu_type < NFS4_READ_LT) || (locku->lu_type > NFS4_WRITEW_LT))
 794                goto xdr_error;
 795        locku->lu_seqid = be32_to_cpup(p++);
 796        status = nfsd4_decode_stateid(argp, &locku->lu_stateid);
 797        if (status)
 798                return status;
 799        READ_BUF(16);
 800        p = xdr_decode_hyper(p, &locku->lu_offset);
 801        p = xdr_decode_hyper(p, &locku->lu_length);
 802
 803        DECODE_TAIL;
 804}
 805
 806static __be32
 807nfsd4_decode_lookup(struct nfsd4_compoundargs *argp, struct nfsd4_lookup *lookup)
 808{
 809        DECODE_HEAD;
 810
 811        READ_BUF(4);
 812        lookup->lo_len = be32_to_cpup(p++);
 813        READ_BUF(lookup->lo_len);
 814        SAVEMEM(lookup->lo_name, lookup->lo_len);
 815        if ((status = check_filename(lookup->lo_name, lookup->lo_len)))
 816                return status;
 817
 818        DECODE_TAIL;
 819}
 820
 821static __be32 nfsd4_decode_share_access(struct nfsd4_compoundargs *argp, u32 *share_access, u32 *deleg_want, u32 *deleg_when)
 822{
 823        __be32 *p;
 824        u32 w;
 825
 826        READ_BUF(4);
 827        w = be32_to_cpup(p++);
 828        *share_access = w & NFS4_SHARE_ACCESS_MASK;
 829        *deleg_want = w & NFS4_SHARE_WANT_MASK;
 830        if (deleg_when)
 831                *deleg_when = w & NFS4_SHARE_WHEN_MASK;
 832
 833        switch (w & NFS4_SHARE_ACCESS_MASK) {
 834        case NFS4_SHARE_ACCESS_READ:
 835        case NFS4_SHARE_ACCESS_WRITE:
 836        case NFS4_SHARE_ACCESS_BOTH:
 837                break;
 838        default:
 839                return nfserr_bad_xdr;
 840        }
 841        w &= ~NFS4_SHARE_ACCESS_MASK;
 842        if (!w)
 843                return nfs_ok;
 844        if (!argp->minorversion)
 845                return nfserr_bad_xdr;
 846        switch (w & NFS4_SHARE_WANT_MASK) {
 847        case NFS4_SHARE_WANT_NO_PREFERENCE:
 848        case NFS4_SHARE_WANT_READ_DELEG:
 849        case NFS4_SHARE_WANT_WRITE_DELEG:
 850        case NFS4_SHARE_WANT_ANY_DELEG:
 851        case NFS4_SHARE_WANT_NO_DELEG:
 852        case NFS4_SHARE_WANT_CANCEL:
 853                break;
 854        default:
 855                return nfserr_bad_xdr;
 856        }
 857        w &= ~NFS4_SHARE_WANT_MASK;
 858        if (!w)
 859                return nfs_ok;
 860
 861        if (!deleg_when)        /* open_downgrade */
 862                return nfserr_inval;
 863        switch (w) {
 864        case NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL:
 865        case NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED:
 866        case (NFS4_SHARE_SIGNAL_DELEG_WHEN_RESRC_AVAIL |
 867              NFS4_SHARE_PUSH_DELEG_WHEN_UNCONTENDED):
 868                return nfs_ok;
 869        }
 870xdr_error:
 871        return nfserr_bad_xdr;
 872}
 873
 874static __be32 nfsd4_decode_share_deny(struct nfsd4_compoundargs *argp, u32 *x)
 875{
 876        __be32 *p;
 877
 878        READ_BUF(4);
 879        *x = be32_to_cpup(p++);
 880        /* Note: unlinke access bits, deny bits may be zero. */
 881        if (*x & ~NFS4_SHARE_DENY_BOTH)
 882                return nfserr_bad_xdr;
 883        return nfs_ok;
 884xdr_error:
 885        return nfserr_bad_xdr;
 886}
 887
 888static __be32 nfsd4_decode_opaque(struct nfsd4_compoundargs *argp, struct xdr_netobj *o)
 889{
 890        __be32 *p;
 891
 892        READ_BUF(4);
 893        o->len = be32_to_cpup(p++);
 894
 895        if (o->len == 0 || o->len > NFS4_OPAQUE_LIMIT)
 896                return nfserr_bad_xdr;
 897
 898        READ_BUF(o->len);
 899        SAVEMEM(o->data, o->len);
 900        return nfs_ok;
 901xdr_error:
 902        return nfserr_bad_xdr;
 903}
 904
 905static __be32
 906nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
 907{
 908        DECODE_HEAD;
 909        u32 dummy;
 910
 911        memset(open->op_bmval, 0, sizeof(open->op_bmval));
 912        open->op_iattr.ia_valid = 0;
 913        open->op_openowner = NULL;
 914
 915        open->op_xdr_error = 0;
 916        /* seqid, share_access, share_deny, clientid, ownerlen */
 917        READ_BUF(4);
 918        open->op_seqid = be32_to_cpup(p++);
 919        /* decode, yet ignore deleg_when until supported */
 920        status = nfsd4_decode_share_access(argp, &open->op_share_access,
 921                                           &open->op_deleg_want, &dummy);
 922        if (status)
 923                goto xdr_error;
 924        status = nfsd4_decode_share_deny(argp, &open->op_share_deny);
 925        if (status)
 926                goto xdr_error;
 927        READ_BUF(sizeof(clientid_t));
 928        COPYMEM(&open->op_clientid, sizeof(clientid_t));
 929        status = nfsd4_decode_opaque(argp, &open->op_owner);
 930        if (status)
 931                goto xdr_error;
 932        READ_BUF(4);
 933        open->op_create = be32_to_cpup(p++);
 934        switch (open->op_create) {
 935        case NFS4_OPEN_NOCREATE:
 936                break;
 937        case NFS4_OPEN_CREATE:
 938                READ_BUF(4);
 939                open->op_createmode = be32_to_cpup(p++);
 940                switch (open->op_createmode) {
 941                case NFS4_CREATE_UNCHECKED:
 942                case NFS4_CREATE_GUARDED:
 943                        status = nfsd4_decode_fattr(argp, open->op_bmval,
 944                                &open->op_iattr, &open->op_acl, &open->op_label,
 945                                &open->op_umask);
 946                        if (status)
 947                                goto out;
 948                        break;
 949                case NFS4_CREATE_EXCLUSIVE:
 950                        READ_BUF(NFS4_VERIFIER_SIZE);
 951                        COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
 952                        break;
 953                case NFS4_CREATE_EXCLUSIVE4_1:
 954                        if (argp->minorversion < 1)
 955                                goto xdr_error;
 956                        READ_BUF(NFS4_VERIFIER_SIZE);
 957                        COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
 958                        status = nfsd4_decode_fattr(argp, open->op_bmval,
 959                                &open->op_iattr, &open->op_acl, &open->op_label,
 960                                &open->op_umask);
 961                        if (status)
 962                                goto out;
 963                        break;
 964                default:
 965                        goto xdr_error;
 966                }
 967                break;
 968        default:
 969                goto xdr_error;
 970        }
 971
 972        /* open_claim */
 973        READ_BUF(4);
 974        open->op_claim_type = be32_to_cpup(p++);
 975        switch (open->op_claim_type) {
 976        case NFS4_OPEN_CLAIM_NULL:
 977        case NFS4_OPEN_CLAIM_DELEGATE_PREV:
 978                READ_BUF(4);
 979                open->op_fname.len = be32_to_cpup(p++);
 980                READ_BUF(open->op_fname.len);
 981                SAVEMEM(open->op_fname.data, open->op_fname.len);
 982                if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
 983                        return status;
 984                break;
 985        case NFS4_OPEN_CLAIM_PREVIOUS:
 986                READ_BUF(4);
 987                open->op_delegate_type = be32_to_cpup(p++);
 988                break;
 989        case NFS4_OPEN_CLAIM_DELEGATE_CUR:
 990                status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
 991                if (status)
 992                        return status;
 993                READ_BUF(4);
 994                open->op_fname.len = be32_to_cpup(p++);
 995                READ_BUF(open->op_fname.len);
 996                SAVEMEM(open->op_fname.data, open->op_fname.len);
 997                if ((status = check_filename(open->op_fname.data, open->op_fname.len)))
 998                        return status;
 999                break;
1000        case NFS4_OPEN_CLAIM_FH:
1001        case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
1002                if (argp->minorversion < 1)
1003                        goto xdr_error;
1004                /* void */
1005                break;
1006        case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
1007                if (argp->minorversion < 1)
1008                        goto xdr_error;
1009                status = nfsd4_decode_stateid(argp, &open->op_delegate_stateid);
1010                if (status)
1011                        return status;
1012                break;
1013        default:
1014                goto xdr_error;
1015        }
1016
1017        DECODE_TAIL;
1018}
1019
1020static __be32
1021nfsd4_decode_open_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_open_confirm *open_conf)
1022{
1023        DECODE_HEAD;
1024
1025        if (argp->minorversion >= 1)
1026                return nfserr_notsupp;
1027
1028        status = nfsd4_decode_stateid(argp, &open_conf->oc_req_stateid);
1029        if (status)
1030                return status;
1031        READ_BUF(4);
1032        open_conf->oc_seqid = be32_to_cpup(p++);
1033
1034        DECODE_TAIL;
1035}
1036
1037static __be32
1038nfsd4_decode_open_downgrade(struct nfsd4_compoundargs *argp, struct nfsd4_open_downgrade *open_down)
1039{
1040        DECODE_HEAD;
1041                    
1042        status = nfsd4_decode_stateid(argp, &open_down->od_stateid);
1043        if (status)
1044                return status;
1045        READ_BUF(4);
1046        open_down->od_seqid = be32_to_cpup(p++);
1047        status = nfsd4_decode_share_access(argp, &open_down->od_share_access,
1048                                           &open_down->od_deleg_want, NULL);
1049        if (status)
1050                return status;
1051        status = nfsd4_decode_share_deny(argp, &open_down->od_share_deny);
1052        if (status)
1053                return status;
1054        DECODE_TAIL;
1055}
1056
1057static __be32
1058nfsd4_decode_putfh(struct nfsd4_compoundargs *argp, struct nfsd4_putfh *putfh)
1059{
1060        DECODE_HEAD;
1061
1062        READ_BUF(4);
1063        putfh->pf_fhlen = be32_to_cpup(p++);
1064        if (putfh->pf_fhlen > NFS4_FHSIZE)
1065                goto xdr_error;
1066        READ_BUF(putfh->pf_fhlen);
1067        SAVEMEM(putfh->pf_fhval, putfh->pf_fhlen);
1068
1069        DECODE_TAIL;
1070}
1071
1072static __be32
1073nfsd4_decode_putpubfh(struct nfsd4_compoundargs *argp, void *p)
1074{
1075        if (argp->minorversion == 0)
1076                return nfs_ok;
1077        return nfserr_notsupp;
1078}
1079
1080static __be32
1081nfsd4_decode_read(struct nfsd4_compoundargs *argp, struct nfsd4_read *read)
1082{
1083        DECODE_HEAD;
1084
1085        status = nfsd4_decode_stateid(argp, &read->rd_stateid);
1086        if (status)
1087                return status;
1088        READ_BUF(12);
1089        p = xdr_decode_hyper(p, &read->rd_offset);
1090        read->rd_length = be32_to_cpup(p++);
1091
1092        DECODE_TAIL;
1093}
1094
1095static __be32
1096nfsd4_decode_readdir(struct nfsd4_compoundargs *argp, struct nfsd4_readdir *readdir)
1097{
1098        DECODE_HEAD;
1099
1100        READ_BUF(24);
1101        p = xdr_decode_hyper(p, &readdir->rd_cookie);
1102        COPYMEM(readdir->rd_verf.data, sizeof(readdir->rd_verf.data));
1103        readdir->rd_dircount = be32_to_cpup(p++);
1104        readdir->rd_maxcount = be32_to_cpup(p++);
1105        if ((status = nfsd4_decode_bitmap(argp, readdir->rd_bmval)))
1106                goto out;
1107
1108        DECODE_TAIL;
1109}
1110
1111static __be32
1112nfsd4_decode_remove(struct nfsd4_compoundargs *argp, struct nfsd4_remove *remove)
1113{
1114        DECODE_HEAD;
1115
1116        READ_BUF(4);
1117        remove->rm_namelen = be32_to_cpup(p++);
1118        READ_BUF(remove->rm_namelen);
1119        SAVEMEM(remove->rm_name, remove->rm_namelen);
1120        if ((status = check_filename(remove->rm_name, remove->rm_namelen)))
1121                return status;
1122
1123        DECODE_TAIL;
1124}
1125
1126static __be32
1127nfsd4_decode_rename(struct nfsd4_compoundargs *argp, struct nfsd4_rename *rename)
1128{
1129        DECODE_HEAD;
1130
1131        READ_BUF(4);
1132        rename->rn_snamelen = be32_to_cpup(p++);
1133        READ_BUF(rename->rn_snamelen);
1134        SAVEMEM(rename->rn_sname, rename->rn_snamelen);
1135        READ_BUF(4);
1136        rename->rn_tnamelen = be32_to_cpup(p++);
1137        READ_BUF(rename->rn_tnamelen);
1138        SAVEMEM(rename->rn_tname, rename->rn_tnamelen);
1139        if ((status = check_filename(rename->rn_sname, rename->rn_snamelen)))
1140                return status;
1141        if ((status = check_filename(rename->rn_tname, rename->rn_tnamelen)))
1142                return status;
1143
1144        DECODE_TAIL;
1145}
1146
1147static __be32
1148nfsd4_decode_renew(struct nfsd4_compoundargs *argp, clientid_t *clientid)
1149{
1150        DECODE_HEAD;
1151
1152        if (argp->minorversion >= 1)
1153                return nfserr_notsupp;
1154
1155        READ_BUF(sizeof(clientid_t));
1156        COPYMEM(clientid, sizeof(clientid_t));
1157
1158        DECODE_TAIL;
1159}
1160
1161static __be32
1162nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp,
1163                     struct nfsd4_secinfo *secinfo)
1164{
1165        DECODE_HEAD;
1166
1167        READ_BUF(4);
1168        secinfo->si_namelen = be32_to_cpup(p++);
1169        READ_BUF(secinfo->si_namelen);
1170        SAVEMEM(secinfo->si_name, secinfo->si_namelen);
1171        status = check_filename(secinfo->si_name, secinfo->si_namelen);
1172        if (status)
1173                return status;
1174        DECODE_TAIL;
1175}
1176
1177static __be32
1178nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp,
1179                     struct nfsd4_secinfo_no_name *sin)
1180{
1181        DECODE_HEAD;
1182
1183        READ_BUF(4);
1184        sin->sin_style = be32_to_cpup(p++);
1185        DECODE_TAIL;
1186}
1187
1188static __be32
1189nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr)
1190{
1191        __be32 status;
1192
1193        status = nfsd4_decode_stateid(argp, &setattr->sa_stateid);
1194        if (status)
1195                return status;
1196        return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
1197                                  &setattr->sa_acl, &setattr->sa_label, NULL);
1198}
1199
1200static __be32
1201nfsd4_decode_setclientid(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid *setclientid)
1202{
1203        DECODE_HEAD;
1204
1205        if (argp->minorversion >= 1)
1206                return nfserr_notsupp;
1207
1208        READ_BUF(NFS4_VERIFIER_SIZE);
1209        COPYMEM(setclientid->se_verf.data, NFS4_VERIFIER_SIZE);
1210
1211        status = nfsd4_decode_opaque(argp, &setclientid->se_name);
1212        if (status)
1213                return nfserr_bad_xdr;
1214        READ_BUF(8);
1215        setclientid->se_callback_prog = be32_to_cpup(p++);
1216        setclientid->se_callback_netid_len = be32_to_cpup(p++);
1217        READ_BUF(setclientid->se_callback_netid_len);
1218        SAVEMEM(setclientid->se_callback_netid_val, setclientid->se_callback_netid_len);
1219        READ_BUF(4);
1220        setclientid->se_callback_addr_len = be32_to_cpup(p++);
1221
1222        READ_BUF(setclientid->se_callback_addr_len);
1223        SAVEMEM(setclientid->se_callback_addr_val, setclientid->se_callback_addr_len);
1224        READ_BUF(4);
1225        setclientid->se_callback_ident = be32_to_cpup(p++);
1226
1227        DECODE_TAIL;
1228}
1229
1230static __be32
1231nfsd4_decode_setclientid_confirm(struct nfsd4_compoundargs *argp, struct nfsd4_setclientid_confirm *scd_c)
1232{
1233        DECODE_HEAD;
1234
1235        if (argp->minorversion >= 1)
1236                return nfserr_notsupp;
1237
1238        READ_BUF(8 + NFS4_VERIFIER_SIZE);
1239        COPYMEM(&scd_c->sc_clientid, 8);
1240        COPYMEM(&scd_c->sc_confirm, NFS4_VERIFIER_SIZE);
1241
1242        DECODE_TAIL;
1243}
1244
1245/* Also used for NVERIFY */
1246static __be32
1247nfsd4_decode_verify(struct nfsd4_compoundargs *argp, struct nfsd4_verify *verify)
1248{
1249        DECODE_HEAD;
1250
1251        if ((status = nfsd4_decode_bitmap(argp, verify->ve_bmval)))
1252                goto out;
1253
1254        /* For convenience's sake, we compare raw xdr'd attributes in
1255         * nfsd4_proc_verify */
1256
1257        READ_BUF(4);
1258        verify->ve_attrlen = be32_to_cpup(p++);
1259        READ_BUF(verify->ve_attrlen);
1260        SAVEMEM(verify->ve_attrval, verify->ve_attrlen);
1261
1262        DECODE_TAIL;
1263}
1264
1265static __be32
1266nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
1267{
1268        int avail;
1269        int len;
1270        DECODE_HEAD;
1271
1272        status = nfsd4_decode_stateid(argp, &write->wr_stateid);
1273        if (status)
1274                return status;
1275        READ_BUF(16);
1276        p = xdr_decode_hyper(p, &write->wr_offset);
1277        write->wr_stable_how = be32_to_cpup(p++);
1278        if (write->wr_stable_how > NFS_FILE_SYNC)
1279                goto xdr_error;
1280        write->wr_buflen = be32_to_cpup(p++);
1281
1282        /* Sorry .. no magic macros for this.. *
1283         * READ_BUF(write->wr_buflen);
1284         * SAVEMEM(write->wr_buf, write->wr_buflen);
1285         */
1286        avail = (char*)argp->end - (char*)argp->p;
1287        if (avail + argp->pagelen < write->wr_buflen) {
1288                dprintk("NFSD: xdr error (%s:%d)\n",
1289                                __FILE__, __LINE__);
1290                goto xdr_error;
1291        }
1292        write->wr_head.iov_base = p;
1293        write->wr_head.iov_len = avail;
1294        write->wr_pagelist = argp->pagelist;
1295
1296        len = XDR_QUADLEN(write->wr_buflen) << 2;
1297        if (len >= avail) {
1298                int pages;
1299
1300                len -= avail;
1301
1302                pages = len >> PAGE_SHIFT;
1303                argp->pagelist += pages;
1304                argp->pagelen -= pages * PAGE_SIZE;
1305                len -= pages * PAGE_SIZE;
1306
1307                next_decode_page(argp);
1308        }
1309        argp->p += XDR_QUADLEN(len);
1310
1311        DECODE_TAIL;
1312}
1313
1314static __be32
1315nfsd4_decode_release_lockowner(struct nfsd4_compoundargs *argp, struct nfsd4_release_lockowner *rlockowner)
1316{
1317        DECODE_HEAD;
1318
1319        if (argp->minorversion >= 1)
1320                return nfserr_notsupp;
1321
1322        READ_BUF(12);
1323        COPYMEM(&rlockowner->rl_clientid, sizeof(clientid_t));
1324        rlockowner->rl_owner.len = be32_to_cpup(p++);
1325        READ_BUF(rlockowner->rl_owner.len);
1326        READMEM(rlockowner->rl_owner.data, rlockowner->rl_owner.len);
1327
1328        if (argp->minorversion && !zero_clientid(&rlockowner->rl_clientid))
1329                return nfserr_inval;
1330        DECODE_TAIL;
1331}
1332
1333static __be32
1334nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp,
1335                         struct nfsd4_exchange_id *exid)
1336{
1337        int dummy, tmp;
1338        DECODE_HEAD;
1339
1340        READ_BUF(NFS4_VERIFIER_SIZE);
1341        COPYMEM(exid->verifier.data, NFS4_VERIFIER_SIZE);
1342
1343        status = nfsd4_decode_opaque(argp, &exid->clname);
1344        if (status)
1345                return nfserr_bad_xdr;
1346
1347        READ_BUF(4);
1348        exid->flags = be32_to_cpup(p++);
1349
1350        /* Ignore state_protect4_a */
1351        READ_BUF(4);
1352        exid->spa_how = be32_to_cpup(p++);
1353        switch (exid->spa_how) {
1354        case SP4_NONE:
1355                break;
1356        case SP4_MACH_CRED:
1357                /* spo_must_enforce */
1358                status = nfsd4_decode_bitmap(argp,
1359                                        exid->spo_must_enforce);
1360                if (status)
1361                        goto out;
1362                /* spo_must_allow */
1363                status = nfsd4_decode_bitmap(argp, exid->spo_must_allow);
1364                if (status)
1365                        goto out;
1366                break;
1367        case SP4_SSV:
1368                /* ssp_ops */
1369                READ_BUF(4);
1370                dummy = be32_to_cpup(p++);
1371                READ_BUF(dummy * 4);
1372                p += dummy;
1373
1374                READ_BUF(4);
1375                dummy = be32_to_cpup(p++);
1376                READ_BUF(dummy * 4);
1377                p += dummy;
1378
1379                /* ssp_hash_algs<> */
1380                READ_BUF(4);
1381                tmp = be32_to_cpup(p++);
1382                while (tmp--) {
1383                        READ_BUF(4);
1384                        dummy = be32_to_cpup(p++);
1385                        READ_BUF(dummy);
1386                        p += XDR_QUADLEN(dummy);
1387                }
1388
1389                /* ssp_encr_algs<> */
1390                READ_BUF(4);
1391                tmp = be32_to_cpup(p++);
1392                while (tmp--) {
1393                        READ_BUF(4);
1394                        dummy = be32_to_cpup(p++);
1395                        READ_BUF(dummy);
1396                        p += XDR_QUADLEN(dummy);
1397                }
1398
1399                /* ignore ssp_window and ssp_num_gss_handles: */
1400                READ_BUF(8);
1401                break;
1402        default:
1403                goto xdr_error;
1404        }
1405
1406        READ_BUF(4);    /* nfs_impl_id4 array length */
1407        dummy = be32_to_cpup(p++);
1408
1409        if (dummy > 1)
1410                goto xdr_error;
1411
1412        if (dummy == 1) {
1413                status = nfsd4_decode_opaque(argp, &exid->nii_domain);
1414                if (status)
1415                        goto xdr_error;
1416
1417                /* nii_name */
1418                status = nfsd4_decode_opaque(argp, &exid->nii_name);
1419                if (status)
1420                        goto xdr_error;
1421
1422                /* nii_date */
1423                status = nfsd4_decode_time(argp, &exid->nii_time);
1424                if (status)
1425                        goto xdr_error;
1426        }
1427        DECODE_TAIL;
1428}
1429
1430static __be32
1431nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
1432                            struct nfsd4_create_session *sess)
1433{
1434        DECODE_HEAD;
1435
1436        READ_BUF(16);
1437        COPYMEM(&sess->clientid, 8);
1438        sess->seqid = be32_to_cpup(p++);
1439        sess->flags = be32_to_cpup(p++);
1440
1441        /* Fore channel attrs */
1442        READ_BUF(28);
1443        p++; /* headerpadsz is always 0 */
1444        sess->fore_channel.maxreq_sz = be32_to_cpup(p++);
1445        sess->fore_channel.maxresp_sz = be32_to_cpup(p++);
1446        sess->fore_channel.maxresp_cached = be32_to_cpup(p++);
1447        sess->fore_channel.maxops = be32_to_cpup(p++);
1448        sess->fore_channel.maxreqs = be32_to_cpup(p++);
1449        sess->fore_channel.nr_rdma_attrs = be32_to_cpup(p++);
1450        if (sess->fore_channel.nr_rdma_attrs == 1) {
1451                READ_BUF(4);
1452                sess->fore_channel.rdma_attrs = be32_to_cpup(p++);
1453        } else if (sess->fore_channel.nr_rdma_attrs > 1) {
1454                dprintk("Too many fore channel attr bitmaps!\n");
1455                goto xdr_error;
1456        }
1457
1458        /* Back channel attrs */
1459        READ_BUF(28);
1460        p++; /* headerpadsz is always 0 */
1461        sess->back_channel.maxreq_sz = be32_to_cpup(p++);
1462        sess->back_channel.maxresp_sz = be32_to_cpup(p++);
1463        sess->back_channel.maxresp_cached = be32_to_cpup(p++);
1464        sess->back_channel.maxops = be32_to_cpup(p++);
1465        sess->back_channel.maxreqs = be32_to_cpup(p++);
1466        sess->back_channel.nr_rdma_attrs = be32_to_cpup(p++);
1467        if (sess->back_channel.nr_rdma_attrs == 1) {
1468                READ_BUF(4);
1469                sess->back_channel.rdma_attrs = be32_to_cpup(p++);
1470        } else if (sess->back_channel.nr_rdma_attrs > 1) {
1471                dprintk("Too many back channel attr bitmaps!\n");
1472                goto xdr_error;
1473        }
1474
1475        READ_BUF(4);
1476        sess->callback_prog = be32_to_cpup(p++);
1477        nfsd4_decode_cb_sec(argp, &sess->cb_sec);
1478        DECODE_TAIL;
1479}
1480
1481static __be32
1482nfsd4_decode_destroy_session(struct nfsd4_compoundargs *argp,
1483                             struct nfsd4_destroy_session *destroy_session)
1484{
1485        DECODE_HEAD;
1486        READ_BUF(NFS4_MAX_SESSIONID_LEN);
1487        COPYMEM(destroy_session->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1488
1489        DECODE_TAIL;
1490}
1491
1492static __be32
1493nfsd4_decode_free_stateid(struct nfsd4_compoundargs *argp,
1494                          struct nfsd4_free_stateid *free_stateid)
1495{
1496        DECODE_HEAD;
1497
1498        READ_BUF(sizeof(stateid_t));
1499        free_stateid->fr_stateid.si_generation = be32_to_cpup(p++);
1500        COPYMEM(&free_stateid->fr_stateid.si_opaque, sizeof(stateid_opaque_t));
1501
1502        DECODE_TAIL;
1503}
1504
1505static __be32
1506nfsd4_decode_sequence(struct nfsd4_compoundargs *argp,
1507                      struct nfsd4_sequence *seq)
1508{
1509        DECODE_HEAD;
1510
1511        READ_BUF(NFS4_MAX_SESSIONID_LEN + 16);
1512        COPYMEM(seq->sessionid.data, NFS4_MAX_SESSIONID_LEN);
1513        seq->seqid = be32_to_cpup(p++);
1514        seq->slotid = be32_to_cpup(p++);
1515        seq->maxslots = be32_to_cpup(p++);
1516        seq->cachethis = be32_to_cpup(p++);
1517
1518        DECODE_TAIL;
1519}
1520
1521static __be32
1522nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_stateid *test_stateid)
1523{
1524        int i;
1525        __be32 *p, status;
1526        struct nfsd4_test_stateid_id *stateid;
1527
1528        READ_BUF(4);
1529        test_stateid->ts_num_ids = ntohl(*p++);
1530
1531        INIT_LIST_HEAD(&test_stateid->ts_stateid_list);
1532
1533        for (i = 0; i < test_stateid->ts_num_ids; i++) {
1534                stateid = svcxdr_tmpalloc(argp, sizeof(*stateid));
1535                if (!stateid) {
1536                        status = nfserrno(-ENOMEM);
1537                        goto out;
1538                }
1539
1540                INIT_LIST_HEAD(&stateid->ts_id_list);
1541                list_add_tail(&stateid->ts_id_list, &test_stateid->ts_stateid_list);
1542
1543                status = nfsd4_decode_stateid(argp, &stateid->ts_id_stateid);
1544                if (status)
1545                        goto out;
1546        }
1547
1548        status = 0;
1549out:
1550        return status;
1551xdr_error:
1552        dprintk("NFSD: xdr error (%s:%d)\n", __FILE__, __LINE__);
1553        status = nfserr_bad_xdr;
1554        goto out;
1555}
1556
1557static __be32 nfsd4_decode_destroy_clientid(struct nfsd4_compoundargs *argp, struct nfsd4_destroy_clientid *dc)
1558{
1559        DECODE_HEAD;
1560
1561        READ_BUF(8);
1562        COPYMEM(&dc->clientid, 8);
1563
1564        DECODE_TAIL;
1565}
1566
1567static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, struct nfsd4_reclaim_complete *rc)
1568{
1569        DECODE_HEAD;
1570
1571        READ_BUF(4);
1572        rc->rca_one_fs = be32_to_cpup(p++);
1573
1574        DECODE_TAIL;
1575}
1576
1577#ifdef CONFIG_NFSD_PNFS
1578static __be32
1579nfsd4_decode_getdeviceinfo(struct nfsd4_compoundargs *argp,
1580                struct nfsd4_getdeviceinfo *gdev)
1581{
1582        DECODE_HEAD;
1583        u32 num, i;
1584
1585        READ_BUF(sizeof(struct nfsd4_deviceid) + 3 * 4);
1586        COPYMEM(&gdev->gd_devid, sizeof(struct nfsd4_deviceid));
1587        gdev->gd_layout_type = be32_to_cpup(p++);
1588        gdev->gd_maxcount = be32_to_cpup(p++);
1589        num = be32_to_cpup(p++);
1590        if (num) {
1591                if (num > 1000)
1592                        goto xdr_error;
1593                READ_BUF(4 * num);
1594                gdev->gd_notify_types = be32_to_cpup(p++);
1595                for (i = 1; i < num; i++) {
1596                        if (be32_to_cpup(p++)) {
1597                                status = nfserr_inval;
1598                                goto out;
1599                        }
1600                }
1601        }
1602        DECODE_TAIL;
1603}
1604
1605static __be32
1606nfsd4_decode_layoutget(struct nfsd4_compoundargs *argp,
1607                struct nfsd4_layoutget *lgp)
1608{
1609        DECODE_HEAD;
1610
1611        READ_BUF(36);
1612        lgp->lg_signal = be32_to_cpup(p++);
1613        lgp->lg_layout_type = be32_to_cpup(p++);
1614        lgp->lg_seg.iomode = be32_to_cpup(p++);
1615        p = xdr_decode_hyper(p, &lgp->lg_seg.offset);
1616        p = xdr_decode_hyper(p, &lgp->lg_seg.length);
1617        p = xdr_decode_hyper(p, &lgp->lg_minlength);
1618
1619        status = nfsd4_decode_stateid(argp, &lgp->lg_sid);
1620        if (status)
1621                return status;
1622
1623        READ_BUF(4);
1624        lgp->lg_maxcount = be32_to_cpup(p++);
1625
1626        DECODE_TAIL;
1627}
1628
1629static __be32
1630nfsd4_decode_layoutcommit(struct nfsd4_compoundargs *argp,
1631                struct nfsd4_layoutcommit *lcp)
1632{
1633        DECODE_HEAD;
1634        u32 timechange;
1635
1636        READ_BUF(20);
1637        p = xdr_decode_hyper(p, &lcp->lc_seg.offset);
1638        p = xdr_decode_hyper(p, &lcp->lc_seg.length);
1639        lcp->lc_reclaim = be32_to_cpup(p++);
1640
1641        status = nfsd4_decode_stateid(argp, &lcp->lc_sid);
1642        if (status)
1643                return status;
1644
1645        READ_BUF(4);
1646        lcp->lc_newoffset = be32_to_cpup(p++);
1647        if (lcp->lc_newoffset) {
1648                READ_BUF(8);
1649                p = xdr_decode_hyper(p, &lcp->lc_last_wr);
1650        } else
1651                lcp->lc_last_wr = 0;
1652        READ_BUF(4);
1653        timechange = be32_to_cpup(p++);
1654        if (timechange) {
1655                status = nfsd4_decode_time(argp, &lcp->lc_mtime);
1656                if (status)
1657                        return status;
1658        } else {
1659                lcp->lc_mtime.tv_nsec = UTIME_NOW;
1660        }
1661        READ_BUF(8);
1662        lcp->lc_layout_type = be32_to_cpup(p++);
1663
1664        /*
1665         * Save the layout update in XDR format and let the layout driver deal
1666         * with it later.
1667         */
1668        lcp->lc_up_len = be32_to_cpup(p++);
1669        if (lcp->lc_up_len > 0) {
1670                READ_BUF(lcp->lc_up_len);
1671                READMEM(lcp->lc_up_layout, lcp->lc_up_len);
1672        }
1673
1674        DECODE_TAIL;
1675}
1676
1677static __be32
1678nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
1679                struct nfsd4_layoutreturn *lrp)
1680{
1681        DECODE_HEAD;
1682
1683        READ_BUF(16);
1684        lrp->lr_reclaim = be32_to_cpup(p++);
1685        lrp->lr_layout_type = be32_to_cpup(p++);
1686        lrp->lr_seg.iomode = be32_to_cpup(p++);
1687        lrp->lr_return_type = be32_to_cpup(p++);
1688        if (lrp->lr_return_type == RETURN_FILE) {
1689                READ_BUF(16);
1690                p = xdr_decode_hyper(p, &lrp->lr_seg.offset);
1691                p = xdr_decode_hyper(p, &lrp->lr_seg.length);
1692
1693                status = nfsd4_decode_stateid(argp, &lrp->lr_sid);
1694                if (status)
1695                        return status;
1696
1697                READ_BUF(4);
1698                lrp->lrf_body_len = be32_to_cpup(p++);
1699                if (lrp->lrf_body_len > 0) {
1700                        READ_BUF(lrp->lrf_body_len);
1701                        READMEM(lrp->lrf_body, lrp->lrf_body_len);
1702                }
1703        } else {
1704                lrp->lr_seg.offset = 0;
1705                lrp->lr_seg.length = NFS4_MAX_UINT64;
1706        }
1707
1708        DECODE_TAIL;
1709}
1710#endif /* CONFIG_NFSD_PNFS */
1711
1712static __be32
1713nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
1714                       struct nfsd4_fallocate *fallocate)
1715{
1716        DECODE_HEAD;
1717
1718        status = nfsd4_decode_stateid(argp, &fallocate->falloc_stateid);
1719        if (status)
1720                return status;
1721
1722        READ_BUF(16);
1723        p = xdr_decode_hyper(p, &fallocate->falloc_offset);
1724        xdr_decode_hyper(p, &fallocate->falloc_length);
1725
1726        DECODE_TAIL;
1727}
1728
1729static __be32
1730nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
1731{
1732        DECODE_HEAD;
1733
1734        status = nfsd4_decode_stateid(argp, &clone->cl_src_stateid);
1735        if (status)
1736                return status;
1737        status = nfsd4_decode_stateid(argp, &clone->cl_dst_stateid);
1738        if (status)
1739                return status;
1740
1741        READ_BUF(8 + 8 + 8);
1742        p = xdr_decode_hyper(p, &clone->cl_src_pos);
1743        p = xdr_decode_hyper(p, &clone->cl_dst_pos);
1744        p = xdr_decode_hyper(p, &clone->cl_count);
1745        DECODE_TAIL;
1746}
1747
1748static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
1749                                      struct nl4_server *ns)
1750{
1751        DECODE_HEAD;
1752        struct nfs42_netaddr *naddr;
1753
1754        READ_BUF(4);
1755        ns->nl4_type = be32_to_cpup(p++);
1756
1757        /* currently support for 1 inter-server source server */
1758        switch (ns->nl4_type) {
1759        case NL4_NETADDR:
1760                naddr = &ns->u.nl4_addr;
1761
1762                READ_BUF(4);
1763                naddr->netid_len = be32_to_cpup(p++);
1764                if (naddr->netid_len > RPCBIND_MAXNETIDLEN)
1765                        goto xdr_error;
1766
1767                READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */
1768                COPYMEM(naddr->netid, naddr->netid_len);
1769
1770                naddr->addr_len = be32_to_cpup(p++);
1771                if (naddr->addr_len > RPCBIND_MAXUADDRLEN)
1772                        goto xdr_error;
1773
1774                READ_BUF(naddr->addr_len);
1775                COPYMEM(naddr->addr, naddr->addr_len);
1776                break;
1777        default:
1778                goto xdr_error;
1779        }
1780        DECODE_TAIL;
1781}
1782
1783static __be32
1784nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
1785{
1786        DECODE_HEAD;
1787        struct nl4_server *ns_dummy;
1788        int i, count;
1789
1790        status = nfsd4_decode_stateid(argp, &copy->cp_src_stateid);
1791        if (status)
1792                return status;
1793        status = nfsd4_decode_stateid(argp, &copy->cp_dst_stateid);
1794        if (status)
1795                return status;
1796
1797        READ_BUF(8 + 8 + 8 + 4 + 4 + 4);
1798        p = xdr_decode_hyper(p, &copy->cp_src_pos);
1799        p = xdr_decode_hyper(p, &copy->cp_dst_pos);
1800        p = xdr_decode_hyper(p, &copy->cp_count);
1801        p++; /* ca_consecutive: we always do consecutive copies */
1802        copy->cp_synchronous = be32_to_cpup(p++);
1803
1804        count = be32_to_cpup(p++);
1805
1806        copy->cp_intra = false;
1807        if (count == 0) { /* intra-server copy */
1808                copy->cp_intra = true;
1809                goto intra;
1810        }
1811
1812        /* decode all the supplied server addresses but use first */
1813        status = nfsd4_decode_nl4_server(argp, &copy->cp_src);
1814        if (status)
1815                return status;
1816
1817        ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL);
1818        if (ns_dummy == NULL)
1819                return nfserrno(-ENOMEM);
1820        for (i = 0; i < count - 1; i++) {
1821                status = nfsd4_decode_nl4_server(argp, ns_dummy);
1822                if (status) {
1823                        kfree(ns_dummy);
1824                        return status;
1825                }
1826        }
1827        kfree(ns_dummy);
1828intra:
1829
1830        DECODE_TAIL;
1831}
1832
1833static __be32
1834nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
1835                            struct nfsd4_offload_status *os)
1836{
1837        return nfsd4_decode_stateid(argp, &os->stateid);
1838}
1839
1840static __be32
1841nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
1842                         struct nfsd4_copy_notify *cn)
1843{
1844        int status;
1845
1846        status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid);
1847        if (status)
1848                return status;
1849        return nfsd4_decode_nl4_server(argp, &cn->cpn_dst);
1850}
1851
1852static __be32
1853nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
1854{
1855        DECODE_HEAD;
1856
1857        status = nfsd4_decode_stateid(argp, &seek->seek_stateid);
1858        if (status)
1859                return status;
1860
1861        READ_BUF(8 + 4);
1862        p = xdr_decode_hyper(p, &seek->seek_offset);
1863        seek->seek_whence = be32_to_cpup(p);
1864
1865        DECODE_TAIL;
1866}
1867
1868static __be32
1869nfsd4_decode_noop(struct nfsd4_compoundargs *argp, void *p)
1870{
1871        return nfs_ok;
1872}
1873
1874static __be32
1875nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
1876{
1877        return nfserr_notsupp;
1878}
1879
1880typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
1881
1882static const nfsd4_dec nfsd4_dec_ops[] = {
1883        [OP_ACCESS]             = (nfsd4_dec)nfsd4_decode_access,
1884        [OP_CLOSE]              = (nfsd4_dec)nfsd4_decode_close,
1885        [OP_COMMIT]             = (nfsd4_dec)nfsd4_decode_commit,
1886        [OP_CREATE]             = (nfsd4_dec)nfsd4_decode_create,
1887        [OP_DELEGPURGE]         = (nfsd4_dec)nfsd4_decode_notsupp,
1888        [OP_DELEGRETURN]        = (nfsd4_dec)nfsd4_decode_delegreturn,
1889        [OP_GETATTR]            = (nfsd4_dec)nfsd4_decode_getattr,
1890        [OP_GETFH]              = (nfsd4_dec)nfsd4_decode_noop,
1891        [OP_LINK]               = (nfsd4_dec)nfsd4_decode_link,
1892        [OP_LOCK]               = (nfsd4_dec)nfsd4_decode_lock,
1893        [OP_LOCKT]              = (nfsd4_dec)nfsd4_decode_lockt,
1894        [OP_LOCKU]              = (nfsd4_dec)nfsd4_decode_locku,
1895        [OP_LOOKUP]             = (nfsd4_dec)nfsd4_decode_lookup,
1896        [OP_LOOKUPP]            = (nfsd4_dec)nfsd4_decode_noop,
1897        [OP_NVERIFY]            = (nfsd4_dec)nfsd4_decode_verify,
1898        [OP_OPEN]               = (nfsd4_dec)nfsd4_decode_open,
1899        [OP_OPENATTR]           = (nfsd4_dec)nfsd4_decode_notsupp,
1900        [OP_OPEN_CONFIRM]       = (nfsd4_dec)nfsd4_decode_open_confirm,
1901        [OP_OPEN_DOWNGRADE]     = (nfsd4_dec)nfsd4_decode_open_downgrade,
1902        [OP_PUTFH]              = (nfsd4_dec)nfsd4_decode_putfh,
1903        [OP_PUTPUBFH]           = (nfsd4_dec)nfsd4_decode_putpubfh,
1904        [OP_PUTROOTFH]          = (nfsd4_dec)nfsd4_decode_noop,
1905        [OP_READ]               = (nfsd4_dec)nfsd4_decode_read,
1906        [OP_READDIR]            = (nfsd4_dec)nfsd4_decode_readdir,
1907        [OP_READLINK]           = (nfsd4_dec)nfsd4_decode_noop,
1908        [OP_REMOVE]             = (nfsd4_dec)nfsd4_decode_remove,
1909        [OP_RENAME]             = (nfsd4_dec)nfsd4_decode_rename,
1910        [OP_RENEW]              = (nfsd4_dec)nfsd4_decode_renew,
1911        [OP_RESTOREFH]          = (nfsd4_dec)nfsd4_decode_noop,
1912        [OP_SAVEFH]             = (nfsd4_dec)nfsd4_decode_noop,
1913        [OP_SECINFO]            = (nfsd4_dec)nfsd4_decode_secinfo,
1914        [OP_SETATTR]            = (nfsd4_dec)nfsd4_decode_setattr,
1915        [OP_SETCLIENTID]        = (nfsd4_dec)nfsd4_decode_setclientid,
1916        [OP_SETCLIENTID_CONFIRM] = (nfsd4_dec)nfsd4_decode_setclientid_confirm,
1917        [OP_VERIFY]             = (nfsd4_dec)nfsd4_decode_verify,
1918        [OP_WRITE]              = (nfsd4_dec)nfsd4_decode_write,
1919        [OP_RELEASE_LOCKOWNER]  = (nfsd4_dec)nfsd4_decode_release_lockowner,
1920
1921        /* new operations for NFSv4.1 */
1922        [OP_BACKCHANNEL_CTL]    = (nfsd4_dec)nfsd4_decode_backchannel_ctl,
1923        [OP_BIND_CONN_TO_SESSION]= (nfsd4_dec)nfsd4_decode_bind_conn_to_session,
1924        [OP_EXCHANGE_ID]        = (nfsd4_dec)nfsd4_decode_exchange_id,
1925        [OP_CREATE_SESSION]     = (nfsd4_dec)nfsd4_decode_create_session,
1926        [OP_DESTROY_SESSION]    = (nfsd4_dec)nfsd4_decode_destroy_session,
1927        [OP_FREE_STATEID]       = (nfsd4_dec)nfsd4_decode_free_stateid,
1928        [OP_GET_DIR_DELEGATION] = (nfsd4_dec)nfsd4_decode_notsupp,
1929#ifdef CONFIG_NFSD_PNFS
1930        [OP_GETDEVICEINFO]      = (nfsd4_dec)nfsd4_decode_getdeviceinfo,
1931        [OP_GETDEVICELIST]      = (nfsd4_dec)nfsd4_decode_notsupp,
1932        [OP_LAYOUTCOMMIT]       = (nfsd4_dec)nfsd4_decode_layoutcommit,
1933        [OP_LAYOUTGET]          = (nfsd4_dec)nfsd4_decode_layoutget,
1934        [OP_LAYOUTRETURN]       = (nfsd4_dec)nfsd4_decode_layoutreturn,
1935#else
1936        [OP_GETDEVICEINFO]      = (nfsd4_dec)nfsd4_decode_notsupp,
1937        [OP_GETDEVICELIST]      = (nfsd4_dec)nfsd4_decode_notsupp,
1938        [OP_LAYOUTCOMMIT]       = (nfsd4_dec)nfsd4_decode_notsupp,
1939        [OP_LAYOUTGET]          = (nfsd4_dec)nfsd4_decode_notsupp,
1940        [OP_LAYOUTRETURN]       = (nfsd4_dec)nfsd4_decode_notsupp,
1941#endif
1942        [OP_SECINFO_NO_NAME]    = (nfsd4_dec)nfsd4_decode_secinfo_no_name,
1943        [OP_SEQUENCE]           = (nfsd4_dec)nfsd4_decode_sequence,
1944        [OP_SET_SSV]            = (nfsd4_dec)nfsd4_decode_notsupp,
1945        [OP_TEST_STATEID]       = (nfsd4_dec)nfsd4_decode_test_stateid,
1946        [OP_WANT_DELEGATION]    = (nfsd4_dec)nfsd4_decode_notsupp,
1947        [OP_DESTROY_CLIENTID]   = (nfsd4_dec)nfsd4_decode_destroy_clientid,
1948        [OP_RECLAIM_COMPLETE]   = (nfsd4_dec)nfsd4_decode_reclaim_complete,
1949
1950        /* new operations for NFSv4.2 */
1951        [OP_ALLOCATE]           = (nfsd4_dec)nfsd4_decode_fallocate,
1952        [OP_COPY]               = (nfsd4_dec)nfsd4_decode_copy,
1953        [OP_COPY_NOTIFY]        = (nfsd4_dec)nfsd4_decode_copy_notify,
1954        [OP_DEALLOCATE]         = (nfsd4_dec)nfsd4_decode_fallocate,
1955        [OP_IO_ADVISE]          = (nfsd4_dec)nfsd4_decode_notsupp,
1956        [OP_LAYOUTERROR]        = (nfsd4_dec)nfsd4_decode_notsupp,
1957        [OP_LAYOUTSTATS]        = (nfsd4_dec)nfsd4_decode_notsupp,
1958        [OP_OFFLOAD_CANCEL]     = (nfsd4_dec)nfsd4_decode_offload_status,
1959        [OP_OFFLOAD_STATUS]     = (nfsd4_dec)nfsd4_decode_offload_status,
1960        [OP_READ_PLUS]          = (nfsd4_dec)nfsd4_decode_notsupp,
1961        [OP_SEEK]               = (nfsd4_dec)nfsd4_decode_seek,
1962        [OP_WRITE_SAME]         = (nfsd4_dec)nfsd4_decode_notsupp,
1963        [OP_CLONE]              = (nfsd4_dec)nfsd4_decode_clone,
1964};
1965
1966static inline bool
1967nfsd4_opnum_in_range(struct nfsd4_compoundargs *argp, struct nfsd4_op *op)
1968{
1969        if (op->opnum < FIRST_NFS4_OP)
1970                return false;
1971        else if (argp->minorversion == 0 && op->opnum > LAST_NFS40_OP)
1972                return false;
1973        else if (argp->minorversion == 1 && op->opnum > LAST_NFS41_OP)
1974                return false;
1975        else if (argp->minorversion == 2 && op->opnum > LAST_NFS42_OP)
1976                return false;
1977        return true;
1978}
1979
1980static __be32
1981nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1982{
1983        DECODE_HEAD;
1984        struct nfsd4_op *op;
1985        bool cachethis = false;
1986        int auth_slack= argp->rqstp->rq_auth_slack;
1987        int max_reply = auth_slack + 8; /* opcnt, status */
1988        int readcount = 0;
1989        int readbytes = 0;
1990        int i;
1991
1992        READ_BUF(4);
1993        argp->taglen = be32_to_cpup(p++);
1994        READ_BUF(argp->taglen);
1995        SAVEMEM(argp->tag, argp->taglen);
1996        READ_BUF(8);
1997        argp->minorversion = be32_to_cpup(p++);
1998        argp->opcnt = be32_to_cpup(p++);
1999        max_reply += 4 + (XDR_QUADLEN(argp->taglen) << 2);
2000
2001        if (argp->taglen > NFSD4_MAX_TAGLEN)
2002                goto xdr_error;
2003        /*
2004         * NFS4ERR_RESOURCE is a more helpful error than GARBAGE_ARGS
2005         * here, so we return success at the xdr level so that
2006         * nfsd4_proc can handle this is an NFS-level error.
2007         */
2008        if (argp->opcnt > NFSD_MAX_OPS_PER_COMPOUND)
2009                return 0;
2010
2011        if (argp->opcnt > ARRAY_SIZE(argp->iops)) {
2012                argp->ops = kzalloc(argp->opcnt * sizeof(*argp->ops), GFP_KERNEL);
2013                if (!argp->ops) {
2014                        argp->ops = argp->iops;
2015                        dprintk("nfsd: couldn't allocate room for COMPOUND\n");
2016                        goto xdr_error;
2017                }
2018        }
2019
2020        if (argp->minorversion > NFSD_SUPPORTED_MINOR_VERSION)
2021                argp->opcnt = 0;
2022
2023        for (i = 0; i < argp->opcnt; i++) {
2024                op = &argp->ops[i];
2025                op->replay = NULL;
2026
2027                READ_BUF(4);
2028                op->opnum = be32_to_cpup(p++);
2029
2030                if (nfsd4_opnum_in_range(argp, op))
2031                        op->status = nfsd4_dec_ops[op->opnum](argp, &op->u);
2032                else {
2033                        op->opnum = OP_ILLEGAL;
2034                        op->status = nfserr_op_illegal;
2035                }
2036                op->opdesc = OPDESC(op);
2037                /*
2038                 * We'll try to cache the result in the DRC if any one
2039                 * op in the compound wants to be cached:
2040                 */
2041                cachethis |= nfsd4_cache_this_op(op);
2042
2043                if (op->opnum == OP_READ) {
2044                        readcount++;
2045                        readbytes += nfsd4_max_reply(argp->rqstp, op);
2046                } else
2047                        max_reply += nfsd4_max_reply(argp->rqstp, op);
2048                /*
2049                 * OP_LOCK and OP_LOCKT may return a conflicting lock.
2050                 * (Special case because it will just skip encoding this
2051                 * if it runs out of xdr buffer space, and it is the only
2052                 * operation that behaves this way.)
2053                 */
2054                if (op->opnum == OP_LOCK || op->opnum == OP_LOCKT)
2055                        max_reply += NFS4_OPAQUE_LIMIT;
2056
2057                if (op->status) {
2058                        argp->opcnt = i+1;
2059                        break;
2060                }
2061        }
2062        /* Sessions make the DRC unnecessary: */
2063        if (argp->minorversion)
2064                cachethis = false;
2065        svc_reserve(argp->rqstp, max_reply + readbytes);
2066        argp->rqstp->rq_cachetype = cachethis ? RC_REPLBUFF : RC_NOCACHE;
2067
2068        if (readcount > 1 || max_reply > PAGE_SIZE - auth_slack)
2069                clear_bit(RQ_SPLICE_OK, &argp->rqstp->rq_flags);
2070
2071        DECODE_TAIL;
2072}
2073
2074static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
2075                             struct svc_export *exp)
2076{
2077        if (exp->ex_flags & NFSEXP_V4ROOT) {
2078                *p++ = cpu_to_be32(convert_to_wallclock(exp->cd->flush_time));
2079                *p++ = 0;
2080        } else if (IS_I_VERSION(inode)) {
2081                p = xdr_encode_hyper(p, nfsd4_change_attribute(stat, inode));
2082        } else {
2083                *p++ = cpu_to_be32(stat->ctime.tv_sec);
2084                *p++ = cpu_to_be32(stat->ctime.tv_nsec);
2085        }
2086        return p;
2087}
2088
2089/*
2090 * ctime (in NFSv4, time_metadata) is not writeable, and the client
2091 * doesn't really care what resolution could theoretically be stored by
2092 * the filesystem.
2093 *
2094 * The client cares how close together changes can be while still
2095 * guaranteeing ctime changes.  For most filesystems (which have
2096 * timestamps with nanosecond fields) that is limited by the resolution
2097 * of the time returned from current_time() (which I'm assuming to be
2098 * 1/HZ).
2099 */
2100static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
2101{
2102        struct timespec64 ts;
2103        u32 ns;
2104
2105        ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
2106        ts = ns_to_timespec64(ns);
2107
2108        p = xdr_encode_hyper(p, ts.tv_sec);
2109        *p++ = cpu_to_be32(ts.tv_nsec);
2110
2111        return p;
2112}
2113
2114static __be32 *encode_cinfo(__be32 *p, struct nfsd4_change_info *c)
2115{
2116        *p++ = cpu_to_be32(c->atomic);
2117        if (c->change_supported) {
2118                p = xdr_encode_hyper(p, c->before_change);
2119                p = xdr_encode_hyper(p, c->after_change);
2120        } else {
2121                *p++ = cpu_to_be32(c->before_ctime_sec);
2122                *p++ = cpu_to_be32(c->before_ctime_nsec);
2123                *p++ = cpu_to_be32(c->after_ctime_sec);
2124                *p++ = cpu_to_be32(c->after_ctime_nsec);
2125        }
2126        return p;
2127}
2128
2129/* Encode as an array of strings the string given with components
2130 * separated @sep, escaped with esc_enter and esc_exit.
2131 */
2132static __be32 nfsd4_encode_components_esc(struct xdr_stream *xdr, char sep,
2133                                          char *components, char esc_enter,
2134                                          char esc_exit)
2135{
2136        __be32 *p;
2137        __be32 pathlen;
2138        int pathlen_offset;
2139        int strlen, count=0;
2140        char *str, *end, *next;
2141
2142        dprintk("nfsd4_encode_components(%s)\n", components);
2143
2144        pathlen_offset = xdr->buf->len;
2145        p = xdr_reserve_space(xdr, 4);
2146        if (!p)
2147                return nfserr_resource;
2148        p++; /* We will fill this in with @count later */
2149
2150        end = str = components;
2151        while (*end) {
2152                bool found_esc = false;
2153
2154                /* try to parse as esc_start, ..., esc_end, sep */
2155                if (*str == esc_enter) {
2156                        for (; *end && (*end != esc_exit); end++)
2157                                /* find esc_exit or end of string */;
2158                        next = end + 1;
2159                        if (*end && (!*next || *next == sep)) {
2160                                str++;
2161                                found_esc = true;
2162                        }
2163                }
2164
2165                if (!found_esc)
2166                        for (; *end && (*end != sep); end++)
2167                                /* find sep or end of string */;
2168
2169                strlen = end - str;
2170                if (strlen) {
2171                        p = xdr_reserve_space(xdr, strlen + 4);
2172                        if (!p)
2173                                return nfserr_resource;
2174                        p = xdr_encode_opaque(p, str, strlen);
2175                        count++;
2176                }
2177                else
2178                        end++;
2179                if (found_esc)
2180                        end = next;
2181
2182                str = end;
2183        }
2184        pathlen = htonl(count);
2185        write_bytes_to_xdr_buf(xdr->buf, pathlen_offset, &pathlen, 4);
2186        return 0;
2187}
2188
2189/* Encode as an array of strings the string given with components
2190 * separated @sep.
2191 */
2192static __be32 nfsd4_encode_components(struct xdr_stream *xdr, char sep,
2193                                      char *components)
2194{
2195        return nfsd4_encode_components_esc(xdr, sep, components, 0, 0);
2196}
2197
2198/*
2199 * encode a location element of a fs_locations structure
2200 */
2201static __be32 nfsd4_encode_fs_location4(struct xdr_stream *xdr,
2202                                        struct nfsd4_fs_location *location)
2203{
2204        __be32 status;
2205
2206        status = nfsd4_encode_components_esc(xdr, ':', location->hosts,
2207                                                '[', ']');
2208        if (status)
2209                return status;
2210        status = nfsd4_encode_components(xdr, '/', location->path);
2211        if (status)
2212                return status;
2213        return 0;
2214}
2215
2216/*
2217 * Encode a path in RFC3530 'pathname4' format
2218 */
2219static __be32 nfsd4_encode_path(struct xdr_stream *xdr,
2220                                const struct path *root,
2221                                const struct path *path)
2222{
2223        struct path cur = *path;
2224        __be32 *p;
2225        struct dentry **components = NULL;
2226        unsigned int ncomponents = 0;
2227        __be32 err = nfserr_jukebox;
2228
2229        dprintk("nfsd4_encode_components(");
2230
2231        path_get(&cur);
2232        /* First walk the path up to the nfsd root, and store the
2233         * dentries/path components in an array.
2234         */
2235        for (;;) {
2236                if (path_equal(&cur, root))
2237                        break;
2238                if (cur.dentry == cur.mnt->mnt_root) {
2239                        if (follow_up(&cur))
2240                                continue;
2241                        goto out_free;
2242                }
2243                if ((ncomponents & 15) == 0) {
2244                        struct dentry **new;
2245                        new = krealloc(components,
2246                                        sizeof(*new) * (ncomponents + 16),
2247                                        GFP_KERNEL);
2248                        if (!new)
2249                                goto out_free;
2250                        components = new;
2251                }
2252                components[ncomponents++] = cur.dentry;
2253                cur.dentry = dget_parent(cur.dentry);
2254        }
2255        err = nfserr_resource;
2256        p = xdr_reserve_space(xdr, 4);
2257        if (!p)
2258                goto out_free;
2259        *p++ = cpu_to_be32(ncomponents);
2260
2261        while (ncomponents) {
2262                struct dentry *dentry = components[ncomponents - 1];
2263                unsigned int len;
2264
2265                spin_lock(&dentry->d_lock);
2266                len = dentry->d_name.len;
2267                p = xdr_reserve_space(xdr, len + 4);
2268                if (!p) {
2269                        spin_unlock(&dentry->d_lock);
2270                        goto out_free;
2271                }
2272                p = xdr_encode_opaque(p, dentry->d_name.name, len);
2273                dprintk("/%pd", dentry);
2274                spin_unlock(&dentry->d_lock);
2275                dput(dentry);
2276                ncomponents--;
2277        }
2278
2279        err = 0;
2280out_free:
2281        dprintk(")\n");
2282        while (ncomponents)
2283                dput(components[--ncomponents]);
2284        kfree(components);
2285        path_put(&cur);
2286        return err;
2287}
2288
2289static __be32 nfsd4_encode_fsloc_fsroot(struct xdr_stream *xdr,
2290                        struct svc_rqst *rqstp, const struct path *path)
2291{
2292        struct svc_export *exp_ps;
2293        __be32 res;
2294
2295        exp_ps = rqst_find_fsidzero_export(rqstp);
2296        if (IS_ERR(exp_ps))
2297                return nfserrno(PTR_ERR(exp_ps));
2298        res = nfsd4_encode_path(xdr, &exp_ps->ex_path, path);
2299        exp_put(exp_ps);
2300        return res;
2301}
2302
2303/*
2304 *  encode a fs_locations structure
2305 */
2306static __be32 nfsd4_encode_fs_locations(struct xdr_stream *xdr,
2307                        struct svc_rqst *rqstp, struct svc_export *exp)
2308{
2309        __be32 status;
2310        int i;
2311        __be32 *p;
2312        struct nfsd4_fs_locations *fslocs = &exp->ex_fslocs;
2313
2314        status = nfsd4_encode_fsloc_fsroot(xdr, rqstp, &exp->ex_path);
2315        if (status)
2316                return status;
2317        p = xdr_reserve_space(xdr, 4);
2318        if (!p)
2319                return nfserr_resource;
2320        *p++ = cpu_to_be32(fslocs->locations_count);
2321        for (i=0; i<fslocs->locations_count; i++) {
2322                status = nfsd4_encode_fs_location4(xdr, &fslocs->locations[i]);
2323                if (status)
2324                        return status;
2325        }
2326        return 0;
2327}
2328
2329static u32 nfs4_file_type(umode_t mode)
2330{
2331        switch (mode & S_IFMT) {
2332        case S_IFIFO:   return NF4FIFO;
2333        case S_IFCHR:   return NF4CHR;
2334        case S_IFDIR:   return NF4DIR;
2335        case S_IFBLK:   return NF4BLK;
2336        case S_IFLNK:   return NF4LNK;
2337        case S_IFREG:   return NF4REG;
2338        case S_IFSOCK:  return NF4SOCK;
2339        default:        return NF4BAD;
2340        };
2341}
2342
2343static inline __be32
2344nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2345                     struct nfs4_ace *ace)
2346{
2347        if (ace->whotype != NFS4_ACL_WHO_NAMED)
2348                return nfs4_acl_write_who(xdr, ace->whotype);
2349        else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
2350                return nfsd4_encode_group(xdr, rqstp, ace->who_gid);
2351        else
2352                return nfsd4_encode_user(xdr, rqstp, ace->who_uid);
2353}
2354
2355static inline __be32
2356nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 layout_types)
2357{
2358        __be32          *p;
2359        unsigned long   i = hweight_long(layout_types);
2360
2361        p = xdr_reserve_space(xdr, 4 + 4 * i);
2362        if (!p)
2363                return nfserr_resource;
2364
2365        *p++ = cpu_to_be32(i);
2366
2367        for (i = LAYOUT_NFSV4_1_FILES; i < LAYOUT_TYPE_MAX; ++i)
2368                if (layout_types & (1 << i))
2369                        *p++ = cpu_to_be32(i);
2370
2371        return 0;
2372}
2373
2374#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
2375                              FATTR4_WORD0_RDATTR_ERROR)
2376#define WORD1_ABSENT_FS_ATTRS FATTR4_WORD1_MOUNTED_ON_FILEID
2377#define WORD2_ABSENT_FS_ATTRS 0
2378
2379#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2380static inline __be32
2381nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2382                            void *context, int len)
2383{
2384        __be32 *p;
2385
2386        p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
2387        if (!p)
2388                return nfserr_resource;
2389
2390        /*
2391         * For now we use a 0 here to indicate the null translation; in
2392         * the future we may place a call to translation code here.
2393         */
2394        *p++ = cpu_to_be32(0); /* lfs */
2395        *p++ = cpu_to_be32(0); /* pi */
2396        p = xdr_encode_opaque(p, context, len);
2397        return 0;
2398}
2399#else
2400static inline __be32
2401nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2402                            void *context, int len)
2403{ return 0; }
2404#endif
2405
2406static __be32 fattr_handle_absent_fs(u32 *bmval0, u32 *bmval1, u32 *bmval2, u32 *rdattr_err)
2407{
2408        /* As per referral draft:  */
2409        if (*bmval0 & ~WORD0_ABSENT_FS_ATTRS ||
2410            *bmval1 & ~WORD1_ABSENT_FS_ATTRS) {
2411                if (*bmval0 & FATTR4_WORD0_RDATTR_ERROR ||
2412                    *bmval0 & FATTR4_WORD0_FS_LOCATIONS)
2413                        *rdattr_err = NFSERR_MOVED;
2414                else
2415                        return nfserr_moved;
2416        }
2417        *bmval0 &= WORD0_ABSENT_FS_ATTRS;
2418        *bmval1 &= WORD1_ABSENT_FS_ATTRS;
2419        *bmval2 &= WORD2_ABSENT_FS_ATTRS;
2420        return 0;
2421}
2422
2423
2424static int get_parent_attributes(struct svc_export *exp, struct kstat *stat)
2425{
2426        struct path path = exp->ex_path;
2427        int err;
2428
2429        path_get(&path);
2430        while (follow_up(&path)) {
2431                if (path.dentry != path.mnt->mnt_root)
2432                        break;
2433        }
2434        err = vfs_getattr(&path, stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
2435        path_put(&path);
2436        return err;
2437}
2438
2439static __be32
2440nfsd4_encode_bitmap(struct xdr_stream *xdr, u32 bmval0, u32 bmval1, u32 bmval2)
2441{
2442        __be32 *p;
2443
2444        if (bmval2) {
2445                p = xdr_reserve_space(xdr, 16);
2446                if (!p)
2447                        goto out_resource;
2448                *p++ = cpu_to_be32(3);
2449                *p++ = cpu_to_be32(bmval0);
2450                *p++ = cpu_to_be32(bmval1);
2451                *p++ = cpu_to_be32(bmval2);
2452        } else if (bmval1) {
2453                p = xdr_reserve_space(xdr, 12);
2454                if (!p)
2455                        goto out_resource;
2456                *p++ = cpu_to_be32(2);
2457                *p++ = cpu_to_be32(bmval0);
2458                *p++ = cpu_to_be32(bmval1);
2459        } else {
2460                p = xdr_reserve_space(xdr, 8);
2461                if (!p)
2462                        goto out_resource;
2463                *p++ = cpu_to_be32(1);
2464                *p++ = cpu_to_be32(bmval0);
2465        }
2466
2467        return 0;
2468out_resource:
2469        return nfserr_resource;
2470}
2471
2472/*
2473 * Note: @fhp can be NULL; in this case, we might have to compose the filehandle
2474 * ourselves.
2475 */
2476static __be32
2477nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
2478                struct svc_export *exp,
2479                struct dentry *dentry, u32 *bmval,
2480                struct svc_rqst *rqstp, int ignore_crossmnt)
2481{
2482        u32 bmval0 = bmval[0];
2483        u32 bmval1 = bmval[1];
2484        u32 bmval2 = bmval[2];
2485        struct kstat stat;
2486        struct svc_fh *tempfh = NULL;
2487        struct kstatfs statfs;
2488        __be32 *p;
2489        int starting_len = xdr->buf->len;
2490        int attrlen_offset;
2491        __be32 attrlen;
2492        u32 dummy;
2493        u64 dummy64;
2494        u32 rdattr_err = 0;
2495        __be32 status;
2496        int err;
2497        struct nfs4_acl *acl = NULL;
2498#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2499        void *context = NULL;
2500        int contextlen;
2501#endif
2502        bool contextsupport = false;
2503        struct nfsd4_compoundres *resp = rqstp->rq_resp;
2504        u32 minorversion = resp->cstate.minorversion;
2505        struct path path = {
2506                .mnt    = exp->ex_path.mnt,
2507                .dentry = dentry,
2508        };
2509        struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
2510
2511        BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
2512        BUG_ON(!nfsd_attrs_supported(minorversion, bmval));
2513
2514        if (exp->ex_fslocs.migrated) {
2515                status = fattr_handle_absent_fs(&bmval0, &bmval1, &bmval2, &rdattr_err);
2516                if (status)
2517                        goto out;
2518        }
2519
2520        err = vfs_getattr(&path, &stat, STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
2521        if (err)
2522                goto out_nfserr;
2523        if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
2524                        FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
2525            (bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
2526                       FATTR4_WORD1_SPACE_TOTAL))) {
2527                err = vfs_statfs(&path, &statfs);
2528                if (err)
2529                        goto out_nfserr;
2530        }
2531        if ((bmval0 & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) {
2532                tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
2533                status = nfserr_jukebox;
2534                if (!tempfh)
2535                        goto out;
2536                fh_init(tempfh, NFS4_FHSIZE);
2537                status = fh_compose(tempfh, exp, dentry, NULL);
2538                if (status)
2539                        goto out;
2540                fhp = tempfh;
2541        }
2542        if (bmval0 & FATTR4_WORD0_ACL) {
2543                err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl);
2544                if (err == -EOPNOTSUPP)
2545                        bmval0 &= ~FATTR4_WORD0_ACL;
2546                else if (err == -EINVAL) {
2547                        status = nfserr_attrnotsupp;
2548                        goto out;
2549                } else if (err != 0)
2550                        goto out_nfserr;
2551        }
2552
2553#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2554        if ((bmval2 & FATTR4_WORD2_SECURITY_LABEL) ||
2555             bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2556                if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
2557                        err = security_inode_getsecctx(d_inode(dentry),
2558                                                &context, &contextlen);
2559                else
2560                        err = -EOPNOTSUPP;
2561                contextsupport = (err == 0);
2562                if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2563                        if (err == -EOPNOTSUPP)
2564                                bmval2 &= ~FATTR4_WORD2_SECURITY_LABEL;
2565                        else if (err)
2566                                goto out_nfserr;
2567                }
2568        }
2569#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
2570
2571        status = nfsd4_encode_bitmap(xdr, bmval0, bmval1, bmval2);
2572        if (status)
2573                goto out;
2574
2575        attrlen_offset = xdr->buf->len;
2576        p = xdr_reserve_space(xdr, 4);
2577        if (!p)
2578                goto out_resource;
2579        p++;                /* to be backfilled later */
2580
2581        if (bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
2582                u32 supp[3];
2583
2584                memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
2585
2586                if (!IS_POSIXACL(dentry->d_inode))
2587                        supp[0] &= ~FATTR4_WORD0_ACL;
2588                if (!contextsupport)
2589                        supp[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
2590                if (!supp[2]) {
2591                        p = xdr_reserve_space(xdr, 12);
2592                        if (!p)
2593                                goto out_resource;
2594                        *p++ = cpu_to_be32(2);
2595                        *p++ = cpu_to_be32(supp[0]);
2596                        *p++ = cpu_to_be32(supp[1]);
2597                } else {
2598                        p = xdr_reserve_space(xdr, 16);
2599                        if (!p)
2600                                goto out_resource;
2601                        *p++ = cpu_to_be32(3);
2602                        *p++ = cpu_to_be32(supp[0]);
2603                        *p++ = cpu_to_be32(supp[1]);
2604                        *p++ = cpu_to_be32(supp[2]);
2605                }
2606        }
2607        if (bmval0 & FATTR4_WORD0_TYPE) {
2608                p = xdr_reserve_space(xdr, 4);
2609                if (!p)
2610                        goto out_resource;
2611                dummy = nfs4_file_type(stat.mode);
2612                if (dummy == NF4BAD) {
2613                        status = nfserr_serverfault;
2614                        goto out;
2615                }
2616                *p++ = cpu_to_be32(dummy);
2617        }
2618        if (bmval0 & FATTR4_WORD0_FH_EXPIRE_TYPE) {
2619                p = xdr_reserve_space(xdr, 4);
2620                if (!p)
2621                        goto out_resource;
2622                if (exp->ex_flags & NFSEXP_NOSUBTREECHECK)
2623                        *p++ = cpu_to_be32(NFS4_FH_PERSISTENT);
2624                else
2625                        *p++ = cpu_to_be32(NFS4_FH_PERSISTENT|
2626                                                NFS4_FH_VOL_RENAME);
2627        }
2628        if (bmval0 & FATTR4_WORD0_CHANGE) {
2629                p = xdr_reserve_space(xdr, 8);
2630                if (!p)
2631                        goto out_resource;
2632                p = encode_change(p, &stat, d_inode(dentry), exp);
2633        }
2634        if (bmval0 & FATTR4_WORD0_SIZE) {
2635                p = xdr_reserve_space(xdr, 8);
2636                if (!p)
2637                        goto out_resource;
2638                p = xdr_encode_hyper(p, stat.size);
2639        }
2640        if (bmval0 & FATTR4_WORD0_LINK_SUPPORT) {
2641                p = xdr_reserve_space(xdr, 4);
2642                if (!p)
2643                        goto out_resource;
2644                *p++ = cpu_to_be32(1);
2645        }
2646        if (bmval0 & FATTR4_WORD0_SYMLINK_SUPPORT) {
2647                p = xdr_reserve_space(xdr, 4);
2648                if (!p)
2649                        goto out_resource;
2650                *p++ = cpu_to_be32(1);
2651        }
2652        if (bmval0 & FATTR4_WORD0_NAMED_ATTR) {
2653                p = xdr_reserve_space(xdr, 4);
2654                if (!p)
2655                        goto out_resource;
2656                *p++ = cpu_to_be32(0);
2657        }
2658        if (bmval0 & FATTR4_WORD0_FSID) {
2659                p = xdr_reserve_space(xdr, 16);
2660                if (!p)
2661                        goto out_resource;
2662                if (exp->ex_fslocs.migrated) {
2663                        p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MAJOR);
2664                        p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
2665                } else switch(fsid_source(fhp)) {
2666                case FSIDSOURCE_FSID:
2667                        p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
2668                        p = xdr_encode_hyper(p, (u64)0);
2669                        break;
2670                case FSIDSOURCE_DEV:
2671                        *p++ = cpu_to_be32(0);
2672                        *p++ = cpu_to_be32(MAJOR(stat.dev));
2673                        *p++ = cpu_to_be32(0);
2674                        *p++ = cpu_to_be32(MINOR(stat.dev));
2675                        break;
2676                case FSIDSOURCE_UUID:
2677                        p = xdr_encode_opaque_fixed(p, exp->ex_uuid,
2678                                                                EX_UUID_LEN);
2679                        break;
2680                }
2681        }
2682        if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
2683                p = xdr_reserve_space(xdr, 4);
2684                if (!p)
2685                        goto out_resource;
2686                *p++ = cpu_to_be32(0);
2687        }
2688        if (bmval0 & FATTR4_WORD0_LEASE_TIME) {
2689                p = xdr_reserve_space(xdr, 4);
2690                if (!p)
2691                        goto out_resource;
2692                *p++ = cpu_to_be32(nn->nfsd4_lease);
2693        }
2694        if (bmval0 & FATTR4_WORD0_RDATTR_ERROR) {
2695                p = xdr_reserve_space(xdr, 4);
2696                if (!p)
2697                        goto out_resource;
2698                *p++ = cpu_to_be32(rdattr_err);
2699        }
2700        if (bmval0 & FATTR4_WORD0_ACL) {
2701                struct nfs4_ace *ace;
2702
2703                if (acl == NULL) {
2704                        p = xdr_reserve_space(xdr, 4);
2705                        if (!p)
2706                                goto out_resource;
2707
2708                        *p++ = cpu_to_be32(0);
2709                        goto out_acl;
2710                }
2711                p = xdr_reserve_space(xdr, 4);
2712                if (!p)
2713                        goto out_resource;
2714                *p++ = cpu_to_be32(acl->naces);
2715
2716                for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) {
2717                        p = xdr_reserve_space(xdr, 4*3);
2718                        if (!p)
2719                                goto out_resource;
2720                        *p++ = cpu_to_be32(ace->type);
2721                        *p++ = cpu_to_be32(ace->flag);
2722                        *p++ = cpu_to_be32(ace->access_mask &
2723                                                        NFS4_ACE_MASK_ALL);
2724                        status = nfsd4_encode_aclname(xdr, rqstp, ace);
2725                        if (status)
2726                                goto out;
2727                }
2728        }
2729out_acl:
2730        if (bmval0 & FATTR4_WORD0_ACLSUPPORT) {
2731                p = xdr_reserve_space(xdr, 4);
2732                if (!p)
2733                        goto out_resource;
2734                *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ?
2735                        ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0);
2736        }
2737        if (bmval0 & FATTR4_WORD0_CANSETTIME) {
2738                p = xdr_reserve_space(xdr, 4);
2739                if (!p)
2740                        goto out_resource;
2741                *p++ = cpu_to_be32(1);
2742        }
2743        if (bmval0 & FATTR4_WORD0_CASE_INSENSITIVE) {
2744                p = xdr_reserve_space(xdr, 4);
2745                if (!p)
2746                        goto out_resource;
2747                *p++ = cpu_to_be32(0);
2748        }
2749        if (bmval0 & FATTR4_WORD0_CASE_PRESERVING) {
2750                p = xdr_reserve_space(xdr, 4);
2751                if (!p)
2752                        goto out_resource;
2753                *p++ = cpu_to_be32(1);
2754        }
2755        if (bmval0 & FATTR4_WORD0_CHOWN_RESTRICTED) {
2756                p = xdr_reserve_space(xdr, 4);
2757                if (!p)
2758                        goto out_resource;
2759                *p++ = cpu_to_be32(1);
2760        }
2761        if (bmval0 & FATTR4_WORD0_FILEHANDLE) {
2762                p = xdr_reserve_space(xdr, fhp->fh_handle.fh_size + 4);
2763                if (!p)
2764                        goto out_resource;
2765                p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base,
2766                                        fhp->fh_handle.fh_size);
2767        }
2768        if (bmval0 & FATTR4_WORD0_FILEID) {
2769                p = xdr_reserve_space(xdr, 8);
2770                if (!p)
2771                        goto out_resource;
2772                p = xdr_encode_hyper(p, stat.ino);
2773        }
2774        if (bmval0 & FATTR4_WORD0_FILES_AVAIL) {
2775                p = xdr_reserve_space(xdr, 8);
2776                if (!p)
2777                        goto out_resource;
2778                p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
2779        }
2780        if (bmval0 & FATTR4_WORD0_FILES_FREE) {
2781                p = xdr_reserve_space(xdr, 8);
2782                if (!p)
2783                        goto out_resource;
2784                p = xdr_encode_hyper(p, (u64) statfs.f_ffree);
2785        }
2786        if (bmval0 & FATTR4_WORD0_FILES_TOTAL) {
2787                p = xdr_reserve_space(xdr, 8);
2788                if (!p)
2789                        goto out_resource;
2790                p = xdr_encode_hyper(p, (u64) statfs.f_files);
2791        }
2792        if (bmval0 & FATTR4_WORD0_FS_LOCATIONS) {
2793                status = nfsd4_encode_fs_locations(xdr, rqstp, exp);
2794                if (status)
2795                        goto out;
2796        }
2797        if (bmval0 & FATTR4_WORD0_HOMOGENEOUS) {
2798                p = xdr_reserve_space(xdr, 4);
2799                if (!p)
2800                        goto out_resource;
2801                *p++ = cpu_to_be32(1);
2802        }
2803        if (bmval0 & FATTR4_WORD0_MAXFILESIZE) {
2804                p = xdr_reserve_space(xdr, 8);
2805                if (!p)
2806                        goto out_resource;
2807                p = xdr_encode_hyper(p, exp->ex_path.mnt->mnt_sb->s_maxbytes);
2808        }
2809        if (bmval0 & FATTR4_WORD0_MAXLINK) {
2810                p = xdr_reserve_space(xdr, 4);
2811                if (!p)
2812                        goto out_resource;
2813                *p++ = cpu_to_be32(255);
2814        }
2815        if (bmval0 & FATTR4_WORD0_MAXNAME) {
2816                p = xdr_reserve_space(xdr, 4);
2817                if (!p)
2818                        goto out_resource;
2819                *p++ = cpu_to_be32(statfs.f_namelen);
2820        }
2821        if (bmval0 & FATTR4_WORD0_MAXREAD) {
2822                p = xdr_reserve_space(xdr, 8);
2823                if (!p)
2824                        goto out_resource;
2825                p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
2826        }
2827        if (bmval0 & FATTR4_WORD0_MAXWRITE) {
2828                p = xdr_reserve_space(xdr, 8);
2829                if (!p)
2830                        goto out_resource;
2831                p = xdr_encode_hyper(p, (u64) svc_max_payload(rqstp));
2832        }
2833        if (bmval1 & FATTR4_WORD1_MODE) {
2834                p = xdr_reserve_space(xdr, 4);
2835                if (!p)
2836                        goto out_resource;
2837                *p++ = cpu_to_be32(stat.mode & S_IALLUGO);
2838        }
2839        if (bmval1 & FATTR4_WORD1_NO_TRUNC) {
2840                p = xdr_reserve_space(xdr, 4);
2841                if (!p)
2842                        goto out_resource;
2843                *p++ = cpu_to_be32(1);
2844        }
2845        if (bmval1 & FATTR4_WORD1_NUMLINKS) {
2846                p = xdr_reserve_space(xdr, 4);
2847                if (!p)
2848                        goto out_resource;
2849                *p++ = cpu_to_be32(stat.nlink);
2850        }
2851        if (bmval1 & FATTR4_WORD1_OWNER) {
2852                status = nfsd4_encode_user(xdr, rqstp, stat.uid);
2853                if (status)
2854                        goto out;
2855        }
2856        if (bmval1 & FATTR4_WORD1_OWNER_GROUP) {
2857                status = nfsd4_encode_group(xdr, rqstp, stat.gid);
2858                if (status)
2859                        goto out;
2860        }
2861        if (bmval1 & FATTR4_WORD1_RAWDEV) {
2862                p = xdr_reserve_space(xdr, 8);
2863                if (!p)
2864                        goto out_resource;
2865                *p++ = cpu_to_be32((u32) MAJOR(stat.rdev));
2866                *p++ = cpu_to_be32((u32) MINOR(stat.rdev));
2867        }
2868        if (bmval1 & FATTR4_WORD1_SPACE_AVAIL) {
2869                p = xdr_reserve_space(xdr, 8);
2870                if (!p)
2871                        goto out_resource;
2872                dummy64 = (u64)statfs.f_bavail * (u64)statfs.f_bsize;
2873                p = xdr_encode_hyper(p, dummy64);
2874        }
2875        if (bmval1 & FATTR4_WORD1_SPACE_FREE) {
2876                p = xdr_reserve_space(xdr, 8);
2877                if (!p)
2878                        goto out_resource;
2879                dummy64 = (u64)statfs.f_bfree * (u64)statfs.f_bsize;
2880                p = xdr_encode_hyper(p, dummy64);
2881        }
2882        if (bmval1 & FATTR4_WORD1_SPACE_TOTAL) {
2883                p = xdr_reserve_space(xdr, 8);
2884                if (!p)
2885                        goto out_resource;
2886                dummy64 = (u64)statfs.f_blocks * (u64)statfs.f_bsize;
2887                p = xdr_encode_hyper(p, dummy64);
2888        }
2889        if (bmval1 & FATTR4_WORD1_SPACE_USED) {
2890                p = xdr_reserve_space(xdr, 8);
2891                if (!p)
2892                        goto out_resource;
2893                dummy64 = (u64)stat.blocks << 9;
2894                p = xdr_encode_hyper(p, dummy64);
2895        }
2896        if (bmval1 & FATTR4_WORD1_TIME_ACCESS) {
2897                p = xdr_reserve_space(xdr, 12);
2898                if (!p)
2899                        goto out_resource;
2900                p = xdr_encode_hyper(p, (s64)stat.atime.tv_sec);
2901                *p++ = cpu_to_be32(stat.atime.tv_nsec);
2902        }
2903        if (bmval1 & FATTR4_WORD1_TIME_DELTA) {
2904                p = xdr_reserve_space(xdr, 12);
2905                if (!p)
2906                        goto out_resource;
2907                p = encode_time_delta(p, d_inode(dentry));
2908        }
2909        if (bmval1 & FATTR4_WORD1_TIME_METADATA) {
2910                p = xdr_reserve_space(xdr, 12);
2911                if (!p)
2912                        goto out_resource;
2913                p = xdr_encode_hyper(p, (s64)stat.ctime.tv_sec);
2914                *p++ = cpu_to_be32(stat.ctime.tv_nsec);
2915        }
2916        if (bmval1 & FATTR4_WORD1_TIME_MODIFY) {
2917                p = xdr_reserve_space(xdr, 12);
2918                if (!p)
2919                        goto out_resource;
2920                p = xdr_encode_hyper(p, (s64)stat.mtime.tv_sec);
2921                *p++ = cpu_to_be32(stat.mtime.tv_nsec);
2922        }
2923        if (bmval1 & FATTR4_WORD1_MOUNTED_ON_FILEID) {
2924                struct kstat parent_stat;
2925                u64 ino = stat.ino;
2926
2927                p = xdr_reserve_space(xdr, 8);
2928                if (!p)
2929                        goto out_resource;
2930                /*
2931                 * Get parent's attributes if not ignoring crossmount
2932                 * and this is the root of a cross-mounted filesystem.
2933                 */
2934                if (ignore_crossmnt == 0 &&
2935                    dentry == exp->ex_path.mnt->mnt_root) {
2936                        err = get_parent_attributes(exp, &parent_stat);
2937                        if (err)
2938                                goto out_nfserr;
2939                        ino = parent_stat.ino;
2940                }
2941                p = xdr_encode_hyper(p, ino);
2942        }
2943#ifdef CONFIG_NFSD_PNFS
2944        if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) {
2945                status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
2946                if (status)
2947                        goto out;
2948        }
2949
2950        if (bmval2 & FATTR4_WORD2_LAYOUT_TYPES) {
2951                status = nfsd4_encode_layout_types(xdr, exp->ex_layout_types);
2952                if (status)
2953                        goto out;
2954        }
2955
2956        if (bmval2 & FATTR4_WORD2_LAYOUT_BLKSIZE) {
2957                p = xdr_reserve_space(xdr, 4);
2958                if (!p)
2959                        goto out_resource;
2960                *p++ = cpu_to_be32(stat.blksize);
2961        }
2962#endif /* CONFIG_NFSD_PNFS */
2963        if (bmval2 & FATTR4_WORD2_SUPPATTR_EXCLCREAT) {
2964                u32 supp[3];
2965
2966                memcpy(supp, nfsd_suppattrs[minorversion], sizeof(supp));
2967                supp[0] &= NFSD_SUPPATTR_EXCLCREAT_WORD0;
2968                supp[1] &= NFSD_SUPPATTR_EXCLCREAT_WORD1;
2969                supp[2] &= NFSD_SUPPATTR_EXCLCREAT_WORD2;
2970
2971                status = nfsd4_encode_bitmap(xdr, supp[0], supp[1], supp[2]);
2972                if (status)
2973                        goto out;
2974        }
2975
2976        if (bmval2 & FATTR4_WORD2_CHANGE_ATTR_TYPE) {
2977                p = xdr_reserve_space(xdr, 4);
2978                if (!p)
2979                        goto out_resource;
2980                if (IS_I_VERSION(d_inode(dentry)))
2981                        *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR);
2982                else
2983                        *p++ = cpu_to_be32(NFS4_CHANGE_TYPE_IS_TIME_METADATA);
2984        }
2985
2986#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2987        if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
2988                status = nfsd4_encode_security_label(xdr, rqstp, context,
2989                                                                contextlen);
2990                if (status)
2991                        goto out;
2992        }
2993#endif
2994
2995        attrlen = htonl(xdr->buf->len - attrlen_offset - 4);
2996        write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4);
2997        status = nfs_ok;
2998
2999out:
3000#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3001        if (context)
3002                security_release_secctx(context, contextlen);
3003#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
3004        kfree(acl);
3005        if (tempfh) {
3006                fh_put(tempfh);
3007                kfree(tempfh);
3008        }
3009        if (status)
3010                xdr_truncate_encode(xdr, starting_len);
3011        return status;
3012out_nfserr:
3013        status = nfserrno(err);
3014        goto out;
3015out_resource:
3016        status = nfserr_resource;
3017        goto out;
3018}
3019
3020static void svcxdr_init_encode_from_buffer(struct xdr_stream *xdr,
3021                                struct xdr_buf *buf, __be32 *p, int bytes)
3022{
3023        xdr->scratch.iov_len = 0;
3024        memset(buf, 0, sizeof(struct xdr_buf));
3025        buf->head[0].iov_base = p;
3026        buf->head[0].iov_len = 0;
3027        buf->len = 0;
3028        xdr->buf = buf;
3029        xdr->iov = buf->head;
3030        xdr->p = p;
3031        xdr->end = (void *)p + bytes;
3032        buf->buflen = bytes;
3033}
3034
3035__be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words,
3036                        struct svc_fh *fhp, struct svc_export *exp,
3037                        struct dentry *dentry, u32 *bmval,
3038                        struct svc_rqst *rqstp, int ignore_crossmnt)
3039{
3040        struct xdr_buf dummy;
3041        struct xdr_stream xdr;
3042        __be32 ret;
3043
3044        svcxdr_init_encode_from_buffer(&xdr, &dummy, *p, words << 2);
3045        ret = nfsd4_encode_fattr(&xdr, fhp, exp, dentry, bmval, rqstp,
3046                                                        ignore_crossmnt);
3047        *p = xdr.p;
3048        return ret;
3049}
3050
3051static inline int attributes_need_mount(u32 *bmval)
3052{
3053        if (bmval[0] & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_LEASE_TIME))
3054                return 1;
3055        if (bmval[1] & ~FATTR4_WORD1_MOUNTED_ON_FILEID)
3056                return 1;
3057        return 0;
3058}
3059
3060static __be32
3061nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
3062                        const char *name, int namlen)
3063{
3064        struct svc_export *exp = cd->rd_fhp->fh_export;
3065        struct dentry *dentry;
3066        __be32 nfserr;
3067        int ignore_crossmnt = 0;
3068
3069        dentry = lookup_positive_unlocked(name, cd->rd_fhp->fh_dentry, namlen);
3070        if (IS_ERR(dentry))
3071                return nfserrno(PTR_ERR(dentry));
3072
3073        exp_get(exp);
3074        /*
3075         * In the case of a mountpoint, the client may be asking for
3076         * attributes that are only properties of the underlying filesystem
3077         * as opposed to the cross-mounted file system. In such a case,
3078         * we will not follow the cross mount and will fill the attribtutes
3079         * directly from the mountpoint dentry.
3080         */
3081        if (nfsd_mountpoint(dentry, exp)) {
3082                int err;
3083
3084                if (!(exp->ex_flags & NFSEXP_V4ROOT)
3085                                && !attributes_need_mount(cd->rd_bmval)) {
3086                        ignore_crossmnt = 1;
3087                        goto out_encode;
3088                }
3089                /*
3090                 * Why the heck aren't we just using nfsd_lookup??
3091                 * Different "."/".." handling?  Something else?
3092                 * At least, add a comment here to explain....
3093                 */
3094                err = nfsd_cross_mnt(cd->rd_rqstp, &dentry, &exp);
3095                if (err) {
3096                        nfserr = nfserrno(err);
3097                        goto out_put;
3098                }
3099                nfserr = check_nfsd_access(exp, cd->rd_rqstp);
3100                if (nfserr)
3101                        goto out_put;
3102
3103        }
3104out_encode:
3105        nfserr = nfsd4_encode_fattr(xdr, NULL, exp, dentry, cd->rd_bmval,
3106                                        cd->rd_rqstp, ignore_crossmnt);
3107out_put:
3108        dput(dentry);
3109        exp_put(exp);
3110        return nfserr;
3111}
3112
3113static __be32 *
3114nfsd4_encode_rdattr_error(struct xdr_stream *xdr, __be32 nfserr)
3115{
3116        __be32 *p;
3117
3118        p = xdr_reserve_space(xdr, 20);
3119        if (!p)
3120                return NULL;
3121        *p++ = htonl(2);
3122        *p++ = htonl(FATTR4_WORD0_RDATTR_ERROR); /* bmval0 */
3123        *p++ = htonl(0);                         /* bmval1 */
3124
3125        *p++ = htonl(4);     /* attribute length */
3126        *p++ = nfserr;       /* no htonl */
3127        return p;
3128}
3129
3130static int
3131nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
3132                    loff_t offset, u64 ino, unsigned int d_type)
3133{
3134        struct readdir_cd *ccd = ccdv;
3135        struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
3136        struct xdr_stream *xdr = cd->xdr;
3137        int start_offset = xdr->buf->len;
3138        int cookie_offset;
3139        u32 name_and_cookie;
3140        int entry_bytes;
3141        __be32 nfserr = nfserr_toosmall;
3142        __be64 wire_offset;
3143        __be32 *p;
3144
3145        /* In nfsv4, "." and ".." never make it onto the wire.. */
3146        if (name && isdotent(name, namlen)) {
3147                cd->common.err = nfs_ok;
3148                return 0;
3149        }
3150
3151        if (cd->cookie_offset) {
3152                wire_offset = cpu_to_be64(offset);
3153                write_bytes_to_xdr_buf(xdr->buf, cd->cookie_offset,
3154                                                        &wire_offset, 8);
3155        }
3156
3157        p = xdr_reserve_space(xdr, 4);
3158        if (!p)
3159                goto fail;
3160        *p++ = xdr_one;                             /* mark entry present */
3161        cookie_offset = xdr->buf->len;
3162        p = xdr_reserve_space(xdr, 3*4 + namlen);
3163        if (!p)
3164                goto fail;
3165        p = xdr_encode_hyper(p, NFS_OFFSET_MAX);    /* offset of next entry */
3166        p = xdr_encode_array(p, name, namlen);      /* name length & name */
3167
3168        nfserr = nfsd4_encode_dirent_fattr(xdr, cd, name, namlen);
3169        switch (nfserr) {
3170        case nfs_ok:
3171                break;
3172        case nfserr_resource:
3173                nfserr = nfserr_toosmall;
3174                goto fail;
3175        case nfserr_noent:
3176                xdr_truncate_encode(xdr, start_offset);
3177                goto skip_entry;
3178        default:
3179                /*
3180                 * If the client requested the RDATTR_ERROR attribute,
3181                 * we stuff the error code into this attribute
3182                 * and continue.  If this attribute was not requested,
3183                 * then in accordance with the spec, we fail the
3184                 * entire READDIR operation(!)
3185                 */
3186                if (!(cd->rd_bmval[0] & FATTR4_WORD0_RDATTR_ERROR))
3187                        goto fail;
3188                p = nfsd4_encode_rdattr_error(xdr, nfserr);
3189                if (p == NULL) {
3190                        nfserr = nfserr_toosmall;
3191                        goto fail;
3192                }
3193        }
3194        nfserr = nfserr_toosmall;
3195        entry_bytes = xdr->buf->len - start_offset;
3196        if (entry_bytes > cd->rd_maxcount)
3197                goto fail;
3198        cd->rd_maxcount -= entry_bytes;
3199        /*
3200         * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so
3201         * let's always let through the first entry, at least:
3202         */
3203        if (!cd->rd_dircount)
3204                goto fail;
3205        name_and_cookie = 4 + 4 * XDR_QUADLEN(namlen) + 8;
3206        if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
3207                goto fail;
3208        cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
3209
3210        cd->cookie_offset = cookie_offset;
3211skip_entry:
3212        cd->common.err = nfs_ok;
3213        return 0;
3214fail:
3215        xdr_truncate_encode(xdr, start_offset);
3216        cd->common.err = nfserr;
3217        return -EINVAL;
3218}
3219
3220static __be32
3221nfsd4_encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
3222{
3223        __be32 *p;
3224
3225        p = xdr_reserve_space(xdr, sizeof(stateid_t));
3226        if (!p)
3227                return nfserr_resource;
3228        *p++ = cpu_to_be32(sid->si_generation);
3229        p = xdr_encode_opaque_fixed(p, &sid->si_opaque,
3230                                        sizeof(stateid_opaque_t));
3231        return 0;
3232}
3233
3234static __be32
3235nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_access *access)
3236{
3237        struct xdr_stream *xdr = &resp->xdr;
3238        __be32 *p;
3239
3240        p = xdr_reserve_space(xdr, 8);
3241        if (!p)
3242                return nfserr_resource;
3243        *p++ = cpu_to_be32(access->ac_supported);
3244        *p++ = cpu_to_be32(access->ac_resp_access);
3245        return 0;
3246}
3247
3248static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
3249{
3250        struct xdr_stream *xdr = &resp->xdr;
3251        __be32 *p;
3252
3253        p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
3254        if (!p)
3255                return nfserr_resource;
3256        p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
3257                                        NFS4_MAX_SESSIONID_LEN);
3258        *p++ = cpu_to_be32(bcts->dir);
3259        /* Upshifting from TCP to RDMA is not supported */
3260        *p++ = cpu_to_be32(0);
3261        return 0;
3262}
3263
3264static __be32
3265nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_close *close)
3266{
3267        struct xdr_stream *xdr = &resp->xdr;
3268
3269        return nfsd4_encode_stateid(xdr, &close->cl_stateid);
3270}
3271
3272
3273static __be32
3274nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_commit *commit)
3275{
3276        struct xdr_stream *xdr = &resp->xdr;
3277        __be32 *p;
3278
3279        p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
3280        if (!p)
3281                return nfserr_resource;
3282        p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
3283                                                NFS4_VERIFIER_SIZE);
3284        return 0;
3285}
3286
3287static __be32
3288nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_create *create)
3289{
3290        struct xdr_stream *xdr = &resp->xdr;
3291        __be32 *p;
3292
3293        p = xdr_reserve_space(xdr, 20);
3294        if (!p)
3295                return nfserr_resource;
3296        encode_cinfo(p, &create->cr_cinfo);
3297        return nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
3298                        create->cr_bmval[1], create->cr_bmval[2]);
3299}
3300
3301static __be32
3302nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_getattr *getattr)
3303{
3304        struct svc_fh *fhp = getattr->ga_fhp;
3305        struct xdr_stream *xdr = &resp->xdr;
3306
3307        return nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
3308                                    getattr->ga_bmval, resp->rqstp, 0);
3309}
3310
3311static __be32
3312nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh **fhpp)
3313{
3314        struct xdr_stream *xdr = &resp->xdr;
3315        struct svc_fh *fhp = *fhpp;
3316        unsigned int len;
3317        __be32 *p;
3318
3319        len = fhp->fh_handle.fh_size;
3320        p = xdr_reserve_space(xdr, len + 4);
3321        if (!p)
3322                return nfserr_resource;
3323        p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len);
3324        return 0;
3325}
3326
3327/*
3328* Including all fields other than the name, a LOCK4denied structure requires
3329*   8(clientid) + 4(namelen) + 8(offset) + 8(length) + 4(type) = 32 bytes.
3330*/
3331static __be32
3332nfsd4_encode_lock_denied(struct xdr_stream *xdr, struct nfsd4_lock_denied *ld)
3333{
3334        struct xdr_netobj *conf = &ld->ld_owner;
3335        __be32 *p;
3336
3337again:
3338        p = xdr_reserve_space(xdr, 32 + XDR_LEN(conf->len));
3339        if (!p) {
3340                /*
3341                 * Don't fail to return the result just because we can't
3342                 * return the conflicting open:
3343                 */
3344                if (conf->len) {
3345                        kfree(conf->data);
3346                        conf->len = 0;
3347                        conf->data = NULL;
3348                        goto again;
3349                }
3350                return nfserr_resource;
3351        }
3352        p = xdr_encode_hyper(p, ld->ld_start);
3353        p = xdr_encode_hyper(p, ld->ld_length);
3354        *p++ = cpu_to_be32(ld->ld_type);
3355        if (conf->len) {
3356                p = xdr_encode_opaque_fixed(p, &ld->ld_clientid, 8);
3357                p = xdr_encode_opaque(p, conf->data, conf->len);
3358                kfree(conf->data);
3359        }  else {  /* non - nfsv4 lock in conflict, no clientid nor owner */
3360                p = xdr_encode_hyper(p, (u64)0); /* clientid */
3361                *p++ = cpu_to_be32(0); /* length of owner name */
3362        }
3363        return nfserr_denied;
3364}
3365
3366static __be32
3367nfsd4_encode_lock(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lock *lock)
3368{
3369        struct xdr_stream *xdr = &resp->xdr;
3370
3371        if (!nfserr)
3372                nfserr = nfsd4_encode_stateid(xdr, &lock->lk_resp_stateid);
3373        else if (nfserr == nfserr_denied)
3374                nfserr = nfsd4_encode_lock_denied(xdr, &lock->lk_denied);
3375
3376        return nfserr;
3377}
3378
3379static __be32
3380nfsd4_encode_lockt(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_lockt *lockt)
3381{
3382        struct xdr_stream *xdr = &resp->xdr;
3383
3384        if (nfserr == nfserr_denied)
3385                nfsd4_encode_lock_denied(xdr, &lockt->lt_denied);
3386        return nfserr;
3387}
3388
3389static __be32
3390nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_locku *locku)
3391{
3392        struct xdr_stream *xdr = &resp->xdr;
3393
3394        return nfsd4_encode_stateid(xdr, &locku->lu_stateid);
3395}
3396
3397
3398static __be32
3399nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_link *link)
3400{
3401        struct xdr_stream *xdr = &resp->xdr;
3402        __be32 *p;
3403
3404        p = xdr_reserve_space(xdr, 20);
3405        if (!p)
3406                return nfserr_resource;
3407        p = encode_cinfo(p, &link->li_cinfo);
3408        return 0;
3409}
3410
3411
3412static __be32
3413nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open *open)
3414{
3415        struct xdr_stream *xdr = &resp->xdr;
3416        __be32 *p;
3417
3418        nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
3419        if (nfserr)
3420                return nfserr;
3421        p = xdr_reserve_space(xdr, 24);
3422        if (!p)
3423                return nfserr_resource;
3424        p = encode_cinfo(p, &open->op_cinfo);
3425        *p++ = cpu_to_be32(open->op_rflags);
3426
3427        nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1],
3428                                        open->op_bmval[2]);
3429        if (nfserr)
3430                return nfserr;
3431
3432        p = xdr_reserve_space(xdr, 4);
3433        if (!p)
3434                return nfserr_resource;
3435
3436        *p++ = cpu_to_be32(open->op_delegate_type);
3437        switch (open->op_delegate_type) {
3438        case NFS4_OPEN_DELEGATE_NONE:
3439                break;
3440        case NFS4_OPEN_DELEGATE_READ:
3441                nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3442                if (nfserr)
3443                        return nfserr;
3444                p = xdr_reserve_space(xdr, 20);
3445                if (!p)
3446                        return nfserr_resource;
3447                *p++ = cpu_to_be32(open->op_recall);
3448
3449                /*
3450                 * TODO: ACE's in delegations
3451                 */
3452                *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3453                *p++ = cpu_to_be32(0);
3454                *p++ = cpu_to_be32(0);
3455                *p++ = cpu_to_be32(0);   /* XXX: is NULL principal ok? */
3456                break;
3457        case NFS4_OPEN_DELEGATE_WRITE:
3458                nfserr = nfsd4_encode_stateid(xdr, &open->op_delegate_stateid);
3459                if (nfserr)
3460                        return nfserr;
3461                p = xdr_reserve_space(xdr, 32);
3462                if (!p)
3463                        return nfserr_resource;
3464                *p++ = cpu_to_be32(0);
3465
3466                /*
3467                 * TODO: space_limit's in delegations
3468                 */
3469                *p++ = cpu_to_be32(NFS4_LIMIT_SIZE);
3470                *p++ = cpu_to_be32(~(u32)0);
3471                *p++ = cpu_to_be32(~(u32)0);
3472
3473                /*
3474                 * TODO: ACE's in delegations
3475                 */
3476                *p++ = cpu_to_be32(NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE);
3477                *p++ = cpu_to_be32(0);
3478                *p++ = cpu_to_be32(0);
3479                *p++ = cpu_to_be32(0);   /* XXX: is NULL principal ok? */
3480                break;
3481        case NFS4_OPEN_DELEGATE_NONE_EXT: /* 4.1 */
3482                switch (open->op_why_no_deleg) {
3483                case WND4_CONTENTION:
3484                case WND4_RESOURCE:
3485                        p = xdr_reserve_space(xdr, 8);
3486                        if (!p)
3487                                return nfserr_resource;
3488                        *p++ = cpu_to_be32(open->op_why_no_deleg);
3489                        /* deleg signaling not supported yet: */
3490                        *p++ = cpu_to_be32(0);
3491                        break;
3492                default:
3493                        p = xdr_reserve_space(xdr, 4);
3494                        if (!p)
3495                                return nfserr_resource;
3496                        *p++ = cpu_to_be32(open->op_why_no_deleg);
3497                }
3498                break;
3499        default:
3500                BUG();
3501        }
3502        /* XXX save filehandle here */
3503        return 0;
3504}
3505
3506static __be32
3507nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_confirm *oc)
3508{
3509        struct xdr_stream *xdr = &resp->xdr;
3510
3511        return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
3512}
3513
3514static __be32
3515nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_open_downgrade *od)
3516{
3517        struct xdr_stream *xdr = &resp->xdr;
3518
3519        return nfsd4_encode_stateid(xdr, &od->od_stateid);
3520}
3521
3522static __be32 nfsd4_encode_splice_read(
3523                                struct nfsd4_compoundres *resp,
3524                                struct nfsd4_read *read,
3525                                struct file *file, unsigned long maxcount)
3526{
3527        struct xdr_stream *xdr = &resp->xdr;
3528        struct xdr_buf *buf = xdr->buf;
3529        u32 eof;
3530        int space_left;
3531        __be32 nfserr;
3532        __be32 *p = xdr->p - 2;
3533
3534        /* Make sure there will be room for padding if needed */
3535        if (xdr->end - xdr->p < 1)
3536                return nfserr_resource;
3537
3538        nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
3539                                  file, read->rd_offset, &maxcount, &eof);
3540        read->rd_length = maxcount;
3541        if (nfserr) {
3542                /*
3543                 * nfsd_splice_actor may have already messed with the
3544                 * page length; reset it so as not to confuse
3545                 * xdr_truncate_encode:
3546                 */
3547                buf->page_len = 0;
3548                return nfserr;
3549        }
3550
3551        *(p++) = htonl(eof);
3552        *(p++) = htonl(maxcount);
3553
3554        buf->page_len = maxcount;
3555        buf->len += maxcount;
3556        xdr->page_ptr += (buf->page_base + maxcount + PAGE_SIZE - 1)
3557                                                        / PAGE_SIZE;
3558
3559        /* Use rest of head for padding and remaining ops: */
3560        buf->tail[0].iov_base = xdr->p;
3561        buf->tail[0].iov_len = 0;
3562        xdr->iov = buf->tail;
3563        if (maxcount&3) {
3564                int pad = 4 - (maxcount&3);
3565
3566                *(xdr->p++) = 0;
3567
3568                buf->tail[0].iov_base += maxcount&3;
3569                buf->tail[0].iov_len = pad;
3570                buf->len += pad;
3571        }
3572
3573        space_left = min_t(int, (void *)xdr->end - (void *)xdr->p,
3574                                buf->buflen - buf->len);
3575        buf->buflen = buf->len + space_left;
3576        xdr->end = (__be32 *)((void *)xdr->end + space_left);
3577
3578        return 0;
3579}
3580
3581static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
3582                                 struct nfsd4_read *read,
3583                                 struct file *file, unsigned long maxcount)
3584{
3585        struct xdr_stream *xdr = &resp->xdr;
3586        u32 eof;
3587        int v;
3588        int starting_len = xdr->buf->len - 8;
3589        long len;
3590        int thislen;
3591        __be32 nfserr;
3592        __be32 tmp;
3593        __be32 *p;
3594        int pad;
3595
3596        /*
3597         * svcrdma requires every READ payload to start somewhere
3598         * in xdr->pages.
3599         */
3600        if (xdr->iov == xdr->buf->head) {
3601                xdr->iov = NULL;
3602                xdr->end = xdr->p;
3603        }
3604
3605        len = maxcount;
3606        v = 0;
3607        while (len) {
3608                thislen = min_t(long, len, PAGE_SIZE);
3609                p = xdr_reserve_space(xdr, thislen);
3610                WARN_ON_ONCE(!p);
3611                resp->rqstp->rq_vec[v].iov_base = p;
3612                resp->rqstp->rq_vec[v].iov_len = thislen;
3613                v++;
3614                len -= thislen;
3615        }
3616        read->rd_vlen = v;
3617
3618        nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
3619                            resp->rqstp->rq_vec, read->rd_vlen, &maxcount,
3620                            &eof);
3621        read->rd_length = maxcount;
3622        if (nfserr)
3623                return nfserr;
3624        if (svc_encode_read_payload(resp->rqstp, starting_len + 8, maxcount))
3625                return nfserr_io;
3626        xdr_truncate_encode(xdr, starting_len + 8 + xdr_align_size(maxcount));
3627
3628        tmp = htonl(eof);
3629        write_bytes_to_xdr_buf(xdr->buf, starting_len    , &tmp, 4);
3630        tmp = htonl(maxcount);
3631        write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4);
3632
3633        tmp = xdr_zero;
3634        pad = (maxcount&3) ? 4 - (maxcount&3) : 0;
3635        write_bytes_to_xdr_buf(xdr->buf, starting_len + 8 + maxcount,
3636                                                                &tmp, pad);
3637        return 0;
3638
3639}
3640
3641static __be32
3642nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
3643                  struct nfsd4_read *read)
3644{
3645        unsigned long maxcount;
3646        struct xdr_stream *xdr = &resp->xdr;
3647        struct file *file;
3648        int starting_len = xdr->buf->len;
3649        __be32 *p;
3650
3651        if (nfserr)
3652                return nfserr;
3653        file = read->rd_nf->nf_file;
3654
3655        p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
3656        if (!p) {
3657                WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags));
3658                return nfserr_resource;
3659        }
3660        if (resp->xdr.buf->page_len &&
3661            test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) {
3662                WARN_ON_ONCE(1);
3663                return nfserr_resource;
3664        }
3665        xdr_commit_encode(xdr);
3666
3667        maxcount = svc_max_payload(resp->rqstp);
3668        maxcount = min_t(unsigned long, maxcount,
3669                         (xdr->buf->buflen - xdr->buf->len));
3670        maxcount = min_t(unsigned long, maxcount, read->rd_length);
3671
3672        if (file->f_op->splice_read &&
3673            test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
3674                nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
3675        else
3676                nfserr = nfsd4_encode_readv(resp, read, file, maxcount);
3677
3678        if (nfserr)
3679                xdr_truncate_encode(xdr, starting_len);
3680
3681        return nfserr;
3682}
3683
3684static __be32
3685nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readlink *readlink)
3686{
3687        int maxcount;
3688        __be32 wire_count;
3689        int zero = 0;
3690        struct xdr_stream *xdr = &resp->xdr;
3691        int length_offset = xdr->buf->len;
3692        __be32 *p;
3693
3694        p = xdr_reserve_space(xdr, 4);
3695        if (!p)
3696                return nfserr_resource;
3697        maxcount = PAGE_SIZE;
3698
3699        p = xdr_reserve_space(xdr, maxcount);
3700        if (!p)
3701                return nfserr_resource;
3702        /*
3703         * XXX: By default, vfs_readlink() will truncate symlinks if they
3704         * would overflow the buffer.  Is this kosher in NFSv4?  If not, one
3705         * easy fix is: if vfs_readlink() precisely fills the buffer, assume
3706         * that truncation occurred, and return NFS4ERR_RESOURCE.
3707         */
3708        nfserr = nfsd_readlink(readlink->rl_rqstp, readlink->rl_fhp,
3709                                                (char *)p, &maxcount);
3710        if (nfserr == nfserr_isdir)
3711                nfserr = nfserr_inval;
3712        if (nfserr) {
3713                xdr_truncate_encode(xdr, length_offset);
3714                return nfserr;
3715        }
3716
3717        wire_count = htonl(maxcount);
3718        write_bytes_to_xdr_buf(xdr->buf, length_offset, &wire_count, 4);
3719        xdr_truncate_encode(xdr, length_offset + 4 + ALIGN(maxcount, 4));
3720        if (maxcount & 3)
3721                write_bytes_to_xdr_buf(xdr->buf, length_offset + 4 + maxcount,
3722                                                &zero, 4 - (maxcount&3));
3723        return 0;
3724}
3725
3726static __be32
3727nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_readdir *readdir)
3728{
3729        int maxcount;
3730        int bytes_left;
3731        loff_t offset;
3732        __be64 wire_offset;
3733        struct xdr_stream *xdr = &resp->xdr;
3734        int starting_len = xdr->buf->len;
3735        __be32 *p;
3736
3737        p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
3738        if (!p)
3739                return nfserr_resource;
3740
3741        /* XXX: Following NFSv3, we ignore the READDIR verifier for now. */
3742        *p++ = cpu_to_be32(0);
3743        *p++ = cpu_to_be32(0);
3744        resp->xdr.buf->head[0].iov_len = ((char *)resp->xdr.p)
3745                                - (char *)resp->xdr.buf->head[0].iov_base;
3746
3747        /*
3748         * Number of bytes left for directory entries allowing for the
3749         * final 8 bytes of the readdir and a following failed op:
3750         */
3751        bytes_left = xdr->buf->buflen - xdr->buf->len
3752                        - COMPOUND_ERR_SLACK_SPACE - 8;
3753        if (bytes_left < 0) {
3754                nfserr = nfserr_resource;
3755                goto err_no_verf;
3756        }
3757        maxcount = svc_max_payload(resp->rqstp);
3758        maxcount = min_t(u32, readdir->rd_maxcount, maxcount);
3759        /*
3760         * Note the rfc defines rd_maxcount as the size of the
3761         * READDIR4resok structure, which includes the verifier above
3762         * and the 8 bytes encoded at the end of this function:
3763         */
3764        if (maxcount < 16) {
3765                nfserr = nfserr_toosmall;
3766                goto err_no_verf;
3767        }
3768        maxcount = min_t(int, maxcount-16, bytes_left);
3769
3770        /* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */
3771        if (!readdir->rd_dircount)
3772                readdir->rd_dircount = svc_max_payload(resp->rqstp);
3773
3774        readdir->xdr = xdr;
3775        readdir->rd_maxcount = maxcount;
3776        readdir->common.err = 0;
3777        readdir->cookie_offset = 0;
3778
3779        offset = readdir->rd_cookie;
3780        nfserr = nfsd_readdir(readdir->rd_rqstp, readdir->rd_fhp,
3781                              &offset,
3782                              &readdir->common, nfsd4_encode_dirent);
3783        if (nfserr == nfs_ok &&
3784            readdir->common.err == nfserr_toosmall &&
3785            xdr->buf->len == starting_len + 8) {
3786                /* nothing encoded; which limit did we hit?: */
3787                if (maxcount - 16 < bytes_left)
3788                        /* It was the fault of rd_maxcount: */
3789                        nfserr = nfserr_toosmall;
3790                else
3791                        /* We ran out of buffer space: */
3792                        nfserr = nfserr_resource;
3793        }
3794        if (nfserr)
3795                goto err_no_verf;
3796
3797        if (readdir->cookie_offset) {
3798                wire_offset = cpu_to_be64(offset);
3799                write_bytes_to_xdr_buf(xdr->buf, readdir->cookie_offset,
3800                                                        &wire_offset, 8);
3801        }
3802
3803        p = xdr_reserve_space(xdr, 8);
3804        if (!p) {
3805                WARN_ON_ONCE(1);
3806                goto err_no_verf;
3807        }
3808        *p++ = 0;       /* no more entries */
3809        *p++ = htonl(readdir->common.err == nfserr_eof);
3810
3811        return 0;
3812err_no_verf:
3813        xdr_truncate_encode(xdr, starting_len);
3814        return nfserr;
3815}
3816
3817static __be32
3818nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_remove *remove)
3819{
3820        struct xdr_stream *xdr = &resp->xdr;
3821        __be32 *p;
3822
3823        p = xdr_reserve_space(xdr, 20);
3824        if (!p)
3825                return nfserr_resource;
3826        p = encode_cinfo(p, &remove->rm_cinfo);
3827        return 0;
3828}
3829
3830static __be32
3831nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_rename *rename)
3832{
3833        struct xdr_stream *xdr = &resp->xdr;
3834        __be32 *p;
3835
3836        p = xdr_reserve_space(xdr, 40);
3837        if (!p)
3838                return nfserr_resource;
3839        p = encode_cinfo(p, &rename->rn_sinfo);
3840        p = encode_cinfo(p, &rename->rn_tinfo);
3841        return 0;
3842}
3843
3844static __be32
3845nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
3846{
3847        u32 i, nflavs, supported;
3848        struct exp_flavor_info *flavs;
3849        struct exp_flavor_info def_flavs[2];
3850        __be32 *p, *flavorsp;
3851        static bool report = true;
3852
3853        if (exp->ex_nflavors) {
3854                flavs = exp->ex_flavors;
3855                nflavs = exp->ex_nflavors;
3856        } else { /* Handling of some defaults in absence of real secinfo: */
3857                flavs = def_flavs;
3858                if (exp->ex_client->flavour->flavour == RPC_AUTH_UNIX) {
3859                        nflavs = 2;
3860                        flavs[0].pseudoflavor = RPC_AUTH_UNIX;
3861                        flavs[1].pseudoflavor = RPC_AUTH_NULL;
3862                } else if (exp->ex_client->flavour->flavour == RPC_AUTH_GSS) {
3863                        nflavs = 1;
3864                        flavs[0].pseudoflavor
3865                                        = svcauth_gss_flavor(exp->ex_client);
3866                } else {
3867                        nflavs = 1;
3868                        flavs[0].pseudoflavor
3869                                        = exp->ex_client->flavour->flavour;
3870                }
3871        }
3872
3873        supported = 0;
3874        p = xdr_reserve_space(xdr, 4);
3875        if (!p)
3876                return nfserr_resource;
3877        flavorsp = p++;         /* to be backfilled later */
3878
3879        for (i = 0; i < nflavs; i++) {
3880                rpc_authflavor_t pf = flavs[i].pseudoflavor;
3881                struct rpcsec_gss_info info;
3882
3883                if (rpcauth_get_gssinfo(pf, &info) == 0) {
3884                        supported++;
3885                        p = xdr_reserve_space(xdr, 4 + 4 +
3886                                              XDR_LEN(info.oid.len) + 4 + 4);
3887                        if (!p)
3888                                return nfserr_resource;
3889                        *p++ = cpu_to_be32(RPC_AUTH_GSS);
3890                        p = xdr_encode_opaque(p,  info.oid.data, info.oid.len);
3891                        *p++ = cpu_to_be32(info.qop);
3892                        *p++ = cpu_to_be32(info.service);
3893                } else if (pf < RPC_AUTH_MAXFLAVOR) {
3894                        supported++;
3895                        p = xdr_reserve_space(xdr, 4);
3896                        if (!p)
3897                                return nfserr_resource;
3898                        *p++ = cpu_to_be32(pf);
3899                } else {
3900                        if (report)
3901                                pr_warn("NFS: SECINFO: security flavor %u "
3902                                        "is not supported\n", pf);
3903                }
3904        }
3905
3906        if (nflavs != supported)
3907                report = false;
3908        *flavorsp = htonl(supported);
3909        return 0;
3910}
3911
3912static __be32
3913nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
3914                     struct nfsd4_secinfo *secinfo)
3915{
3916        struct xdr_stream *xdr = &resp->xdr;
3917
3918        return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp);
3919}
3920
3921static __be32
3922nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
3923                     struct nfsd4_secinfo_no_name *secinfo)
3924{
3925        struct xdr_stream *xdr = &resp->xdr;
3926
3927        return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp);
3928}
3929
3930/*
3931 * The SETATTR encode routine is special -- it always encodes a bitmap,
3932 * regardless of the error status.
3933 */
3934static __be32
3935nfsd4_encode_setattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setattr *setattr)
3936{
3937        struct xdr_stream *xdr = &resp->xdr;
3938        __be32 *p;
3939
3940        p = xdr_reserve_space(xdr, 16);
3941        if (!p)
3942                return nfserr_resource;
3943        if (nfserr) {
3944                *p++ = cpu_to_be32(3);
3945                *p++ = cpu_to_be32(0);
3946                *p++ = cpu_to_be32(0);
3947                *p++ = cpu_to_be32(0);
3948        }
3949        else {
3950                *p++ = cpu_to_be32(3);
3951                *p++ = cpu_to_be32(setattr->sa_bmval[0]);
3952                *p++ = cpu_to_be32(setattr->sa_bmval[1]);
3953                *p++ = cpu_to_be32(setattr->sa_bmval[2]);
3954        }
3955        return nfserr;
3956}
3957
3958static __be32
3959nfsd4_encode_setclientid(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_setclientid *scd)
3960{
3961        struct xdr_stream *xdr = &resp->xdr;
3962        __be32 *p;
3963
3964        if (!nfserr) {
3965                p = xdr_reserve_space(xdr, 8 + NFS4_VERIFIER_SIZE);
3966                if (!p)
3967                        return nfserr_resource;
3968                p = xdr_encode_opaque_fixed(p, &scd->se_clientid, 8);
3969                p = xdr_encode_opaque_fixed(p, &scd->se_confirm,
3970                                                NFS4_VERIFIER_SIZE);
3971        }
3972        else if (nfserr == nfserr_clid_inuse) {
3973                p = xdr_reserve_space(xdr, 8);
3974                if (!p)
3975                        return nfserr_resource;
3976                *p++ = cpu_to_be32(0);
3977                *p++ = cpu_to_be32(0);
3978        }
3979        return nfserr;
3980}
3981
3982static __be32
3983nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_write *write)
3984{
3985        struct xdr_stream *xdr = &resp->xdr;
3986        __be32 *p;
3987
3988        p = xdr_reserve_space(xdr, 16);
3989        if (!p)
3990                return nfserr_resource;
3991        *p++ = cpu_to_be32(write->wr_bytes_written);
3992        *p++ = cpu_to_be32(write->wr_how_written);
3993        p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
3994                                                NFS4_VERIFIER_SIZE);
3995        return 0;
3996}
3997
3998static __be32
3999nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
4000                         struct nfsd4_exchange_id *exid)
4001{
4002        struct xdr_stream *xdr = &resp->xdr;
4003        __be32 *p;
4004        char *major_id;
4005        char *server_scope;
4006        int major_id_sz;
4007        int server_scope_sz;
4008        uint64_t minor_id = 0;
4009        struct nfsd_net *nn = net_generic(SVC_NET(resp->rqstp), nfsd_net_id);
4010
4011        major_id = nn->nfsd_name;
4012        major_id_sz = strlen(nn->nfsd_name);
4013        server_scope = nn->nfsd_name;
4014        server_scope_sz = strlen(nn->nfsd_name);
4015
4016        p = xdr_reserve_space(xdr,
4017                8 /* eir_clientid */ +
4018                4 /* eir_sequenceid */ +
4019                4 /* eir_flags */ +
4020                4 /* spr_how */);
4021        if (!p)
4022                return nfserr_resource;
4023
4024        p = xdr_encode_opaque_fixed(p, &exid->clientid, 8);
4025        *p++ = cpu_to_be32(exid->seqid);
4026        *p++ = cpu_to_be32(exid->flags);
4027
4028        *p++ = cpu_to_be32(exid->spa_how);
4029
4030        switch (exid->spa_how) {
4031        case SP4_NONE:
4032                break;
4033        case SP4_MACH_CRED:
4034                /* spo_must_enforce bitmap: */
4035                nfserr = nfsd4_encode_bitmap(xdr,
4036                                        exid->spo_must_enforce[0],
4037                                        exid->spo_must_enforce[1],
4038                                        exid->spo_must_enforce[2]);
4039                if (nfserr)
4040                        return nfserr;
4041                /* spo_must_allow bitmap: */
4042                nfserr = nfsd4_encode_bitmap(xdr,
4043                                        exid->spo_must_allow[0],
4044                                        exid->spo_must_allow[1],
4045                                        exid->spo_must_allow[2]);
4046                if (nfserr)
4047                        return nfserr;
4048                break;
4049        default:
4050                WARN_ON_ONCE(1);
4051        }
4052
4053        p = xdr_reserve_space(xdr,
4054                8 /* so_minor_id */ +
4055                4 /* so_major_id.len */ +
4056                (XDR_QUADLEN(major_id_sz) * 4) +
4057                4 /* eir_server_scope.len */ +
4058                (XDR_QUADLEN(server_scope_sz) * 4) +
4059                4 /* eir_server_impl_id.count (0) */);
4060        if (!p)
4061                return nfserr_resource;
4062
4063        /* The server_owner struct */
4064        p = xdr_encode_hyper(p, minor_id);      /* Minor id */
4065        /* major id */
4066        p = xdr_encode_opaque(p, major_id, major_id_sz);
4067
4068        /* Server scope */
4069        p = xdr_encode_opaque(p, server_scope, server_scope_sz);
4070
4071        /* Implementation id */
4072        *p++ = cpu_to_be32(0);  /* zero length nfs_impl_id4 array */
4073        return 0;
4074}
4075
4076static __be32
4077nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
4078                            struct nfsd4_create_session *sess)
4079{
4080        struct xdr_stream *xdr = &resp->xdr;
4081        __be32 *p;
4082
4083        p = xdr_reserve_space(xdr, 24);
4084        if (!p)
4085                return nfserr_resource;
4086        p = xdr_encode_opaque_fixed(p, sess->sessionid.data,
4087                                        NFS4_MAX_SESSIONID_LEN);
4088        *p++ = cpu_to_be32(sess->seqid);
4089        *p++ = cpu_to_be32(sess->flags);
4090
4091        p = xdr_reserve_space(xdr, 28);
4092        if (!p)
4093                return nfserr_resource;
4094        *p++ = cpu_to_be32(0); /* headerpadsz */
4095        *p++ = cpu_to_be32(sess->fore_channel.maxreq_sz);
4096        *p++ = cpu_to_be32(sess->fore_channel.maxresp_sz);
4097        *p++ = cpu_to_be32(sess->fore_channel.maxresp_cached);
4098        *p++ = cpu_to_be32(sess->fore_channel.maxops);
4099        *p++ = cpu_to_be32(sess->fore_channel.maxreqs);
4100        *p++ = cpu_to_be32(sess->fore_channel.nr_rdma_attrs);
4101
4102        if (sess->fore_channel.nr_rdma_attrs) {
4103                p = xdr_reserve_space(xdr, 4);
4104                if (!p)
4105                        return nfserr_resource;
4106                *p++ = cpu_to_be32(sess->fore_channel.rdma_attrs);
4107        }
4108
4109        p = xdr_reserve_space(xdr, 28);
4110        if (!p)
4111                return nfserr_resource;
4112        *p++ = cpu_to_be32(0); /* headerpadsz */
4113        *p++ = cpu_to_be32(sess->back_channel.maxreq_sz);
4114        *p++ = cpu_to_be32(sess->back_channel.maxresp_sz);
4115        *p++ = cpu_to_be32(sess->back_channel.maxresp_cached);
4116        *p++ = cpu_to_be32(sess->back_channel.maxops);
4117        *p++ = cpu_to_be32(sess->back_channel.maxreqs);
4118        *p++ = cpu_to_be32(sess->back_channel.nr_rdma_attrs);
4119
4120        if (sess->back_channel.nr_rdma_attrs) {
4121                p = xdr_reserve_space(xdr, 4);
4122                if (!p)
4123                        return nfserr_resource;
4124                *p++ = cpu_to_be32(sess->back_channel.rdma_attrs);
4125        }
4126        return 0;
4127}
4128
4129static __be32
4130nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
4131                      struct nfsd4_sequence *seq)
4132{
4133        struct xdr_stream *xdr = &resp->xdr;
4134        __be32 *p;
4135
4136        p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
4137        if (!p)
4138                return nfserr_resource;
4139        p = xdr_encode_opaque_fixed(p, seq->sessionid.data,
4140                                        NFS4_MAX_SESSIONID_LEN);
4141        *p++ = cpu_to_be32(seq->seqid);
4142        *p++ = cpu_to_be32(seq->slotid);
4143        /* Note slotid's are numbered from zero: */
4144        *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_highest_slotid */
4145        *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_target_highest_slotid */
4146        *p++ = cpu_to_be32(seq->status_flags);
4147
4148        resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
4149        return 0;
4150}
4151
4152static __be32
4153nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
4154                          struct nfsd4_test_stateid *test_stateid)
4155{
4156        struct xdr_stream *xdr = &resp->xdr;
4157        struct nfsd4_test_stateid_id *stateid, *next;
4158        __be32 *p;
4159
4160        p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
4161        if (!p)
4162                return nfserr_resource;
4163        *p++ = htonl(test_stateid->ts_num_ids);
4164
4165        list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) {
4166                *p++ = stateid->ts_id_status;
4167        }
4168
4169        return 0;
4170}
4171
4172#ifdef CONFIG_NFSD_PNFS
4173static __be32
4174nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
4175                struct nfsd4_getdeviceinfo *gdev)
4176{
4177        struct xdr_stream *xdr = &resp->xdr;
4178        const struct nfsd4_layout_ops *ops;
4179        u32 starting_len = xdr->buf->len, needed_len;
4180        __be32 *p;
4181
4182        p = xdr_reserve_space(xdr, 4);
4183        if (!p)
4184                return nfserr_resource;
4185
4186        *p++ = cpu_to_be32(gdev->gd_layout_type);
4187
4188        /* If maxcount is 0 then just update notifications */
4189        if (gdev->gd_maxcount != 0) {
4190                ops = nfsd4_layout_ops[gdev->gd_layout_type];
4191                nfserr = ops->encode_getdeviceinfo(xdr, gdev);
4192                if (nfserr) {
4193                        /*
4194                         * We don't bother to burden the layout drivers with
4195                         * enforcing gd_maxcount, just tell the client to
4196                         * come back with a bigger buffer if it's not enough.
4197                         */
4198                        if (xdr->buf->len + 4 > gdev->gd_maxcount)
4199                                goto toosmall;
4200                        return nfserr;
4201                }
4202        }
4203
4204        if (gdev->gd_notify_types) {
4205                p = xdr_reserve_space(xdr, 4 + 4);
4206                if (!p)
4207                        return nfserr_resource;
4208                *p++ = cpu_to_be32(1);                  /* bitmap length */
4209                *p++ = cpu_to_be32(gdev->gd_notify_types);
4210        } else {
4211                p = xdr_reserve_space(xdr, 4);
4212                if (!p)
4213                        return nfserr_resource;
4214                *p++ = 0;
4215        }
4216
4217        return 0;
4218toosmall:
4219        dprintk("%s: maxcount too small\n", __func__);
4220        needed_len = xdr->buf->len + 4 /* notifications */;
4221        xdr_truncate_encode(xdr, starting_len);
4222        p = xdr_reserve_space(xdr, 4);
4223        if (!p)
4224                return nfserr_resource;
4225        *p++ = cpu_to_be32(needed_len);
4226        return nfserr_toosmall;
4227}
4228
4229static __be32
4230nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
4231                struct nfsd4_layoutget *lgp)
4232{
4233        struct xdr_stream *xdr = &resp->xdr;
4234        const struct nfsd4_layout_ops *ops;
4235        __be32 *p;
4236
4237        p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t));
4238        if (!p)
4239                return nfserr_resource;
4240
4241        *p++ = cpu_to_be32(1);  /* we always set return-on-close */
4242        *p++ = cpu_to_be32(lgp->lg_sid.si_generation);
4243        p = xdr_encode_opaque_fixed(p, &lgp->lg_sid.si_opaque,
4244                                    sizeof(stateid_opaque_t));
4245
4246        *p++ = cpu_to_be32(1);  /* we always return a single layout */
4247        p = xdr_encode_hyper(p, lgp->lg_seg.offset);
4248        p = xdr_encode_hyper(p, lgp->lg_seg.length);
4249        *p++ = cpu_to_be32(lgp->lg_seg.iomode);
4250        *p++ = cpu_to_be32(lgp->lg_layout_type);
4251
4252        ops = nfsd4_layout_ops[lgp->lg_layout_type];
4253        return ops->encode_layoutget(xdr, lgp);
4254}
4255
4256static __be32
4257nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr,
4258                          struct nfsd4_layoutcommit *lcp)
4259{
4260        struct xdr_stream *xdr = &resp->xdr;
4261        __be32 *p;
4262
4263        p = xdr_reserve_space(xdr, 4);
4264        if (!p)
4265                return nfserr_resource;
4266        *p++ = cpu_to_be32(lcp->lc_size_chg);
4267        if (lcp->lc_size_chg) {
4268                p = xdr_reserve_space(xdr, 8);
4269                if (!p)
4270                        return nfserr_resource;
4271                p = xdr_encode_hyper(p, lcp->lc_newsize);
4272        }
4273
4274        return 0;
4275}
4276
4277static __be32
4278nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
4279                struct nfsd4_layoutreturn *lrp)
4280{
4281        struct xdr_stream *xdr = &resp->xdr;
4282        __be32 *p;
4283
4284        p = xdr_reserve_space(xdr, 4);
4285        if (!p)
4286                return nfserr_resource;
4287        *p++ = cpu_to_be32(lrp->lrs_present);
4288        if (lrp->lrs_present)
4289                return nfsd4_encode_stateid(xdr, &lrp->lr_sid);
4290        return 0;
4291}
4292#endif /* CONFIG_NFSD_PNFS */
4293
4294static __be32
4295nfsd42_encode_write_res(struct nfsd4_compoundres *resp,
4296                struct nfsd42_write_res *write, bool sync)
4297{
4298        __be32 *p;
4299        p = xdr_reserve_space(&resp->xdr, 4);
4300        if (!p)
4301                return nfserr_resource;
4302
4303        if (sync)
4304                *p++ = cpu_to_be32(0);
4305        else {
4306                __be32 nfserr;
4307                *p++ = cpu_to_be32(1);
4308                nfserr = nfsd4_encode_stateid(&resp->xdr, &write->cb_stateid);
4309                if (nfserr)
4310                        return nfserr;
4311        }
4312        p = xdr_reserve_space(&resp->xdr, 8 + 4 + NFS4_VERIFIER_SIZE);
4313        if (!p)
4314                return nfserr_resource;
4315
4316        p = xdr_encode_hyper(p, write->wr_bytes_written);
4317        *p++ = cpu_to_be32(write->wr_stable_how);
4318        p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
4319                                    NFS4_VERIFIER_SIZE);
4320        return nfs_ok;
4321}
4322
4323static __be32
4324nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
4325{
4326        struct xdr_stream *xdr = &resp->xdr;
4327        struct nfs42_netaddr *addr;
4328        __be32 *p;
4329
4330        p = xdr_reserve_space(xdr, 4);
4331        *p++ = cpu_to_be32(ns->nl4_type);
4332
4333        switch (ns->nl4_type) {
4334        case NL4_NETADDR:
4335                addr = &ns->u.nl4_addr;
4336
4337                /* netid_len, netid, uaddr_len, uaddr (port included
4338                 * in RPCBIND_MAXUADDRLEN)
4339                 */
4340                p = xdr_reserve_space(xdr,
4341                        4 /* netid len */ +
4342                        (XDR_QUADLEN(addr->netid_len) * 4) +
4343                        4 /* uaddr len */ +
4344                        (XDR_QUADLEN(addr->addr_len) * 4));
4345                if (!p)
4346                        return nfserr_resource;
4347
4348                *p++ = cpu_to_be32(addr->netid_len);
4349                p = xdr_encode_opaque_fixed(p, addr->netid,
4350                                            addr->netid_len);
4351                *p++ = cpu_to_be32(addr->addr_len);
4352                p = xdr_encode_opaque_fixed(p, addr->addr,
4353                                        addr->addr_len);
4354                break;
4355        default:
4356                WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR);
4357                return nfserr_inval;
4358        }
4359
4360        return 0;
4361}
4362
4363static __be32
4364nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
4365                  struct nfsd4_copy *copy)
4366{
4367        __be32 *p;
4368
4369        nfserr = nfsd42_encode_write_res(resp, &copy->cp_res,
4370                        copy->cp_synchronous);
4371        if (nfserr)
4372                return nfserr;
4373
4374        p = xdr_reserve_space(&resp->xdr, 4 + 4);
4375        *p++ = xdr_one; /* cr_consecutive */
4376        *p++ = cpu_to_be32(copy->cp_synchronous);
4377        return 0;
4378}
4379
4380static __be32
4381nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
4382                            struct nfsd4_offload_status *os)
4383{
4384        struct xdr_stream *xdr = &resp->xdr;
4385        __be32 *p;
4386
4387        p = xdr_reserve_space(xdr, 8 + 4);
4388        if (!p)
4389                return nfserr_resource;
4390        p = xdr_encode_hyper(p, os->count);
4391        *p++ = cpu_to_be32(0);
4392
4393        return nfserr;
4394}
4395
4396static __be32
4397nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
4398                         struct nfsd4_copy_notify *cn)
4399{
4400        struct xdr_stream *xdr = &resp->xdr;
4401        __be32 *p;
4402
4403        if (nfserr)
4404                return nfserr;
4405
4406        /* 8 sec, 4 nsec */
4407        p = xdr_reserve_space(xdr, 12);
4408        if (!p)
4409                return nfserr_resource;
4410
4411        /* cnr_lease_time */
4412        p = xdr_encode_hyper(p, cn->cpn_sec);
4413        *p++ = cpu_to_be32(cn->cpn_nsec);
4414
4415        /* cnr_stateid */
4416        nfserr = nfsd4_encode_stateid(xdr, &cn->cpn_cnr_stateid);
4417        if (nfserr)
4418                return nfserr;
4419
4420        /* cnr_src.nl_nsvr */
4421        p = xdr_reserve_space(xdr, 4);
4422        if (!p)
4423                return nfserr_resource;
4424
4425        *p++ = cpu_to_be32(1);
4426
4427        return nfsd42_encode_nl4_server(resp, &cn->cpn_src);
4428}
4429
4430static __be32
4431nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
4432                  struct nfsd4_seek *seek)
4433{
4434        __be32 *p;
4435
4436        p = xdr_reserve_space(&resp->xdr, 4 + 8);
4437        *p++ = cpu_to_be32(seek->seek_eof);
4438        p = xdr_encode_hyper(p, seek->seek_pos);
4439
4440        return 0;
4441}
4442
4443static __be32
4444nfsd4_encode_noop(struct nfsd4_compoundres *resp, __be32 nfserr, void *p)
4445{
4446        return nfserr;
4447}
4448
4449typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
4450
4451/*
4452 * Note: nfsd4_enc_ops vector is shared for v4.0 and v4.1
4453 * since we don't need to filter out obsolete ops as this is
4454 * done in the decoding phase.
4455 */
4456static const nfsd4_enc nfsd4_enc_ops[] = {
4457        [OP_ACCESS]             = (nfsd4_enc)nfsd4_encode_access,
4458        [OP_CLOSE]              = (nfsd4_enc)nfsd4_encode_close,
4459        [OP_COMMIT]             = (nfsd4_enc)nfsd4_encode_commit,
4460        [OP_CREATE]             = (nfsd4_enc)nfsd4_encode_create,
4461        [OP_DELEGPURGE]         = (nfsd4_enc)nfsd4_encode_noop,
4462        [OP_DELEGRETURN]        = (nfsd4_enc)nfsd4_encode_noop,
4463        [OP_GETATTR]            = (nfsd4_enc)nfsd4_encode_getattr,
4464        [OP_GETFH]              = (nfsd4_enc)nfsd4_encode_getfh,
4465        [OP_LINK]               = (nfsd4_enc)nfsd4_encode_link,
4466        [OP_LOCK]               = (nfsd4_enc)nfsd4_encode_lock,
4467        [OP_LOCKT]              = (nfsd4_enc)nfsd4_encode_lockt,
4468        [OP_LOCKU]              = (nfsd4_enc)nfsd4_encode_locku,
4469        [OP_LOOKUP]             = (nfsd4_enc)nfsd4_encode_noop,
4470        [OP_LOOKUPP]            = (nfsd4_enc)nfsd4_encode_noop,
4471        [OP_NVERIFY]            = (nfsd4_enc)nfsd4_encode_noop,
4472        [OP_OPEN]               = (nfsd4_enc)nfsd4_encode_open,
4473        [OP_OPENATTR]           = (nfsd4_enc)nfsd4_encode_noop,
4474        [OP_OPEN_CONFIRM]       = (nfsd4_enc)nfsd4_encode_open_confirm,
4475        [OP_OPEN_DOWNGRADE]     = (nfsd4_enc)nfsd4_encode_open_downgrade,
4476        [OP_PUTFH]              = (nfsd4_enc)nfsd4_encode_noop,
4477        [OP_PUTPUBFH]           = (nfsd4_enc)nfsd4_encode_noop,
4478        [OP_PUTROOTFH]          = (nfsd4_enc)nfsd4_encode_noop,
4479        [OP_READ]               = (nfsd4_enc)nfsd4_encode_read,
4480        [OP_READDIR]            = (nfsd4_enc)nfsd4_encode_readdir,
4481        [OP_READLINK]           = (nfsd4_enc)nfsd4_encode_readlink,
4482        [OP_REMOVE]             = (nfsd4_enc)nfsd4_encode_remove,
4483        [OP_RENAME]             = (nfsd4_enc)nfsd4_encode_rename,
4484        [OP_RENEW]              = (nfsd4_enc)nfsd4_encode_noop,
4485        [OP_RESTOREFH]          = (nfsd4_enc)nfsd4_encode_noop,
4486        [OP_SAVEFH]             = (nfsd4_enc)nfsd4_encode_noop,
4487        [OP_SECINFO]            = (nfsd4_enc)nfsd4_encode_secinfo,
4488        [OP_SETATTR]            = (nfsd4_enc)nfsd4_encode_setattr,
4489        [OP_SETCLIENTID]        = (nfsd4_enc)nfsd4_encode_setclientid,
4490        [OP_SETCLIENTID_CONFIRM] = (nfsd4_enc)nfsd4_encode_noop,
4491        [OP_VERIFY]             = (nfsd4_enc)nfsd4_encode_noop,
4492        [OP_WRITE]              = (nfsd4_enc)nfsd4_encode_write,
4493        [OP_RELEASE_LOCKOWNER]  = (nfsd4_enc)nfsd4_encode_noop,
4494
4495        /* NFSv4.1 operations */
4496        [OP_BACKCHANNEL_CTL]    = (nfsd4_enc)nfsd4_encode_noop,
4497        [OP_BIND_CONN_TO_SESSION] = (nfsd4_enc)nfsd4_encode_bind_conn_to_session,
4498        [OP_EXCHANGE_ID]        = (nfsd4_enc)nfsd4_encode_exchange_id,
4499        [OP_CREATE_SESSION]     = (nfsd4_enc)nfsd4_encode_create_session,
4500        [OP_DESTROY_SESSION]    = (nfsd4_enc)nfsd4_encode_noop,
4501        [OP_FREE_STATEID]       = (nfsd4_enc)nfsd4_encode_noop,
4502        [OP_GET_DIR_DELEGATION] = (nfsd4_enc)nfsd4_encode_noop,
4503#ifdef CONFIG_NFSD_PNFS
4504        [OP_GETDEVICEINFO]      = (nfsd4_enc)nfsd4_encode_getdeviceinfo,
4505        [OP_GETDEVICELIST]      = (nfsd4_enc)nfsd4_encode_noop,
4506        [OP_LAYOUTCOMMIT]       = (nfsd4_enc)nfsd4_encode_layoutcommit,
4507        [OP_LAYOUTGET]          = (nfsd4_enc)nfsd4_encode_layoutget,
4508        [OP_LAYOUTRETURN]       = (nfsd4_enc)nfsd4_encode_layoutreturn,
4509#else
4510        [OP_GETDEVICEINFO]      = (nfsd4_enc)nfsd4_encode_noop,
4511        [OP_GETDEVICELIST]      = (nfsd4_enc)nfsd4_encode_noop,
4512        [OP_LAYOUTCOMMIT]       = (nfsd4_enc)nfsd4_encode_noop,
4513        [OP_LAYOUTGET]          = (nfsd4_enc)nfsd4_encode_noop,
4514        [OP_LAYOUTRETURN]       = (nfsd4_enc)nfsd4_encode_noop,
4515#endif
4516        [OP_SECINFO_NO_NAME]    = (nfsd4_enc)nfsd4_encode_secinfo_no_name,
4517        [OP_SEQUENCE]           = (nfsd4_enc)nfsd4_encode_sequence,
4518        [OP_SET_SSV]            = (nfsd4_enc)nfsd4_encode_noop,
4519        [OP_TEST_STATEID]       = (nfsd4_enc)nfsd4_encode_test_stateid,
4520        [OP_WANT_DELEGATION]    = (nfsd4_enc)nfsd4_encode_noop,
4521        [OP_DESTROY_CLIENTID]   = (nfsd4_enc)nfsd4_encode_noop,
4522        [OP_RECLAIM_COMPLETE]   = (nfsd4_enc)nfsd4_encode_noop,
4523
4524        /* NFSv4.2 operations */
4525        [OP_ALLOCATE]           = (nfsd4_enc)nfsd4_encode_noop,
4526        [OP_COPY]               = (nfsd4_enc)nfsd4_encode_copy,
4527        [OP_COPY_NOTIFY]        = (nfsd4_enc)nfsd4_encode_copy_notify,
4528        [OP_DEALLOCATE]         = (nfsd4_enc)nfsd4_encode_noop,
4529        [OP_IO_ADVISE]          = (nfsd4_enc)nfsd4_encode_noop,
4530        [OP_LAYOUTERROR]        = (nfsd4_enc)nfsd4_encode_noop,
4531        [OP_LAYOUTSTATS]        = (nfsd4_enc)nfsd4_encode_noop,
4532        [OP_OFFLOAD_CANCEL]     = (nfsd4_enc)nfsd4_encode_noop,
4533        [OP_OFFLOAD_STATUS]     = (nfsd4_enc)nfsd4_encode_offload_status,
4534        [OP_READ_PLUS]          = (nfsd4_enc)nfsd4_encode_noop,
4535        [OP_SEEK]               = (nfsd4_enc)nfsd4_encode_seek,
4536        [OP_WRITE_SAME]         = (nfsd4_enc)nfsd4_encode_noop,
4537        [OP_CLONE]              = (nfsd4_enc)nfsd4_encode_noop,
4538};
4539
4540/*
4541 * Calculate whether we still have space to encode repsize bytes.
4542 * There are two considerations:
4543 *     - For NFS versions >=4.1, the size of the reply must stay within
4544 *       session limits
4545 *     - For all NFS versions, we must stay within limited preallocated
4546 *       buffer space.
4547 *
4548 * This is called before the operation is processed, so can only provide
4549 * an upper estimate.  For some nonidempotent operations (such as
4550 * getattr), it's not necessarily a problem if that estimate is wrong,
4551 * as we can fail it after processing without significant side effects.
4552 */
4553__be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 respsize)
4554{
4555        struct xdr_buf *buf = &resp->rqstp->rq_res;
4556        struct nfsd4_slot *slot = resp->cstate.slot;
4557
4558        if (buf->len + respsize <= buf->buflen)
4559                return nfs_ok;
4560        if (!nfsd4_has_session(&resp->cstate))
4561                return nfserr_resource;
4562        if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) {
4563                WARN_ON_ONCE(1);
4564                return nfserr_rep_too_big_to_cache;
4565        }
4566        return nfserr_rep_too_big;
4567}
4568
4569void
4570nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
4571{
4572        struct xdr_stream *xdr = &resp->xdr;
4573        struct nfs4_stateowner *so = resp->cstate.replay_owner;
4574        struct svc_rqst *rqstp = resp->rqstp;
4575        const struct nfsd4_operation *opdesc = op->opdesc;
4576        int post_err_offset;
4577        nfsd4_enc encoder;
4578        __be32 *p;
4579
4580        p = xdr_reserve_space(xdr, 8);
4581        if (!p) {
4582                WARN_ON_ONCE(1);
4583                return;
4584        }
4585        *p++ = cpu_to_be32(op->opnum);
4586        post_err_offset = xdr->buf->len;
4587
4588        if (op->opnum == OP_ILLEGAL)
4589                goto status;
4590        if (op->status && opdesc &&
4591                        !(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
4592                goto status;
4593        BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
4594               !nfsd4_enc_ops[op->opnum]);
4595        encoder = nfsd4_enc_ops[op->opnum];
4596        op->status = encoder(resp, op->status, &op->u);
4597        if (opdesc && opdesc->op_release)
4598                opdesc->op_release(&op->u);
4599        xdr_commit_encode(xdr);
4600
4601        /* nfsd4_check_resp_size guarantees enough room for error status */
4602        if (!op->status) {
4603                int space_needed = 0;
4604                if (!nfsd4_last_compound_op(rqstp))
4605                        space_needed = COMPOUND_ERR_SLACK_SPACE;
4606                op->status = nfsd4_check_resp_size(resp, space_needed);
4607        }
4608        if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) {
4609                struct nfsd4_slot *slot = resp->cstate.slot;
4610
4611                if (slot->sl_flags & NFSD4_SLOT_CACHETHIS)
4612                        op->status = nfserr_rep_too_big_to_cache;
4613                else
4614                        op->status = nfserr_rep_too_big;
4615        }
4616        if (op->status == nfserr_resource ||
4617            op->status == nfserr_rep_too_big ||
4618            op->status == nfserr_rep_too_big_to_cache) {
4619                /*
4620                 * The operation may have already been encoded or
4621                 * partially encoded.  No op returns anything additional
4622                 * in the case of one of these three errors, so we can
4623                 * just truncate back to after the status.  But it's a
4624                 * bug if we had to do this on a non-idempotent op:
4625                 */
4626                warn_on_nonidempotent_op(op);
4627                xdr_truncate_encode(xdr, post_err_offset);
4628        }
4629        if (so) {
4630                int len = xdr->buf->len - post_err_offset;
4631
4632                so->so_replay.rp_status = op->status;
4633                so->so_replay.rp_buflen = len;
4634                read_bytes_from_xdr_buf(xdr->buf, post_err_offset,
4635                                                so->so_replay.rp_buf, len);
4636        }
4637status:
4638        /* Note that op->status is already in network byte order: */
4639        write_bytes_to_xdr_buf(xdr->buf, post_err_offset - 4, &op->status, 4);
4640}
4641
4642/* 
4643 * Encode the reply stored in the stateowner reply cache 
4644 * 
4645 * XDR note: do not encode rp->rp_buflen: the buffer contains the
4646 * previously sent already encoded operation.
4647 */
4648void
4649nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
4650{
4651        __be32 *p;
4652        struct nfs4_replay *rp = op->replay;
4653
4654        p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
4655        if (!p) {
4656                WARN_ON_ONCE(1);
4657                return;
4658        }
4659        *p++ = cpu_to_be32(op->opnum);
4660        *p++ = rp->rp_status;  /* already xdr'ed */
4661
4662        p = xdr_encode_opaque_fixed(p, rp->rp_buf, rp->rp_buflen);
4663}
4664
4665int
4666nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
4667{
4668        return xdr_ressize_check(rqstp, p);
4669}
4670
4671void nfsd4_release_compoundargs(struct svc_rqst *rqstp)
4672{
4673        struct nfsd4_compoundargs *args = rqstp->rq_argp;
4674
4675        if (args->ops != args->iops) {
4676                kfree(args->ops);
4677                args->ops = args->iops;
4678        }
4679        kfree(args->tmpp);
4680        args->tmpp = NULL;
4681        while (args->to_free) {
4682                struct svcxdr_tmpbuf *tb = args->to_free;
4683                args->to_free = tb->next;
4684                kfree(tb);
4685        }
4686}
4687
4688int
4689nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
4690{
4691        struct nfsd4_compoundargs *args = rqstp->rq_argp;
4692
4693        if (rqstp->rq_arg.head[0].iov_len % 4) {
4694                /* client is nuts */
4695                dprintk("%s: compound not properly padded! (peeraddr=%pISc xid=0x%x)",
4696                        __func__, svc_addr(rqstp), be32_to_cpu(rqstp->rq_xid));
4697                return 0;
4698        }
4699        args->p = p;
4700        args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
4701        args->pagelist = rqstp->rq_arg.pages;
4702        args->pagelen = rqstp->rq_arg.page_len;
4703        args->tail = false;
4704        args->tmpp = NULL;
4705        args->to_free = NULL;
4706        args->ops = args->iops;
4707        args->rqstp = rqstp;
4708
4709        return !nfsd4_decode_compound(args);
4710}
4711
4712int
4713nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p)
4714{
4715        /*
4716         * All that remains is to write the tag and operation count...
4717         */
4718        struct nfsd4_compoundres *resp = rqstp->rq_resp;
4719        struct xdr_buf *buf = resp->xdr.buf;
4720
4721        WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len +
4722                                 buf->tail[0].iov_len);
4723
4724        rqstp->rq_next_page = resp->xdr.page_ptr + 1;
4725
4726        p = resp->tagp;
4727        *p++ = htonl(resp->taglen);
4728        memcpy(p, resp->tag, resp->taglen);
4729        p += XDR_QUADLEN(resp->taglen);
4730        *p++ = htonl(resp->opcnt);
4731
4732        nfsd4_sequence_done(resp);
4733        return 1;
4734}
4735
4736/*
4737 * Local variables:
4738 *  c-basic-offset: 8
4739 * End:
4740 */
4741