linux/fs/nfsd/nfs4proc.c
<<
>>
Prefs
   1/*
   2 *  Server-side procedures 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#include <linux/file.h>
  36#include <linux/falloc.h>
  37#include <linux/slab.h>
  38
  39#include "idmap.h"
  40#include "cache.h"
  41#include "xdr4.h"
  42#include "vfs.h"
  43#include "current_stateid.h"
  44#include "netns.h"
  45#include "acl.h"
  46#include "pnfs.h"
  47#include "trace.h"
  48
  49#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
  50#include <linux/security.h>
  51
  52static inline void
  53nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
  54{
  55        struct inode *inode = d_inode(resfh->fh_dentry);
  56        int status;
  57
  58        mutex_lock(&inode->i_mutex);
  59        status = security_inode_setsecctx(resfh->fh_dentry,
  60                label->data, label->len);
  61        mutex_unlock(&inode->i_mutex);
  62
  63        if (status)
  64                /*
  65                 * XXX: We should really fail the whole open, but we may
  66                 * already have created a new file, so it may be too
  67                 * late.  For now this seems the least of evils:
  68                 */
  69                bmval[2] &= ~FATTR4_WORD2_SECURITY_LABEL;
  70
  71        return;
  72}
  73#else
  74static inline void
  75nfsd4_security_inode_setsecctx(struct svc_fh *resfh, struct xdr_netobj *label, u32 *bmval)
  76{ }
  77#endif
  78
  79#define NFSDDBG_FACILITY                NFSDDBG_PROC
  80
  81static u32 nfsd_attrmask[] = {
  82        NFSD_WRITEABLE_ATTRS_WORD0,
  83        NFSD_WRITEABLE_ATTRS_WORD1,
  84        NFSD_WRITEABLE_ATTRS_WORD2
  85};
  86
  87static u32 nfsd41_ex_attrmask[] = {
  88        NFSD_SUPPATTR_EXCLCREAT_WORD0,
  89        NFSD_SUPPATTR_EXCLCREAT_WORD1,
  90        NFSD_SUPPATTR_EXCLCREAT_WORD2
  91};
  92
  93static __be32
  94check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
  95                   u32 *bmval, u32 *writable)
  96{
  97        struct dentry *dentry = cstate->current_fh.fh_dentry;
  98
  99        /*
 100         * Check about attributes are supported by the NFSv4 server or not.
 101         * According to spec, unsupported attributes return ERR_ATTRNOTSUPP.
 102         */
 103        if ((bmval[0] & ~nfsd_suppattrs0(cstate->minorversion)) ||
 104            (bmval[1] & ~nfsd_suppattrs1(cstate->minorversion)) ||
 105            (bmval[2] & ~nfsd_suppattrs2(cstate->minorversion)))
 106                return nfserr_attrnotsupp;
 107
 108        /*
 109         * Check FATTR4_WORD0_ACL can be supported
 110         * in current environment or not.
 111         */
 112        if (bmval[0] & FATTR4_WORD0_ACL) {
 113                if (!IS_POSIXACL(d_inode(dentry)))
 114                        return nfserr_attrnotsupp;
 115        }
 116
 117        /*
 118         * According to spec, read-only attributes return ERR_INVAL.
 119         */
 120        if (writable) {
 121                if ((bmval[0] & ~writable[0]) || (bmval[1] & ~writable[1]) ||
 122                    (bmval[2] & ~writable[2]))
 123                        return nfserr_inval;
 124        }
 125
 126        return nfs_ok;
 127}
 128
 129static __be32
 130nfsd4_check_open_attributes(struct svc_rqst *rqstp,
 131        struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
 132{
 133        __be32 status = nfs_ok;
 134
 135        if (open->op_create == NFS4_OPEN_CREATE) {
 136                if (open->op_createmode == NFS4_CREATE_UNCHECKED
 137                    || open->op_createmode == NFS4_CREATE_GUARDED)
 138                        status = check_attr_support(rqstp, cstate,
 139                                        open->op_bmval, nfsd_attrmask);
 140                else if (open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1)
 141                        status = check_attr_support(rqstp, cstate,
 142                                        open->op_bmval, nfsd41_ex_attrmask);
 143        }
 144
 145        return status;
 146}
 147
 148static int
 149is_create_with_attrs(struct nfsd4_open *open)
 150{
 151        return open->op_create == NFS4_OPEN_CREATE
 152                && (open->op_createmode == NFS4_CREATE_UNCHECKED
 153                    || open->op_createmode == NFS4_CREATE_GUARDED
 154                    || open->op_createmode == NFS4_CREATE_EXCLUSIVE4_1);
 155}
 156
 157/*
 158 * if error occurs when setting the acl, just clear the acl bit
 159 * in the returned attr bitmap.
 160 */
 161static void
 162do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
 163                struct nfs4_acl *acl, u32 *bmval)
 164{
 165        __be32 status;
 166
 167        status = nfsd4_set_nfs4_acl(rqstp, fhp, acl);
 168        if (status)
 169                /*
 170                 * We should probably fail the whole open at this point,
 171                 * but we've already created the file, so it's too late;
 172                 * So this seems the least of evils:
 173                 */
 174                bmval[0] &= ~FATTR4_WORD0_ACL;
 175}
 176
 177static inline void
 178fh_dup2(struct svc_fh *dst, struct svc_fh *src)
 179{
 180        fh_put(dst);
 181        dget(src->fh_dentry);
 182        if (src->fh_export)
 183                exp_get(src->fh_export);
 184        *dst = *src;
 185}
 186
 187static __be32
 188do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open *open, int accmode)
 189{
 190        __be32 status;
 191
 192        if (open->op_truncate &&
 193                !(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
 194                return nfserr_inval;
 195
 196        accmode |= NFSD_MAY_READ_IF_EXEC;
 197
 198        if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
 199                accmode |= NFSD_MAY_READ;
 200        if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
 201                accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC);
 202        if (open->op_share_deny & NFS4_SHARE_DENY_READ)
 203                accmode |= NFSD_MAY_WRITE;
 204
 205        status = fh_verify(rqstp, current_fh, S_IFREG, accmode);
 206
 207        return status;
 208}
 209
 210static __be32 nfsd_check_obj_isreg(struct svc_fh *fh)
 211{
 212        umode_t mode = d_inode(fh->fh_dentry)->i_mode;
 213
 214        if (S_ISREG(mode))
 215                return nfs_ok;
 216        if (S_ISDIR(mode))
 217                return nfserr_isdir;
 218        /*
 219         * Using err_symlink as our catch-all case may look odd; but
 220         * there's no other obvious error for this case in 4.0, and we
 221         * happen to know that it will cause the linux v4 client to do
 222         * the right thing on attempts to open something other than a
 223         * regular file.
 224         */
 225        return nfserr_symlink;
 226}
 227
 228static void nfsd4_set_open_owner_reply_cache(struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh *resfh)
 229{
 230        if (nfsd4_has_session(cstate))
 231                return;
 232        fh_copy_shallow(&open->op_openowner->oo_owner.so_replay.rp_openfh,
 233                        &resfh->fh_handle);
 234}
 235
 236static __be32
 237do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open, struct svc_fh **resfh)
 238{
 239        struct svc_fh *current_fh = &cstate->current_fh;
 240        int accmode;
 241        __be32 status;
 242
 243        *resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
 244        if (!*resfh)
 245                return nfserr_jukebox;
 246        fh_init(*resfh, NFS4_FHSIZE);
 247        open->op_truncate = 0;
 248
 249        if (open->op_create) {
 250                /* FIXME: check session persistence and pnfs flags.
 251                 * The nfsv4.1 spec requires the following semantics:
 252                 *
 253                 * Persistent   | pNFS   | Server REQUIRED | Client Allowed
 254                 * Reply Cache  | server |                 |
 255                 * -------------+--------+-----------------+--------------------
 256                 * no           | no     | EXCLUSIVE4_1    | EXCLUSIVE4_1
 257                 *              |        |                 | (SHOULD)
 258                 *              |        | and EXCLUSIVE4  | or EXCLUSIVE4
 259                 *              |        |                 | (SHOULD NOT)
 260                 * no           | yes    | EXCLUSIVE4_1    | EXCLUSIVE4_1
 261                 * yes          | no     | GUARDED4        | GUARDED4
 262                 * yes          | yes    | GUARDED4        | GUARDED4
 263                 */
 264
 265                /*
 266                 * Note: create modes (UNCHECKED,GUARDED...) are the same
 267                 * in NFSv4 as in v3 except EXCLUSIVE4_1.
 268                 */
 269                status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
 270                                        open->op_fname.len, &open->op_iattr,
 271                                        *resfh, open->op_createmode,
 272                                        (u32 *)open->op_verf.data,
 273                                        &open->op_truncate, &open->op_created);
 274
 275                if (!status && open->op_label.len)
 276                        nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval);
 277
 278                /*
 279                 * Following rfc 3530 14.2.16, use the returned bitmask
 280                 * to indicate which attributes we used to store the
 281                 * verifier:
 282                 */
 283                if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0)
 284                        open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS |
 285                                                        FATTR4_WORD1_TIME_MODIFY);
 286        } else
 287                /*
 288                 * Note this may exit with the parent still locked.
 289                 * We will hold the lock until nfsd4_open's final
 290                 * lookup, to prevent renames or unlinks until we've had
 291                 * a chance to an acquire a delegation if appropriate.
 292                 */
 293                status = nfsd_lookup(rqstp, current_fh,
 294                                     open->op_fname.data, open->op_fname.len, *resfh);
 295        if (status)
 296                goto out;
 297        status = nfsd_check_obj_isreg(*resfh);
 298        if (status)
 299                goto out;
 300
 301        if (is_create_with_attrs(open) && open->op_acl != NULL)
 302                do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval);
 303
 304        nfsd4_set_open_owner_reply_cache(cstate, open, *resfh);
 305        accmode = NFSD_MAY_NOP;
 306        if (open->op_created ||
 307                        open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
 308                accmode |= NFSD_MAY_OWNER_OVERRIDE;
 309        status = do_open_permission(rqstp, *resfh, open, accmode);
 310        set_change_info(&open->op_cinfo, current_fh);
 311out:
 312        return status;
 313}
 314
 315static __be32
 316do_open_fhandle(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_open *open)
 317{
 318        struct svc_fh *current_fh = &cstate->current_fh;
 319        __be32 status;
 320        int accmode = 0;
 321
 322        /* We don't know the target directory, and therefore can not
 323        * set the change info
 324        */
 325
 326        memset(&open->op_cinfo, 0, sizeof(struct nfsd4_change_info));
 327
 328        nfsd4_set_open_owner_reply_cache(cstate, open, current_fh);
 329
 330        open->op_truncate = (open->op_iattr.ia_valid & ATTR_SIZE) &&
 331                (open->op_iattr.ia_size == 0);
 332        /*
 333         * In the delegation case, the client is telling us about an
 334         * open that it *already* performed locally, some time ago.  We
 335         * should let it succeed now if possible.
 336         *
 337         * In the case of a CLAIM_FH open, on the other hand, the client
 338         * may be counting on us to enforce permissions (the Linux 4.1
 339         * client uses this for normal opens, for example).
 340         */
 341        if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEG_CUR_FH)
 342                accmode = NFSD_MAY_OWNER_OVERRIDE;
 343
 344        status = do_open_permission(rqstp, current_fh, open, accmode);
 345
 346        return status;
 347}
 348
 349static void
 350copy_clientid(clientid_t *clid, struct nfsd4_session *session)
 351{
 352        struct nfsd4_sessionid *sid =
 353                        (struct nfsd4_sessionid *)session->se_sessionid.data;
 354
 355        clid->cl_boot = sid->clientid.cl_boot;
 356        clid->cl_id = sid->clientid.cl_id;
 357}
 358
 359static __be32
 360nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 361           struct nfsd4_open *open)
 362{
 363        __be32 status;
 364        struct svc_fh *resfh = NULL;
 365        struct nfsd4_compoundres *resp;
 366        struct net *net = SVC_NET(rqstp);
 367        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 368
 369        dprintk("NFSD: nfsd4_open filename %.*s op_openowner %p\n",
 370                (int)open->op_fname.len, open->op_fname.data,
 371                open->op_openowner);
 372
 373        /* This check required by spec. */
 374        if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
 375                return nfserr_inval;
 376
 377        open->op_created = 0;
 378        /*
 379         * RFC5661 18.51.3
 380         * Before RECLAIM_COMPLETE done, server should deny new lock
 381         */
 382        if (nfsd4_has_session(cstate) &&
 383            !test_bit(NFSD4_CLIENT_RECLAIM_COMPLETE,
 384                      &cstate->session->se_client->cl_flags) &&
 385            open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
 386                return nfserr_grace;
 387
 388        if (nfsd4_has_session(cstate))
 389                copy_clientid(&open->op_clientid, cstate->session);
 390
 391        /* check seqid for replay. set nfs4_owner */
 392        resp = rqstp->rq_resp;
 393        status = nfsd4_process_open1(&resp->cstate, open, nn);
 394        if (status == nfserr_replay_me) {
 395                struct nfs4_replay *rp = &open->op_openowner->oo_owner.so_replay;
 396                fh_put(&cstate->current_fh);
 397                fh_copy_shallow(&cstate->current_fh.fh_handle,
 398                                &rp->rp_openfh);
 399                status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
 400                if (status)
 401                        dprintk("nfsd4_open: replay failed"
 402                                " restoring previous filehandle\n");
 403                else
 404                        status = nfserr_replay_me;
 405        }
 406        if (status)
 407                goto out;
 408        if (open->op_xdr_error) {
 409                status = open->op_xdr_error;
 410                goto out;
 411        }
 412
 413        status = nfsd4_check_open_attributes(rqstp, cstate, open);
 414        if (status)
 415                goto out;
 416
 417        /* Openowner is now set, so sequence id will get bumped.  Now we need
 418         * these checks before we do any creates: */
 419        status = nfserr_grace;
 420        if (locks_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
 421                goto out;
 422        status = nfserr_no_grace;
 423        if (!locks_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
 424                goto out;
 425
 426        switch (open->op_claim_type) {
 427                case NFS4_OPEN_CLAIM_DELEGATE_CUR:
 428                case NFS4_OPEN_CLAIM_NULL:
 429                        status = do_open_lookup(rqstp, cstate, open, &resfh);
 430                        if (status)
 431                                goto out;
 432                        break;
 433                case NFS4_OPEN_CLAIM_PREVIOUS:
 434                        status = nfs4_check_open_reclaim(&open->op_clientid,
 435                                                         cstate, nn);
 436                        if (status)
 437                                goto out;
 438                        open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
 439                case NFS4_OPEN_CLAIM_FH:
 440                case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
 441                        status = do_open_fhandle(rqstp, cstate, open);
 442                        if (status)
 443                                goto out;
 444                        resfh = &cstate->current_fh;
 445                        break;
 446                case NFS4_OPEN_CLAIM_DELEG_PREV_FH:
 447                case NFS4_OPEN_CLAIM_DELEGATE_PREV:
 448                        dprintk("NFSD: unsupported OPEN claim type %d\n",
 449                                open->op_claim_type);
 450                        status = nfserr_notsupp;
 451                        goto out;
 452                default:
 453                        dprintk("NFSD: Invalid OPEN claim type %d\n",
 454                                open->op_claim_type);
 455                        status = nfserr_inval;
 456                        goto out;
 457        }
 458        /*
 459         * nfsd4_process_open2() does the actual opening of the file.  If
 460         * successful, it (1) truncates the file if open->op_truncate was
 461         * set, (2) sets open->op_stateid, (3) sets open->op_delegation.
 462         */
 463        status = nfsd4_process_open2(rqstp, resfh, open);
 464        WARN(status && open->op_created,
 465             "nfsd4_process_open2 failed to open newly-created file! status=%u\n",
 466             be32_to_cpu(status));
 467out:
 468        if (resfh && resfh != &cstate->current_fh) {
 469                fh_dup2(&cstate->current_fh, resfh);
 470                fh_put(resfh);
 471                kfree(resfh);
 472        }
 473        nfsd4_cleanup_open_state(cstate, open);
 474        nfsd4_bump_seqid(cstate, status);
 475        return status;
 476}
 477
 478/*
 479 * OPEN is the only seqid-mutating operation whose decoding can fail
 480 * with a seqid-mutating error (specifically, decoding of user names in
 481 * the attributes).  Therefore we have to do some processing to look up
 482 * the stateowner so that we can bump the seqid.
 483 */
 484static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_op *op)
 485{
 486        struct nfsd4_open *open = (struct nfsd4_open *)&op->u;
 487
 488        if (!seqid_mutating_err(ntohl(op->status)))
 489                return op->status;
 490        if (nfsd4_has_session(cstate))
 491                return op->status;
 492        open->op_xdr_error = op->status;
 493        return nfsd4_open(rqstp, cstate, open);
 494}
 495
 496/*
 497 * filehandle-manipulating ops.
 498 */
 499static __be32
 500nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 501            struct svc_fh **getfh)
 502{
 503        if (!cstate->current_fh.fh_dentry)
 504                return nfserr_nofilehandle;
 505
 506        *getfh = &cstate->current_fh;
 507        return nfs_ok;
 508}
 509
 510static __be32
 511nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 512            struct nfsd4_putfh *putfh)
 513{
 514        fh_put(&cstate->current_fh);
 515        cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen;
 516        memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval,
 517               putfh->pf_fhlen);
 518        return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS);
 519}
 520
 521static __be32
 522nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 523                void *arg)
 524{
 525        __be32 status;
 526
 527        fh_put(&cstate->current_fh);
 528        status = exp_pseudoroot(rqstp, &cstate->current_fh);
 529        return status;
 530}
 531
 532static __be32
 533nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 534                void *arg)
 535{
 536        if (!cstate->save_fh.fh_dentry)
 537                return nfserr_restorefh;
 538
 539        fh_dup2(&cstate->current_fh, &cstate->save_fh);
 540        if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) {
 541                memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t));
 542                SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
 543        }
 544        return nfs_ok;
 545}
 546
 547static __be32
 548nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 549             void *arg)
 550{
 551        if (!cstate->current_fh.fh_dentry)
 552                return nfserr_nofilehandle;
 553
 554        fh_dup2(&cstate->save_fh, &cstate->current_fh);
 555        if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) {
 556                memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t));
 557                SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG);
 558        }
 559        return nfs_ok;
 560}
 561
 562/*
 563 * misc nfsv4 ops
 564 */
 565static __be32
 566nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 567             struct nfsd4_access *access)
 568{
 569        if (access->ac_req_access & ~NFS3_ACCESS_FULL)
 570                return nfserr_inval;
 571
 572        access->ac_resp_access = access->ac_req_access;
 573        return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access,
 574                           &access->ac_supported);
 575}
 576
 577static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net)
 578{
 579        __be32 verf[2];
 580        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 581
 582        /*
 583         * This is opaque to client, so no need to byte-swap. Use
 584         * __force to keep sparse happy
 585         */
 586        verf[0] = (__force __be32)nn->nfssvc_boot.tv_sec;
 587        verf[1] = (__force __be32)nn->nfssvc_boot.tv_usec;
 588        memcpy(verifier->data, verf, sizeof(verifier->data));
 589}
 590
 591static __be32
 592nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 593             struct nfsd4_commit *commit)
 594{
 595        gen_boot_verifier(&commit->co_verf, SVC_NET(rqstp));
 596        return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
 597                             commit->co_count);
 598}
 599
 600static __be32
 601nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 602             struct nfsd4_create *create)
 603{
 604        struct svc_fh resfh;
 605        __be32 status;
 606        dev_t rdev;
 607
 608        fh_init(&resfh, NFS4_FHSIZE);
 609
 610        status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR,
 611                           NFSD_MAY_CREATE);
 612        if (status)
 613                return status;
 614
 615        status = check_attr_support(rqstp, cstate, create->cr_bmval,
 616                                    nfsd_attrmask);
 617        if (status)
 618                return status;
 619
 620        switch (create->cr_type) {
 621        case NF4LNK:
 622                status = nfsd_symlink(rqstp, &cstate->current_fh,
 623                                      create->cr_name, create->cr_namelen,
 624                                      create->cr_data, &resfh);
 625                break;
 626
 627        case NF4BLK:
 628                rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
 629                if (MAJOR(rdev) != create->cr_specdata1 ||
 630                    MINOR(rdev) != create->cr_specdata2)
 631                        return nfserr_inval;
 632                status = nfsd_create(rqstp, &cstate->current_fh,
 633                                     create->cr_name, create->cr_namelen,
 634                                     &create->cr_iattr, S_IFBLK, rdev, &resfh);
 635                break;
 636
 637        case NF4CHR:
 638                rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
 639                if (MAJOR(rdev) != create->cr_specdata1 ||
 640                    MINOR(rdev) != create->cr_specdata2)
 641                        return nfserr_inval;
 642                status = nfsd_create(rqstp, &cstate->current_fh,
 643                                     create->cr_name, create->cr_namelen,
 644                                     &create->cr_iattr,S_IFCHR, rdev, &resfh);
 645                break;
 646
 647        case NF4SOCK:
 648                status = nfsd_create(rqstp, &cstate->current_fh,
 649                                     create->cr_name, create->cr_namelen,
 650                                     &create->cr_iattr, S_IFSOCK, 0, &resfh);
 651                break;
 652
 653        case NF4FIFO:
 654                status = nfsd_create(rqstp, &cstate->current_fh,
 655                                     create->cr_name, create->cr_namelen,
 656                                     &create->cr_iattr, S_IFIFO, 0, &resfh);
 657                break;
 658
 659        case NF4DIR:
 660                create->cr_iattr.ia_valid &= ~ATTR_SIZE;
 661                status = nfsd_create(rqstp, &cstate->current_fh,
 662                                     create->cr_name, create->cr_namelen,
 663                                     &create->cr_iattr, S_IFDIR, 0, &resfh);
 664                break;
 665
 666        default:
 667                status = nfserr_badtype;
 668        }
 669
 670        if (status)
 671                goto out;
 672
 673        if (create->cr_label.len)
 674                nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval);
 675
 676        if (create->cr_acl != NULL)
 677                do_set_nfs4_acl(rqstp, &resfh, create->cr_acl,
 678                                create->cr_bmval);
 679
 680        fh_unlock(&cstate->current_fh);
 681        set_change_info(&create->cr_cinfo, &cstate->current_fh);
 682        fh_dup2(&cstate->current_fh, &resfh);
 683out:
 684        fh_put(&resfh);
 685        return status;
 686}
 687
 688static __be32
 689nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 690              struct nfsd4_getattr *getattr)
 691{
 692        __be32 status;
 693
 694        status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
 695        if (status)
 696                return status;
 697
 698        if (getattr->ga_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
 699                return nfserr_inval;
 700
 701        getattr->ga_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
 702        getattr->ga_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
 703        getattr->ga_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
 704
 705        getattr->ga_fhp = &cstate->current_fh;
 706        return nfs_ok;
 707}
 708
 709static __be32
 710nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 711           struct nfsd4_link *link)
 712{
 713        __be32 status = nfserr_nofilehandle;
 714
 715        if (!cstate->save_fh.fh_dentry)
 716                return status;
 717        status = nfsd_link(rqstp, &cstate->current_fh,
 718                           link->li_name, link->li_namelen, &cstate->save_fh);
 719        if (!status)
 720                set_change_info(&link->li_cinfo, &cstate->current_fh);
 721        return status;
 722}
 723
 724static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh)
 725{
 726        struct svc_fh tmp_fh;
 727        __be32 ret;
 728
 729        fh_init(&tmp_fh, NFS4_FHSIZE);
 730        ret = exp_pseudoroot(rqstp, &tmp_fh);
 731        if (ret)
 732                return ret;
 733        if (tmp_fh.fh_dentry == fh->fh_dentry) {
 734                fh_put(&tmp_fh);
 735                return nfserr_noent;
 736        }
 737        fh_put(&tmp_fh);
 738        return nfsd_lookup(rqstp, fh, "..", 2, fh);
 739}
 740
 741static __be32
 742nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 743              void *arg)
 744{
 745        return nfsd4_do_lookupp(rqstp, &cstate->current_fh);
 746}
 747
 748static __be32
 749nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 750             struct nfsd4_lookup *lookup)
 751{
 752        return nfsd_lookup(rqstp, &cstate->current_fh,
 753                           lookup->lo_name, lookup->lo_len,
 754                           &cstate->current_fh);
 755}
 756
 757static __be32
 758nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 759           struct nfsd4_read *read)
 760{
 761        __be32 status;
 762
 763        /* no need to check permission - this will be done in nfsd_read() */
 764
 765        read->rd_filp = NULL;
 766        if (read->rd_offset >= OFFSET_MAX)
 767                return nfserr_inval;
 768
 769        /*
 770         * If we do a zero copy read, then a client will see read data
 771         * that reflects the state of the file *after* performing the
 772         * following compound.
 773         *
 774         * To ensure proper ordering, we therefore turn off zero copy if
 775         * the client wants us to do more in this compound:
 776         */
 777        if (!nfsd4_last_compound_op(rqstp))
 778                clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags);
 779
 780        /* check stateid */
 781        if ((status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
 782                                                 cstate, &read->rd_stateid,
 783                                                 RD_STATE, &read->rd_filp))) {
 784                dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
 785                goto out;
 786        }
 787        status = nfs_ok;
 788out:
 789        read->rd_rqstp = rqstp;
 790        read->rd_fhp = &cstate->current_fh;
 791        return status;
 792}
 793
 794static __be32
 795nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 796              struct nfsd4_readdir *readdir)
 797{
 798        u64 cookie = readdir->rd_cookie;
 799        static const nfs4_verifier zeroverf;
 800
 801        /* no need to check permission - this will be done in nfsd_readdir() */
 802
 803        if (readdir->rd_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1)
 804                return nfserr_inval;
 805
 806        readdir->rd_bmval[0] &= nfsd_suppattrs0(cstate->minorversion);
 807        readdir->rd_bmval[1] &= nfsd_suppattrs1(cstate->minorversion);
 808        readdir->rd_bmval[2] &= nfsd_suppattrs2(cstate->minorversion);
 809
 810        if ((cookie == 1) || (cookie == 2) ||
 811            (cookie == 0 && memcmp(readdir->rd_verf.data, zeroverf.data, NFS4_VERIFIER_SIZE)))
 812                return nfserr_bad_cookie;
 813
 814        readdir->rd_rqstp = rqstp;
 815        readdir->rd_fhp = &cstate->current_fh;
 816        return nfs_ok;
 817}
 818
 819static __be32
 820nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 821               struct nfsd4_readlink *readlink)
 822{
 823        readlink->rl_rqstp = rqstp;
 824        readlink->rl_fhp = &cstate->current_fh;
 825        return nfs_ok;
 826}
 827
 828static __be32
 829nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 830             struct nfsd4_remove *remove)
 831{
 832        __be32 status;
 833
 834        if (locks_in_grace(SVC_NET(rqstp)))
 835                return nfserr_grace;
 836        status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
 837                             remove->rm_name, remove->rm_namelen);
 838        if (!status) {
 839                fh_unlock(&cstate->current_fh);
 840                set_change_info(&remove->rm_cinfo, &cstate->current_fh);
 841        }
 842        return status;
 843}
 844
 845static __be32
 846nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 847             struct nfsd4_rename *rename)
 848{
 849        __be32 status = nfserr_nofilehandle;
 850
 851        if (!cstate->save_fh.fh_dentry)
 852                return status;
 853        if (locks_in_grace(SVC_NET(rqstp)) &&
 854                !(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK))
 855                return nfserr_grace;
 856        status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,
 857                             rename->rn_snamelen, &cstate->current_fh,
 858                             rename->rn_tname, rename->rn_tnamelen);
 859        if (status)
 860                return status;
 861        set_change_info(&rename->rn_sinfo, &cstate->current_fh);
 862        set_change_info(&rename->rn_tinfo, &cstate->save_fh);
 863        return nfs_ok;
 864}
 865
 866static __be32
 867nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 868              struct nfsd4_secinfo *secinfo)
 869{
 870        struct svc_fh resfh;
 871        struct svc_export *exp;
 872        struct dentry *dentry;
 873        __be32 err;
 874
 875        fh_init(&resfh, NFS4_FHSIZE);
 876        err = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, NFSD_MAY_EXEC);
 877        if (err)
 878                return err;
 879        err = nfsd_lookup_dentry(rqstp, &cstate->current_fh,
 880                                    secinfo->si_name, secinfo->si_namelen,
 881                                    &exp, &dentry);
 882        if (err)
 883                return err;
 884        if (d_really_is_negative(dentry)) {
 885                exp_put(exp);
 886                err = nfserr_noent;
 887        } else
 888                secinfo->si_exp = exp;
 889        dput(dentry);
 890        if (cstate->minorversion)
 891                /* See rfc 5661 section 2.6.3.1.1.8 */
 892                fh_put(&cstate->current_fh);
 893        return err;
 894}
 895
 896static __be32
 897nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 898              struct nfsd4_secinfo_no_name *sin)
 899{
 900        __be32 err;
 901
 902        switch (sin->sin_style) {
 903        case NFS4_SECINFO_STYLE4_CURRENT_FH:
 904                break;
 905        case NFS4_SECINFO_STYLE4_PARENT:
 906                err = nfsd4_do_lookupp(rqstp, &cstate->current_fh);
 907                if (err)
 908                        return err;
 909                break;
 910        default:
 911                return nfserr_inval;
 912        }
 913
 914        sin->sin_exp = exp_get(cstate->current_fh.fh_export);
 915        fh_put(&cstate->current_fh);
 916        return nfs_ok;
 917}
 918
 919static __be32
 920nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 921              struct nfsd4_setattr *setattr)
 922{
 923        __be32 status = nfs_ok;
 924        int err;
 925
 926        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
 927                status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
 928                        &setattr->sa_stateid, WR_STATE, NULL);
 929                if (status) {
 930                        dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
 931                        return status;
 932                }
 933        }
 934        err = fh_want_write(&cstate->current_fh);
 935        if (err)
 936                return nfserrno(err);
 937        status = nfs_ok;
 938
 939        status = check_attr_support(rqstp, cstate, setattr->sa_bmval,
 940                                    nfsd_attrmask);
 941        if (status)
 942                goto out;
 943
 944        if (setattr->sa_acl != NULL)
 945                status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh,
 946                                            setattr->sa_acl);
 947        if (status)
 948                goto out;
 949        if (setattr->sa_label.len)
 950                status = nfsd4_set_nfs4_label(rqstp, &cstate->current_fh,
 951                                &setattr->sa_label);
 952        if (status)
 953                goto out;
 954        status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
 955                                0, (time_t)0);
 956out:
 957        fh_drop_write(&cstate->current_fh);
 958        return status;
 959}
 960
 961static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
 962{
 963        int i = 1;
 964        int buflen = write->wr_buflen;
 965
 966        vec[0].iov_base = write->wr_head.iov_base;
 967        vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len);
 968        buflen -= vec[0].iov_len;
 969
 970        while (buflen) {
 971                vec[i].iov_base = page_address(write->wr_pagelist[i - 1]);
 972                vec[i].iov_len = min_t(int, PAGE_SIZE, buflen);
 973                buflen -= vec[i].iov_len;
 974                i++;
 975        }
 976        return i;
 977}
 978
 979static __be32
 980nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 981            struct nfsd4_write *write)
 982{
 983        stateid_t *stateid = &write->wr_stateid;
 984        struct file *filp = NULL;
 985        __be32 status = nfs_ok;
 986        unsigned long cnt;
 987        int nvecs;
 988
 989        /* no need to check permission - this will be done in nfsd_write() */
 990
 991        if (write->wr_offset >= OFFSET_MAX)
 992                return nfserr_inval;
 993
 994        status = nfs4_preprocess_stateid_op(SVC_NET(rqstp),
 995                                        cstate, stateid, WR_STATE, &filp);
 996        if (status) {
 997                dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
 998                return status;
 999        }
1000
1001        cnt = write->wr_buflen;
1002        write->wr_how_written = write->wr_stable_how;
1003        gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));
1004
1005        nvecs = fill_in_write_vector(rqstp->rq_vec, write);
1006        WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
1007
1008        status =  nfsd_write(rqstp, &cstate->current_fh, filp,
1009                             write->wr_offset, rqstp->rq_vec, nvecs,
1010                             &cnt, &write->wr_how_written);
1011        if (filp)
1012                fput(filp);
1013
1014        write->wr_bytes_written = cnt;
1015
1016        return status;
1017}
1018
1019static __be32
1020nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1021                struct nfsd4_fallocate *fallocate, int flags)
1022{
1023        __be32 status = nfserr_notsupp;
1024        struct file *file;
1025
1026        status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
1027                                            &fallocate->falloc_stateid,
1028                                            WR_STATE, &file);
1029        if (status != nfs_ok) {
1030                dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
1031                return status;
1032        }
1033        if (!file)
1034                return nfserr_bad_stateid;
1035
1036        status = nfsd4_vfs_fallocate(rqstp, &cstate->current_fh, file,
1037                                     fallocate->falloc_offset,
1038                                     fallocate->falloc_length,
1039                                     flags);
1040        fput(file);
1041        return status;
1042}
1043
1044static __be32
1045nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1046               struct nfsd4_fallocate *fallocate)
1047{
1048        return nfsd4_fallocate(rqstp, cstate, fallocate, 0);
1049}
1050
1051static __be32
1052nfsd4_deallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1053                 struct nfsd4_fallocate *fallocate)
1054{
1055        return nfsd4_fallocate(rqstp, cstate, fallocate,
1056                               FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE);
1057}
1058
1059static __be32
1060nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1061                struct nfsd4_seek *seek)
1062{
1063        int whence;
1064        __be32 status;
1065        struct file *file;
1066
1067        status = nfs4_preprocess_stateid_op(SVC_NET(rqstp), cstate,
1068                                            &seek->seek_stateid,
1069                                            RD_STATE, &file);
1070        if (status) {
1071                dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
1072                return status;
1073        }
1074        if (!file)
1075                return nfserr_bad_stateid;
1076
1077        switch (seek->seek_whence) {
1078        case NFS4_CONTENT_DATA:
1079                whence = SEEK_DATA;
1080                break;
1081        case NFS4_CONTENT_HOLE:
1082                whence = SEEK_HOLE;
1083                break;
1084        default:
1085                status = nfserr_union_notsupp;
1086                goto out;
1087        }
1088
1089        /*
1090         * Note:  This call does change file->f_pos, but nothing in NFSD
1091         *        should ever file->f_pos.
1092         */
1093        seek->seek_pos = vfs_llseek(file, seek->seek_offset, whence);
1094        if (seek->seek_pos < 0)
1095                status = nfserrno(seek->seek_pos);
1096        else if (seek->seek_pos >= i_size_read(file_inode(file)))
1097                seek->seek_eof = true;
1098
1099out:
1100        fput(file);
1101        return status;
1102}
1103
1104/* This routine never returns NFS_OK!  If there are no other errors, it
1105 * will return NFSERR_SAME or NFSERR_NOT_SAME depending on whether the
1106 * attributes matched.  VERIFY is implemented by mapping NFSERR_SAME
1107 * to NFS_OK after the call; NVERIFY by mapping NFSERR_NOT_SAME to NFS_OK.
1108 */
1109static __be32
1110_nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1111             struct nfsd4_verify *verify)
1112{
1113        __be32 *buf, *p;
1114        int count;
1115        __be32 status;
1116
1117        status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP);
1118        if (status)
1119                return status;
1120
1121        status = check_attr_support(rqstp, cstate, verify->ve_bmval, NULL);
1122        if (status)
1123                return status;
1124
1125        if ((verify->ve_bmval[0] & FATTR4_WORD0_RDATTR_ERROR)
1126            || (verify->ve_bmval[1] & NFSD_WRITEONLY_ATTRS_WORD1))
1127                return nfserr_inval;
1128        if (verify->ve_attrlen & 3)
1129                return nfserr_inval;
1130
1131        /* count in words:
1132         *   bitmap_len(1) + bitmap(2) + attr_len(1) = 4
1133         */
1134        count = 4 + (verify->ve_attrlen >> 2);
1135        buf = kmalloc(count << 2, GFP_KERNEL);
1136        if (!buf)
1137                return nfserr_jukebox;
1138
1139        p = buf;
1140        status = nfsd4_encode_fattr_to_buf(&p, count, &cstate->current_fh,
1141                                    cstate->current_fh.fh_export,
1142                                    cstate->current_fh.fh_dentry,
1143                                    verify->ve_bmval,
1144                                    rqstp, 0);
1145        /*
1146         * If nfsd4_encode_fattr() ran out of space, assume that's because
1147         * the attributes are longer (hence different) than those given:
1148         */
1149        if (status == nfserr_resource)
1150                status = nfserr_not_same;
1151        if (status)
1152                goto out_kfree;
1153
1154        /* skip bitmap */
1155        p = buf + 1 + ntohl(buf[0]);
1156        status = nfserr_not_same;
1157        if (ntohl(*p++) != verify->ve_attrlen)
1158                goto out_kfree;
1159        if (!memcmp(p, verify->ve_attrval, verify->ve_attrlen))
1160                status = nfserr_same;
1161
1162out_kfree:
1163        kfree(buf);
1164        return status;
1165}
1166
1167static __be32
1168nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1169              struct nfsd4_verify *verify)
1170{
1171        __be32 status;
1172
1173        status = _nfsd4_verify(rqstp, cstate, verify);
1174        return status == nfserr_not_same ? nfs_ok : status;
1175}
1176
1177static __be32
1178nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
1179             struct nfsd4_verify *verify)
1180{
1181        __be32 status;
1182
1183        status = _nfsd4_verify(rqstp, cstate, verify);
1184        return status == nfserr_same ? nfs_ok : status;
1185}
1186
1187#ifdef CONFIG_NFSD_PNFS
1188static const struct nfsd4_layout_ops *
1189nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type)
1190{
1191        if (!exp->ex_layout_type) {
1192                dprintk("%s: export does not support pNFS\n", __func__);
1193                return NULL;
1194        }
1195
1196        if (exp->ex_layout_type != layout_type) {
1197                dprintk("%s: layout type %d not supported\n",
1198                        __func__, layout_type);
1199                return NULL;
1200        }
1201
1202        return nfsd4_layout_ops[layout_type];
1203}
1204
1205static __be32
1206nfsd4_getdeviceinfo(struct svc_rqst *rqstp,
1207                struct nfsd4_compound_state *cstate,
1208                struct nfsd4_getdeviceinfo *gdp)
1209{
1210        const struct nfsd4_layout_ops *ops;
1211        struct nfsd4_deviceid_map *map;
1212        struct svc_export *exp;
1213        __be32 nfserr;
1214
1215        dprintk("%s: layout_type %u dev_id [0x%llx:0x%x] maxcnt %u\n",
1216               __func__,
1217               gdp->gd_layout_type,
1218               gdp->gd_devid.fsid_idx, gdp->gd_devid.generation,
1219               gdp->gd_maxcount);
1220
1221        map = nfsd4_find_devid_map(gdp->gd_devid.fsid_idx);
1222        if (!map) {
1223                dprintk("%s: couldn't find device ID to export mapping!\n",
1224                        __func__);
1225                return nfserr_noent;
1226        }
1227
1228        exp = rqst_exp_find(rqstp, map->fsid_type, map->fsid);
1229        if (IS_ERR(exp)) {
1230                dprintk("%s: could not find device id\n", __func__);
1231                return nfserr_noent;
1232        }
1233
1234        nfserr = nfserr_layoutunavailable;
1235        ops = nfsd4_layout_verify(exp, gdp->gd_layout_type);
1236        if (!ops)
1237                goto out;
1238
1239        nfserr = nfs_ok;
1240        if (gdp->gd_maxcount != 0)
1241                nfserr = ops->proc_getdeviceinfo(exp->ex_path.mnt->mnt_sb, gdp);
1242
1243        gdp->gd_notify_types &= ops->notify_types;
1244out:
1245        exp_put(exp);
1246        return nfserr;
1247}
1248
1249static __be32
1250nfsd4_layoutget(struct svc_rqst *rqstp,
1251                struct nfsd4_compound_state *cstate,
1252                struct nfsd4_layoutget *lgp)
1253{
1254        struct svc_fh *current_fh = &cstate->current_fh;
1255        const struct nfsd4_layout_ops *ops;
1256        struct nfs4_layout_stateid *ls;
1257        __be32 nfserr;
1258        int accmode;
1259
1260        switch (lgp->lg_seg.iomode) {
1261        case IOMODE_READ:
1262                accmode = NFSD_MAY_READ;
1263                break;
1264        case IOMODE_RW:
1265                accmode = NFSD_MAY_READ | NFSD_MAY_WRITE;
1266                break;
1267        default:
1268                dprintk("%s: invalid iomode %d\n",
1269                        __func__, lgp->lg_seg.iomode);
1270                nfserr = nfserr_badiomode;
1271                goto out;
1272        }
1273
1274        nfserr = fh_verify(rqstp, current_fh, 0, accmode);
1275        if (nfserr)
1276                goto out;
1277
1278        nfserr = nfserr_layoutunavailable;
1279        ops = nfsd4_layout_verify(current_fh->fh_export, lgp->lg_layout_type);
1280        if (!ops)
1281                goto out;
1282
1283        /*
1284         * Verify minlength and range as per RFC5661:
1285         *  o  If loga_length is less than loga_minlength,
1286         *     the metadata server MUST return NFS4ERR_INVAL.
1287         *  o  If the sum of loga_offset and loga_minlength exceeds
1288         *     NFS4_UINT64_MAX, and loga_minlength is not
1289         *     NFS4_UINT64_MAX, the error NFS4ERR_INVAL MUST result.
1290         *  o  If the sum of loga_offset and loga_length exceeds
1291         *     NFS4_UINT64_MAX, and loga_length is not NFS4_UINT64_MAX,
1292         *     the error NFS4ERR_INVAL MUST result.
1293         */
1294        nfserr = nfserr_inval;
1295        if (lgp->lg_seg.length < lgp->lg_minlength ||
1296            (lgp->lg_minlength != NFS4_MAX_UINT64 &&
1297             lgp->lg_minlength > NFS4_MAX_UINT64 - lgp->lg_seg.offset) ||
1298            (lgp->lg_seg.length != NFS4_MAX_UINT64 &&
1299             lgp->lg_seg.length > NFS4_MAX_UINT64 - lgp->lg_seg.offset))
1300                goto out;
1301        if (lgp->lg_seg.length == 0)
1302                goto out;
1303
1304        nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid,
1305                                                true, lgp->lg_layout_type, &ls);
1306        if (nfserr) {
1307                trace_layout_get_lookup_fail(&lgp->lg_sid);
1308                goto out;
1309        }
1310
1311        nfserr = nfserr_recallconflict;
1312        if (atomic_read(&ls->ls_stid.sc_file->fi_lo_recalls))
1313                goto out_put_stid;
1314
1315        nfserr = ops->proc_layoutget(d_inode(current_fh->fh_dentry),
1316                                     current_fh, lgp);
1317        if (nfserr)
1318                goto out_put_stid;
1319
1320        nfserr = nfsd4_insert_layout(lgp, ls);
1321
1322out_put_stid:
1323        nfs4_put_stid(&ls->ls_stid);
1324out:
1325        return nfserr;
1326}
1327
1328static __be32
1329nfsd4_layoutcommit(struct svc_rqst *rqstp,
1330                struct nfsd4_compound_state *cstate,
1331                struct nfsd4_layoutcommit *lcp)
1332{
1333        const struct nfsd4_layout_seg *seg = &lcp->lc_seg;
1334        struct svc_fh *current_fh = &cstate->current_fh;
1335        const struct nfsd4_layout_ops *ops;
1336        loff_t new_size = lcp->lc_last_wr + 1;
1337        struct inode *inode;
1338        struct nfs4_layout_stateid *ls;
1339        __be32 nfserr;
1340
1341        nfserr = fh_verify(rqstp, current_fh, 0, NFSD_MAY_WRITE);
1342        if (nfserr)
1343                goto out;
1344
1345        nfserr = nfserr_layoutunavailable;
1346        ops = nfsd4_layout_verify(current_fh->fh_export, lcp->lc_layout_type);
1347        if (!ops)
1348                goto out;
1349        inode = d_inode(current_fh->fh_dentry);
1350
1351        nfserr = nfserr_inval;
1352        if (new_size <= seg->offset) {
1353                dprintk("pnfsd: last write before layout segment\n");
1354                goto out;
1355        }
1356        if (new_size > seg->offset + seg->length) {
1357                dprintk("pnfsd: last write beyond layout segment\n");
1358                goto out;
1359        }
1360        if (!lcp->lc_newoffset && new_size > i_size_read(inode)) {
1361                dprintk("pnfsd: layoutcommit beyond EOF\n");
1362                goto out;
1363        }
1364
1365        nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lcp->lc_sid,
1366                                                false, lcp->lc_layout_type,
1367                                                &ls);
1368        if (nfserr) {
1369                trace_layout_commit_lookup_fail(&lcp->lc_sid);
1370                /* fixup error code as per RFC5661 */
1371                if (nfserr == nfserr_bad_stateid)
1372                        nfserr = nfserr_badlayout;
1373                goto out;
1374        }
1375
1376        nfserr = ops->proc_layoutcommit(inode, lcp);
1377        if (nfserr)
1378                goto out_put_stid;
1379
1380        if (new_size > i_size_read(inode)) {
1381                lcp->lc_size_chg = 1;
1382                lcp->lc_newsize = new_size;
1383        } else {
1384                lcp->lc_size_chg = 0;
1385        }
1386
1387out_put_stid:
1388        nfs4_put_stid(&ls->ls_stid);
1389out:
1390        return nfserr;
1391}
1392
1393static __be32
1394nfsd4_layoutreturn(struct svc_rqst *rqstp,
1395                struct nfsd4_compound_state *cstate,
1396                struct nfsd4_layoutreturn *lrp)
1397{
1398        struct svc_fh *current_fh = &cstate->current_fh;
1399        __be32 nfserr;
1400
1401        nfserr = fh_verify(rqstp, current_fh, 0, NFSD_MAY_NOP);
1402        if (nfserr)
1403                goto out;
1404
1405        nfserr = nfserr_layoutunavailable;
1406        if (!nfsd4_layout_verify(current_fh->fh_export, lrp->lr_layout_type))
1407                goto out;
1408
1409        switch (lrp->lr_seg.iomode) {
1410        case IOMODE_READ:
1411        case IOMODE_RW:
1412        case IOMODE_ANY:
1413                break;
1414        default:
1415                dprintk("%s: invalid iomode %d\n", __func__,
1416                        lrp->lr_seg.iomode);
1417                nfserr = nfserr_inval;
1418                goto out;
1419        }
1420
1421        switch (lrp->lr_return_type) {
1422        case RETURN_FILE:
1423                nfserr = nfsd4_return_file_layouts(rqstp, cstate, lrp);
1424                break;
1425        case RETURN_FSID:
1426        case RETURN_ALL:
1427                nfserr = nfsd4_return_client_layouts(rqstp, cstate, lrp);
1428                break;
1429        default:
1430                dprintk("%s: invalid return_type %d\n", __func__,
1431                        lrp->lr_return_type);
1432                nfserr = nfserr_inval;
1433                break;
1434        }
1435out:
1436        return nfserr;
1437}
1438#endif /* CONFIG_NFSD_PNFS */
1439
1440/*
1441 * NULL call.
1442 */
1443static __be32
1444nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
1445{
1446        return nfs_ok;
1447}
1448
1449static inline void nfsd4_increment_op_stats(u32 opnum)
1450{
1451        if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP)
1452                nfsdstats.nfs4_opcount[opnum]++;
1453}
1454
1455typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
1456                              void *);
1457typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op);
1458typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *);
1459typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *);
1460
1461enum nfsd4_op_flags {
1462        ALLOWED_WITHOUT_FH = 1 << 0,    /* No current filehandle required */
1463        ALLOWED_ON_ABSENT_FS = 1 << 1,  /* ops processed on absent fs */
1464        ALLOWED_AS_FIRST_OP = 1 << 2,   /* ops reqired first in compound */
1465        /* For rfc 5661 section 2.6.3.1.1: */
1466        OP_HANDLES_WRONGSEC = 1 << 3,
1467        OP_IS_PUTFH_LIKE = 1 << 4,
1468        /*
1469         * These are the ops whose result size we estimate before
1470         * encoding, to avoid performing an op then not being able to
1471         * respond or cache a response.  This includes writes and setattrs
1472         * as well as the operations usually called "nonidempotent":
1473         */
1474        OP_MODIFIES_SOMETHING = 1 << 5,
1475        /*
1476         * Cache compounds containing these ops in the xid-based drc:
1477         * We use the DRC for compounds containing non-idempotent
1478         * operations, *except* those that are 4.1-specific (since
1479         * sessions provide their own EOS), and except for stateful
1480         * operations other than setclientid and setclientid_confirm
1481         * (since sequence numbers provide EOS for open, lock, etc in
1482         * the v4.0 case).
1483         */
1484        OP_CACHEME = 1 << 6,
1485        /*
1486         * These are ops which clear current state id.
1487         */
1488        OP_CLEAR_STATEID = 1 << 7,
1489};
1490
1491struct nfsd4_operation {
1492        nfsd4op_func op_func;
1493        u32 op_flags;
1494        char *op_name;
1495        /* Try to get response size before operation */
1496        nfsd4op_rsize op_rsize_bop;
1497        stateid_getter op_get_currentstateid;
1498        stateid_setter op_set_currentstateid;
1499};
1500
1501static struct nfsd4_operation nfsd4_ops[];
1502
1503static const char *nfsd4_op_name(unsigned opnum);
1504
1505/*
1506 * Enforce NFSv4.1 COMPOUND ordering rules:
1507 *
1508 * Also note, enforced elsewhere:
1509 *      - SEQUENCE other than as first op results in
1510 *        NFS4ERR_SEQUENCE_POS. (Enforced in nfsd4_sequence().)
1511 *      - BIND_CONN_TO_SESSION must be the only op in its compound.
1512 *        (Enforced in nfsd4_bind_conn_to_session().)
1513 *      - DESTROY_SESSION must be the final operation in a compound, if
1514 *        sessionid's in SEQUENCE and DESTROY_SESSION are the same.
1515 *        (Enforced in nfsd4_destroy_session().)
1516 */
1517static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
1518{
1519        struct nfsd4_op *op = &args->ops[0];
1520
1521        /* These ordering requirements don't apply to NFSv4.0: */
1522        if (args->minorversion == 0)
1523                return nfs_ok;
1524        /* This is weird, but OK, not our problem: */
1525        if (args->opcnt == 0)
1526                return nfs_ok;
1527        if (op->status == nfserr_op_illegal)
1528                return nfs_ok;
1529        if (!(nfsd4_ops[op->opnum].op_flags & ALLOWED_AS_FIRST_OP))
1530                return nfserr_op_not_in_session;
1531        if (op->opnum == OP_SEQUENCE)
1532                return nfs_ok;
1533        if (args->opcnt != 1)
1534                return nfserr_not_only_op;
1535        return nfs_ok;
1536}
1537
1538static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
1539{
1540        return &nfsd4_ops[op->opnum];
1541}
1542
1543bool nfsd4_cache_this_op(struct nfsd4_op *op)
1544{
1545        if (op->opnum == OP_ILLEGAL)
1546                return false;
1547        return OPDESC(op)->op_flags & OP_CACHEME;
1548}
1549
1550static bool need_wrongsec_check(struct svc_rqst *rqstp)
1551{
1552        struct nfsd4_compoundres *resp = rqstp->rq_resp;
1553        struct nfsd4_compoundargs *argp = rqstp->rq_argp;
1554        struct nfsd4_op *this = &argp->ops[resp->opcnt - 1];
1555        struct nfsd4_op *next = &argp->ops[resp->opcnt];
1556        struct nfsd4_operation *thisd;
1557        struct nfsd4_operation *nextd;
1558
1559        thisd = OPDESC(this);
1560        /*
1561         * Most ops check wronsec on our own; only the putfh-like ops
1562         * have special rules.
1563         */
1564        if (!(thisd->op_flags & OP_IS_PUTFH_LIKE))
1565                return false;
1566        /*
1567         * rfc 5661 2.6.3.1.1.6: don't bother erroring out a
1568         * put-filehandle operation if we're not going to use the
1569         * result:
1570         */
1571        if (argp->opcnt == resp->opcnt)
1572                return false;
1573        if (next->opnum == OP_ILLEGAL)
1574                return false;
1575        nextd = OPDESC(next);
1576        /*
1577         * Rest of 2.6.3.1.1: certain operations will return WRONGSEC
1578         * errors themselves as necessary; others should check for them
1579         * now:
1580         */
1581        return !(nextd->op_flags & OP_HANDLES_WRONGSEC);
1582}
1583
1584static void svcxdr_init_encode(struct svc_rqst *rqstp,
1585                               struct nfsd4_compoundres *resp)
1586{
1587        struct xdr_stream *xdr = &resp->xdr;
1588        struct xdr_buf *buf = &rqstp->rq_res;
1589        struct kvec *head = buf->head;
1590
1591        xdr->buf = buf;
1592        xdr->iov = head;
1593        xdr->p   = head->iov_base + head->iov_len;
1594        xdr->end = head->iov_base + PAGE_SIZE - rqstp->rq_auth_slack;
1595        /* Tail and page_len should be zero at this point: */
1596        buf->len = buf->head[0].iov_len;
1597        xdr->scratch.iov_len = 0;
1598        xdr->page_ptr = buf->pages - 1;
1599        buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages)
1600                - rqstp->rq_auth_slack;
1601}
1602
1603/*
1604 * COMPOUND call.
1605 */
1606static __be32
1607nfsd4_proc_compound(struct svc_rqst *rqstp,
1608                    struct nfsd4_compoundargs *args,
1609                    struct nfsd4_compoundres *resp)
1610{
1611        struct nfsd4_op *op;
1612        struct nfsd4_operation *opdesc;
1613        struct nfsd4_compound_state *cstate = &resp->cstate;
1614        struct svc_fh *current_fh = &cstate->current_fh;
1615        struct svc_fh *save_fh = &cstate->save_fh;
1616        __be32          status;
1617
1618        svcxdr_init_encode(rqstp, resp);
1619        resp->tagp = resp->xdr.p;
1620        /* reserve space for: taglen, tag, and opcnt */
1621        xdr_reserve_space(&resp->xdr, 8 + args->taglen);
1622        resp->taglen = args->taglen;
1623        resp->tag = args->tag;
1624        resp->rqstp = rqstp;
1625        cstate->minorversion = args->minorversion;
1626        fh_init(current_fh, NFS4_FHSIZE);
1627        fh_init(save_fh, NFS4_FHSIZE);
1628        /*
1629         * Don't use the deferral mechanism for NFSv4; compounds make it
1630         * too hard to avoid non-idempotency problems.
1631         */
1632        clear_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
1633
1634        /*
1635         * According to RFC3010, this takes precedence over all other errors.
1636         */
1637        status = nfserr_minor_vers_mismatch;
1638        if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
1639                goto out;
1640
1641        status = nfs41_check_op_ordering(args);
1642        if (status) {
1643                op = &args->ops[0];
1644                op->status = status;
1645                goto encode_op;
1646        }
1647
1648        while (!status && resp->opcnt < args->opcnt) {
1649                op = &args->ops[resp->opcnt++];
1650
1651                dprintk("nfsv4 compound op #%d/%d: %d (%s)\n",
1652                        resp->opcnt, args->opcnt, op->opnum,
1653                        nfsd4_op_name(op->opnum));
1654                /*
1655                 * The XDR decode routines may have pre-set op->status;
1656                 * for example, if there is a miscellaneous XDR error
1657                 * it will be set to nfserr_bad_xdr.
1658                 */
1659                if (op->status) {
1660                        if (op->opnum == OP_OPEN)
1661                                op->status = nfsd4_open_omfg(rqstp, cstate, op);
1662                        goto encode_op;
1663                }
1664
1665                opdesc = OPDESC(op);
1666
1667                if (!current_fh->fh_dentry) {
1668                        if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
1669                                op->status = nfserr_nofilehandle;
1670                                goto encode_op;
1671                        }
1672                } else if (current_fh->fh_export->ex_fslocs.migrated &&
1673                          !(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
1674                        op->status = nfserr_moved;
1675                        goto encode_op;
1676                }
1677
1678                fh_clear_wcc(current_fh);
1679
1680                /* If op is non-idempotent */
1681                if (opdesc->op_flags & OP_MODIFIES_SOMETHING) {
1682                        /*
1683                         * Don't execute this op if we couldn't encode a
1684                         * succesful reply:
1685                         */
1686                        u32 plen = opdesc->op_rsize_bop(rqstp, op);
1687                        /*
1688                         * Plus if there's another operation, make sure
1689                         * we'll have space to at least encode an error:
1690                         */
1691                        if (resp->opcnt < args->opcnt)
1692                                plen += COMPOUND_ERR_SLACK_SPACE;
1693                        op->status = nfsd4_check_resp_size(resp, plen);
1694                }
1695
1696                if (op->status)
1697                        goto encode_op;
1698
1699                if (opdesc->op_get_currentstateid)
1700                        opdesc->op_get_currentstateid(cstate, &op->u);
1701                op->status = opdesc->op_func(rqstp, cstate, &op->u);
1702
1703                if (!op->status) {
1704                        if (opdesc->op_set_currentstateid)
1705                                opdesc->op_set_currentstateid(cstate, &op->u);
1706
1707                        if (opdesc->op_flags & OP_CLEAR_STATEID)
1708                                clear_current_stateid(cstate);
1709
1710                        if (need_wrongsec_check(rqstp))
1711                                op->status = check_nfsd_access(current_fh->fh_export, rqstp);
1712                }
1713
1714encode_op:
1715                /* Only from SEQUENCE */
1716                if (cstate->status == nfserr_replay_cache) {
1717                        dprintk("%s NFS4.1 replay from cache\n", __func__);
1718                        status = op->status;
1719                        goto out;
1720                }
1721                if (op->status == nfserr_replay_me) {
1722                        op->replay = &cstate->replay_owner->so_replay;
1723                        nfsd4_encode_replay(&resp->xdr, op);
1724                        status = op->status = op->replay->rp_status;
1725                } else {
1726                        nfsd4_encode_operation(resp, op);
1727                        status = op->status;
1728                }
1729
1730                dprintk("nfsv4 compound op %p opcnt %d #%d: %d: status %d\n",
1731                        args->ops, args->opcnt, resp->opcnt, op->opnum,
1732                        be32_to_cpu(status));
1733
1734                nfsd4_cstate_clear_replay(cstate);
1735                /* XXX Ugh, we need to get rid of this kind of special case: */
1736                if (op->opnum == OP_READ && op->u.read.rd_filp)
1737                        fput(op->u.read.rd_filp);
1738
1739                nfsd4_increment_op_stats(op->opnum);
1740        }
1741
1742        cstate->status = status;
1743        fh_put(current_fh);
1744        fh_put(save_fh);
1745        BUG_ON(cstate->replay_owner);
1746out:
1747        /* Reset deferral mechanism for RPC deferrals */
1748        set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags);
1749        dprintk("nfsv4 compound returned %d\n", ntohl(status));
1750        return status;
1751}
1752
1753#define op_encode_hdr_size              (2)
1754#define op_encode_stateid_maxsz         (XDR_QUADLEN(NFS4_STATEID_SIZE))
1755#define op_encode_verifier_maxsz        (XDR_QUADLEN(NFS4_VERIFIER_SIZE))
1756#define op_encode_change_info_maxsz     (5)
1757#define nfs4_fattr_bitmap_maxsz         (4)
1758
1759/* We'll fall back on returning no lockowner if run out of space: */
1760#define op_encode_lockowner_maxsz       (0)
1761#define op_encode_lock_denied_maxsz     (8 + op_encode_lockowner_maxsz)
1762
1763#define nfs4_owner_maxsz                (1 + XDR_QUADLEN(IDMAP_NAMESZ))
1764
1765#define op_encode_ace_maxsz             (3 + nfs4_owner_maxsz)
1766#define op_encode_delegation_maxsz      (1 + op_encode_stateid_maxsz + 1 + \
1767                                         op_encode_ace_maxsz)
1768
1769#define op_encode_channel_attrs_maxsz   (6 + 1 + 1)
1770
1771static inline u32 nfsd4_only_status_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1772{
1773        return (op_encode_hdr_size) * sizeof(__be32);
1774}
1775
1776static inline u32 nfsd4_status_stateid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1777{
1778        return (op_encode_hdr_size + op_encode_stateid_maxsz)* sizeof(__be32);
1779}
1780
1781static inline u32 nfsd4_commit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1782{
1783        return (op_encode_hdr_size + op_encode_verifier_maxsz) * sizeof(__be32);
1784}
1785
1786static inline u32 nfsd4_create_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1787{
1788        return (op_encode_hdr_size + op_encode_change_info_maxsz
1789                + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
1790}
1791
1792/*
1793 * Note since this is an idempotent operation we won't insist on failing
1794 * the op prematurely if the estimate is too large.  We may turn off splice
1795 * reads unnecessarily.
1796 */
1797static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp,
1798                                      struct nfsd4_op *op)
1799{
1800        u32 *bmap = op->u.getattr.ga_bmval;
1801        u32 bmap0 = bmap[0], bmap1 = bmap[1], bmap2 = bmap[2];
1802        u32 ret = 0;
1803
1804        if (bmap0 & FATTR4_WORD0_ACL)
1805                return svc_max_payload(rqstp);
1806        if (bmap0 & FATTR4_WORD0_FS_LOCATIONS)
1807                return svc_max_payload(rqstp);
1808
1809        if (bmap1 & FATTR4_WORD1_OWNER) {
1810                ret += IDMAP_NAMESZ + 4;
1811                bmap1 &= ~FATTR4_WORD1_OWNER;
1812        }
1813        if (bmap1 & FATTR4_WORD1_OWNER_GROUP) {
1814                ret += IDMAP_NAMESZ + 4;
1815                bmap1 &= ~FATTR4_WORD1_OWNER_GROUP;
1816        }
1817        if (bmap0 & FATTR4_WORD0_FILEHANDLE) {
1818                ret += NFS4_FHSIZE + 4;
1819                bmap0 &= ~FATTR4_WORD0_FILEHANDLE;
1820        }
1821        if (bmap2 & FATTR4_WORD2_SECURITY_LABEL) {
1822                ret += NFS4_MAXLABELLEN + 12;
1823                bmap2 &= ~FATTR4_WORD2_SECURITY_LABEL;
1824        }
1825        /*
1826         * Largest of remaining attributes are 16 bytes (e.g.,
1827         * supported_attributes)
1828         */
1829        ret += 16 * (hweight32(bmap0) + hweight32(bmap1) + hweight32(bmap2));
1830        /* bitmask, length */
1831        ret += 20;
1832        return ret;
1833}
1834
1835static inline u32 nfsd4_link_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1836{
1837        return (op_encode_hdr_size + op_encode_change_info_maxsz)
1838                * sizeof(__be32);
1839}
1840
1841static inline u32 nfsd4_lock_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1842{
1843        return (op_encode_hdr_size + op_encode_lock_denied_maxsz)
1844                * sizeof(__be32);
1845}
1846
1847static inline u32 nfsd4_open_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1848{
1849        return (op_encode_hdr_size + op_encode_stateid_maxsz
1850                + op_encode_change_info_maxsz + 1
1851                + nfs4_fattr_bitmap_maxsz
1852                + op_encode_delegation_maxsz) * sizeof(__be32);
1853}
1854
1855static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1856{
1857        u32 maxcount = 0, rlen = 0;
1858
1859        maxcount = svc_max_payload(rqstp);
1860        rlen = min(op->u.read.rd_length, maxcount);
1861
1862        return (op_encode_hdr_size + 2 + XDR_QUADLEN(rlen)) * sizeof(__be32);
1863}
1864
1865static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1866{
1867        u32 maxcount = 0, rlen = 0;
1868
1869        maxcount = svc_max_payload(rqstp);
1870        rlen = min(op->u.readdir.rd_maxcount, maxcount);
1871
1872        return (op_encode_hdr_size + op_encode_verifier_maxsz +
1873                XDR_QUADLEN(rlen)) * sizeof(__be32);
1874}
1875
1876static inline u32 nfsd4_remove_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1877{
1878        return (op_encode_hdr_size + op_encode_change_info_maxsz)
1879                * sizeof(__be32);
1880}
1881
1882static inline u32 nfsd4_rename_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1883{
1884        return (op_encode_hdr_size + op_encode_change_info_maxsz
1885                + op_encode_change_info_maxsz) * sizeof(__be32);
1886}
1887
1888static inline u32 nfsd4_sequence_rsize(struct svc_rqst *rqstp,
1889                                       struct nfsd4_op *op)
1890{
1891        return (op_encode_hdr_size
1892                + XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) * sizeof(__be32);
1893}
1894
1895static inline u32 nfsd4_setattr_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1896{
1897        return (op_encode_hdr_size + nfs4_fattr_bitmap_maxsz) * sizeof(__be32);
1898}
1899
1900static inline u32 nfsd4_setclientid_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1901{
1902        return (op_encode_hdr_size + 2 + XDR_QUADLEN(NFS4_VERIFIER_SIZE)) *
1903                                                                sizeof(__be32);
1904}
1905
1906static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1907{
1908        return (op_encode_hdr_size + 2 + op_encode_verifier_maxsz) * sizeof(__be32);
1909}
1910
1911static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1912{
1913        return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\
1914                1 + 1 + /* eir_flags, spr_how */\
1915                4 + /* spo_must_enforce & _allow with bitmap */\
1916                2 + /*eir_server_owner.so_minor_id */\
1917                /* eir_server_owner.so_major_id<> */\
1918                XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
1919                /* eir_server_scope<> */\
1920                XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\
1921                1 + /* eir_server_impl_id array length */\
1922                0 /* ignored eir_server_impl_id contents */) * sizeof(__be32);
1923}
1924
1925static inline u32 nfsd4_bind_conn_to_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1926{
1927        return (op_encode_hdr_size + \
1928                XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* bctsr_sessid */\
1929                2 /* bctsr_dir, use_conn_in_rdma_mode */) * sizeof(__be32);
1930}
1931
1932static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1933{
1934        return (op_encode_hdr_size + \
1935                XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + /* sessionid */\
1936                2 + /* csr_sequence, csr_flags */\
1937                op_encode_channel_attrs_maxsz + \
1938                op_encode_channel_attrs_maxsz) * sizeof(__be32);
1939}
1940
1941#ifdef CONFIG_NFSD_PNFS
1942/*
1943 * At this stage we don't really know what layout driver will handle the request,
1944 * so we need to define an arbitrary upper bound here.
1945 */
1946#define MAX_LAYOUT_SIZE         128
1947static inline u32 nfsd4_layoutget_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1948{
1949        return (op_encode_hdr_size +
1950                1 /* logr_return_on_close */ +
1951                op_encode_stateid_maxsz +
1952                1 /* nr of layouts */ +
1953                MAX_LAYOUT_SIZE) * sizeof(__be32);
1954}
1955
1956static inline u32 nfsd4_layoutcommit_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1957{
1958        return (op_encode_hdr_size +
1959                1 /* locr_newsize */ +
1960                2 /* ns_size */) * sizeof(__be32);
1961}
1962
1963static inline u32 nfsd4_layoutreturn_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
1964{
1965        return (op_encode_hdr_size +
1966                1 /* lrs_stateid */ +
1967                op_encode_stateid_maxsz) * sizeof(__be32);
1968}
1969#endif /* CONFIG_NFSD_PNFS */
1970
1971static struct nfsd4_operation nfsd4_ops[] = {
1972        [OP_ACCESS] = {
1973                .op_func = (nfsd4op_func)nfsd4_access,
1974                .op_name = "OP_ACCESS",
1975        },
1976        [OP_CLOSE] = {
1977                .op_func = (nfsd4op_func)nfsd4_close,
1978                .op_flags = OP_MODIFIES_SOMETHING,
1979                .op_name = "OP_CLOSE",
1980                .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
1981                .op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid,
1982                .op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid,
1983        },
1984        [OP_COMMIT] = {
1985                .op_func = (nfsd4op_func)nfsd4_commit,
1986                .op_flags = OP_MODIFIES_SOMETHING,
1987                .op_name = "OP_COMMIT",
1988                .op_rsize_bop = (nfsd4op_rsize)nfsd4_commit_rsize,
1989        },
1990        [OP_CREATE] = {
1991                .op_func = (nfsd4op_func)nfsd4_create,
1992                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID,
1993                .op_name = "OP_CREATE",
1994                .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize,
1995        },
1996        [OP_DELEGRETURN] = {
1997                .op_func = (nfsd4op_func)nfsd4_delegreturn,
1998                .op_flags = OP_MODIFIES_SOMETHING,
1999                .op_name = "OP_DELEGRETURN",
2000                .op_rsize_bop = nfsd4_only_status_rsize,
2001                .op_get_currentstateid = (stateid_getter)nfsd4_get_delegreturnstateid,
2002        },
2003        [OP_GETATTR] = {
2004                .op_func = (nfsd4op_func)nfsd4_getattr,
2005                .op_flags = ALLOWED_ON_ABSENT_FS,
2006                .op_rsize_bop = nfsd4_getattr_rsize,
2007                .op_name = "OP_GETATTR",
2008        },
2009        [OP_GETFH] = {
2010                .op_func = (nfsd4op_func)nfsd4_getfh,
2011                .op_name = "OP_GETFH",
2012        },
2013        [OP_LINK] = {
2014                .op_func = (nfsd4op_func)nfsd4_link,
2015                .op_flags = ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING
2016                                | OP_CACHEME,
2017                .op_name = "OP_LINK",
2018                .op_rsize_bop = (nfsd4op_rsize)nfsd4_link_rsize,
2019        },
2020        [OP_LOCK] = {
2021                .op_func = (nfsd4op_func)nfsd4_lock,
2022                .op_flags = OP_MODIFIES_SOMETHING,
2023                .op_name = "OP_LOCK",
2024                .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize,
2025                .op_set_currentstateid = (stateid_setter)nfsd4_set_lockstateid,
2026        },
2027        [OP_LOCKT] = {
2028                .op_func = (nfsd4op_func)nfsd4_lockt,
2029                .op_name = "OP_LOCKT",
2030        },
2031        [OP_LOCKU] = {
2032                .op_func = (nfsd4op_func)nfsd4_locku,
2033                .op_flags = OP_MODIFIES_SOMETHING,
2034                .op_name = "OP_LOCKU",
2035                .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
2036                .op_get_currentstateid = (stateid_getter)nfsd4_get_lockustateid,
2037        },
2038        [OP_LOOKUP] = {
2039                .op_func = (nfsd4op_func)nfsd4_lookup,
2040                .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
2041                .op_name = "OP_LOOKUP",
2042        },
2043        [OP_LOOKUPP] = {
2044                .op_func = (nfsd4op_func)nfsd4_lookupp,
2045                .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID,
2046                .op_name = "OP_LOOKUPP",
2047        },
2048        [OP_NVERIFY] = {
2049                .op_func = (nfsd4op_func)nfsd4_nverify,
2050                .op_name = "OP_NVERIFY",
2051        },
2052        [OP_OPEN] = {
2053                .op_func = (nfsd4op_func)nfsd4_open,
2054                .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
2055                .op_name = "OP_OPEN",
2056                .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize,
2057                .op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid,
2058        },
2059        [OP_OPEN_CONFIRM] = {
2060                .op_func = (nfsd4op_func)nfsd4_open_confirm,
2061                .op_flags = OP_MODIFIES_SOMETHING,
2062                .op_name = "OP_OPEN_CONFIRM",
2063                .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
2064        },
2065        [OP_OPEN_DOWNGRADE] = {
2066                .op_func = (nfsd4op_func)nfsd4_open_downgrade,
2067                .op_flags = OP_MODIFIES_SOMETHING,
2068                .op_name = "OP_OPEN_DOWNGRADE",
2069                .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize,
2070                .op_get_currentstateid = (stateid_getter)nfsd4_get_opendowngradestateid,
2071                .op_set_currentstateid = (stateid_setter)nfsd4_set_opendowngradestateid,
2072        },
2073        [OP_PUTFH] = {
2074                .op_func = (nfsd4op_func)nfsd4_putfh,
2075                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2076                                | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
2077                .op_name = "OP_PUTFH",
2078                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2079        },
2080        [OP_PUTPUBFH] = {
2081                .op_func = (nfsd4op_func)nfsd4_putrootfh,
2082                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2083                                | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
2084                .op_name = "OP_PUTPUBFH",
2085                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2086        },
2087        [OP_PUTROOTFH] = {
2088                .op_func = (nfsd4op_func)nfsd4_putrootfh,
2089                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2090                                | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID,
2091                .op_name = "OP_PUTROOTFH",
2092                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2093        },
2094        [OP_READ] = {
2095                .op_func = (nfsd4op_func)nfsd4_read,
2096                .op_name = "OP_READ",
2097                .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize,
2098                .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid,
2099        },
2100        [OP_READDIR] = {
2101                .op_func = (nfsd4op_func)nfsd4_readdir,
2102                .op_name = "OP_READDIR",
2103                .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize,
2104        },
2105        [OP_READLINK] = {
2106                .op_func = (nfsd4op_func)nfsd4_readlink,
2107                .op_name = "OP_READLINK",
2108        },
2109        [OP_REMOVE] = {
2110                .op_func = (nfsd4op_func)nfsd4_remove,
2111                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
2112                .op_name = "OP_REMOVE",
2113                .op_rsize_bop = (nfsd4op_rsize)nfsd4_remove_rsize,
2114        },
2115        [OP_RENAME] = {
2116                .op_func = (nfsd4op_func)nfsd4_rename,
2117                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
2118                .op_name = "OP_RENAME",
2119                .op_rsize_bop = (nfsd4op_rsize)nfsd4_rename_rsize,
2120        },
2121        [OP_RENEW] = {
2122                .op_func = (nfsd4op_func)nfsd4_renew,
2123                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2124                                | OP_MODIFIES_SOMETHING,
2125                .op_name = "OP_RENEW",
2126                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2127
2128        },
2129        [OP_RESTOREFH] = {
2130                .op_func = (nfsd4op_func)nfsd4_restorefh,
2131                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2132                                | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING,
2133                .op_name = "OP_RESTOREFH",
2134                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2135        },
2136        [OP_SAVEFH] = {
2137                .op_func = (nfsd4op_func)nfsd4_savefh,
2138                .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING,
2139                .op_name = "OP_SAVEFH",
2140                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2141        },
2142        [OP_SECINFO] = {
2143                .op_func = (nfsd4op_func)nfsd4_secinfo,
2144                .op_flags = OP_HANDLES_WRONGSEC,
2145                .op_name = "OP_SECINFO",
2146        },
2147        [OP_SETATTR] = {
2148                .op_func = (nfsd4op_func)nfsd4_setattr,
2149                .op_name = "OP_SETATTR",
2150                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
2151                .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize,
2152                .op_get_currentstateid = (stateid_getter)nfsd4_get_setattrstateid,
2153        },
2154        [OP_SETCLIENTID] = {
2155                .op_func = (nfsd4op_func)nfsd4_setclientid,
2156                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2157                                | OP_MODIFIES_SOMETHING | OP_CACHEME,
2158                .op_name = "OP_SETCLIENTID",
2159                .op_rsize_bop = (nfsd4op_rsize)nfsd4_setclientid_rsize,
2160        },
2161        [OP_SETCLIENTID_CONFIRM] = {
2162                .op_func = (nfsd4op_func)nfsd4_setclientid_confirm,
2163                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2164                                | OP_MODIFIES_SOMETHING | OP_CACHEME,
2165                .op_name = "OP_SETCLIENTID_CONFIRM",
2166                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2167        },
2168        [OP_VERIFY] = {
2169                .op_func = (nfsd4op_func)nfsd4_verify,
2170                .op_name = "OP_VERIFY",
2171        },
2172        [OP_WRITE] = {
2173                .op_func = (nfsd4op_func)nfsd4_write,
2174                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
2175                .op_name = "OP_WRITE",
2176                .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize,
2177                .op_get_currentstateid = (stateid_getter)nfsd4_get_writestateid,
2178        },
2179        [OP_RELEASE_LOCKOWNER] = {
2180                .op_func = (nfsd4op_func)nfsd4_release_lockowner,
2181                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
2182                                | OP_MODIFIES_SOMETHING,
2183                .op_name = "OP_RELEASE_LOCKOWNER",
2184                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2185        },
2186
2187        /* NFSv4.1 operations */
2188        [OP_EXCHANGE_ID] = {
2189                .op_func = (nfsd4op_func)nfsd4_exchange_id,
2190                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
2191                                | OP_MODIFIES_SOMETHING,
2192                .op_name = "OP_EXCHANGE_ID",
2193                .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize,
2194        },
2195        [OP_BACKCHANNEL_CTL] = {
2196                .op_func = (nfsd4op_func)nfsd4_backchannel_ctl,
2197                .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
2198                .op_name = "OP_BACKCHANNEL_CTL",
2199                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2200        },
2201        [OP_BIND_CONN_TO_SESSION] = {
2202                .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session,
2203                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
2204                                | OP_MODIFIES_SOMETHING,
2205                .op_name = "OP_BIND_CONN_TO_SESSION",
2206                .op_rsize_bop = (nfsd4op_rsize)nfsd4_bind_conn_to_session_rsize,
2207        },
2208        [OP_CREATE_SESSION] = {
2209                .op_func = (nfsd4op_func)nfsd4_create_session,
2210                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
2211                                | OP_MODIFIES_SOMETHING,
2212                .op_name = "OP_CREATE_SESSION",
2213                .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_session_rsize,
2214        },
2215        [OP_DESTROY_SESSION] = {
2216                .op_func = (nfsd4op_func)nfsd4_destroy_session,
2217                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
2218                                | OP_MODIFIES_SOMETHING,
2219                .op_name = "OP_DESTROY_SESSION",
2220                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2221        },
2222        [OP_SEQUENCE] = {
2223                .op_func = (nfsd4op_func)nfsd4_sequence,
2224                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP,
2225                .op_name = "OP_SEQUENCE",
2226                .op_rsize_bop = (nfsd4op_rsize)nfsd4_sequence_rsize,
2227        },
2228        [OP_DESTROY_CLIENTID] = {
2229                .op_func = (nfsd4op_func)nfsd4_destroy_clientid,
2230                .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP
2231                                | OP_MODIFIES_SOMETHING,
2232                .op_name = "OP_DESTROY_CLIENTID",
2233                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2234        },
2235        [OP_RECLAIM_COMPLETE] = {
2236                .op_func = (nfsd4op_func)nfsd4_reclaim_complete,
2237                .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
2238                .op_name = "OP_RECLAIM_COMPLETE",
2239                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2240        },
2241        [OP_SECINFO_NO_NAME] = {
2242                .op_func = (nfsd4op_func)nfsd4_secinfo_no_name,
2243                .op_flags = OP_HANDLES_WRONGSEC,
2244                .op_name = "OP_SECINFO_NO_NAME",
2245        },
2246        [OP_TEST_STATEID] = {
2247                .op_func = (nfsd4op_func)nfsd4_test_stateid,
2248                .op_flags = ALLOWED_WITHOUT_FH,
2249                .op_name = "OP_TEST_STATEID",
2250        },
2251        [OP_FREE_STATEID] = {
2252                .op_func = (nfsd4op_func)nfsd4_free_stateid,
2253                .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING,
2254                .op_name = "OP_FREE_STATEID",
2255                .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid,
2256                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2257        },
2258#ifdef CONFIG_NFSD_PNFS
2259        [OP_GETDEVICEINFO] = {
2260                .op_func = (nfsd4op_func)nfsd4_getdeviceinfo,
2261                .op_flags = ALLOWED_WITHOUT_FH,
2262                .op_name = "OP_GETDEVICEINFO",
2263        },
2264        [OP_LAYOUTGET] = {
2265                .op_func = (nfsd4op_func)nfsd4_layoutget,
2266                .op_flags = OP_MODIFIES_SOMETHING,
2267                .op_name = "OP_LAYOUTGET",
2268                .op_rsize_bop = (nfsd4op_rsize)nfsd4_layoutget_rsize,
2269        },
2270        [OP_LAYOUTCOMMIT] = {
2271                .op_func = (nfsd4op_func)nfsd4_layoutcommit,
2272                .op_flags = OP_MODIFIES_SOMETHING,
2273                .op_name = "OP_LAYOUTCOMMIT",
2274                .op_rsize_bop = (nfsd4op_rsize)nfsd4_layoutcommit_rsize,
2275        },
2276        [OP_LAYOUTRETURN] = {
2277                .op_func = (nfsd4op_func)nfsd4_layoutreturn,
2278                .op_flags = OP_MODIFIES_SOMETHING,
2279                .op_name = "OP_LAYOUTRETURN",
2280                .op_rsize_bop = (nfsd4op_rsize)nfsd4_layoutreturn_rsize,
2281        },
2282#endif /* CONFIG_NFSD_PNFS */
2283
2284        /* NFSv4.2 operations */
2285        [OP_ALLOCATE] = {
2286                .op_func = (nfsd4op_func)nfsd4_allocate,
2287                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
2288                .op_name = "OP_ALLOCATE",
2289                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2290        },
2291        [OP_DEALLOCATE] = {
2292                .op_func = (nfsd4op_func)nfsd4_deallocate,
2293                .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
2294                .op_name = "OP_DEALLOCATE",
2295                .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
2296        },
2297        [OP_SEEK] = {
2298                .op_func = (nfsd4op_func)nfsd4_seek,
2299                .op_name = "OP_SEEK",
2300        },
2301};
2302
2303int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op)
2304{
2305        struct nfsd4_operation *opdesc;
2306        nfsd4op_rsize estimator;
2307
2308        if (op->opnum == OP_ILLEGAL)
2309                return op_encode_hdr_size * sizeof(__be32);
2310        opdesc = OPDESC(op);
2311        estimator = opdesc->op_rsize_bop;
2312        return estimator ? estimator(rqstp, op) : PAGE_SIZE;
2313}
2314
2315void warn_on_nonidempotent_op(struct nfsd4_op *op)
2316{
2317        if (OPDESC(op)->op_flags & OP_MODIFIES_SOMETHING) {
2318                pr_err("unable to encode reply to nonidempotent op %d (%s)\n",
2319                        op->opnum, nfsd4_op_name(op->opnum));
2320                WARN_ON_ONCE(1);
2321        }
2322}
2323
2324static const char *nfsd4_op_name(unsigned opnum)
2325{
2326        if (opnum < ARRAY_SIZE(nfsd4_ops))
2327                return nfsd4_ops[opnum].op_name;
2328        return "unknown_operation";
2329}
2330
2331#define nfsd4_voidres                   nfsd4_voidargs
2332struct nfsd4_voidargs { int dummy; };
2333
2334static struct svc_procedure             nfsd_procedures4[2] = {
2335        [NFSPROC4_NULL] = {
2336                .pc_func = (svc_procfunc) nfsd4_proc_null,
2337                .pc_encode = (kxdrproc_t) nfs4svc_encode_voidres,
2338                .pc_argsize = sizeof(struct nfsd4_voidargs),
2339                .pc_ressize = sizeof(struct nfsd4_voidres),
2340                .pc_cachetype = RC_NOCACHE,
2341                .pc_xdrressize = 1,
2342        },
2343        [NFSPROC4_COMPOUND] = {
2344                .pc_func = (svc_procfunc) nfsd4_proc_compound,
2345                .pc_decode = (kxdrproc_t) nfs4svc_decode_compoundargs,
2346                .pc_encode = (kxdrproc_t) nfs4svc_encode_compoundres,
2347                .pc_argsize = sizeof(struct nfsd4_compoundargs),
2348                .pc_ressize = sizeof(struct nfsd4_compoundres),
2349                .pc_release = nfsd4_release_compoundargs,
2350                .pc_cachetype = RC_NOCACHE,
2351                .pc_xdrressize = NFSD_BUFSIZE/4,
2352        },
2353};
2354
2355struct svc_version      nfsd_version4 = {
2356                .vs_vers        = 4,
2357                .vs_nproc       = 2,
2358                .vs_proc        = nfsd_procedures4,
2359                .vs_dispatch    = nfsd_dispatch,
2360                .vs_xdrsize     = NFS4_SVC_XDRSIZE,
2361                .vs_rpcb_optnl  = 1,
2362};
2363
2364/*
2365 * Local variables:
2366 *  c-basic-offset: 8
2367 * End:
2368 */
2369