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