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