linux/fs/nfsd/nfs4callback.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) 2001 The Regents of the University of Michigan.
   3 *  All rights reserved.
   4 *
   5 *  Kendrick Smith <kmsmith@umich.edu>
   6 *  Andy Adamson <andros@umich.edu>
   7 *
   8 *  Redistribution and use in source and binary forms, with or without
   9 *  modification, are permitted provided that the following conditions
  10 *  are met:
  11 *
  12 *  1. Redistributions of source code must retain the above copyright
  13 *     notice, this list of conditions and the following disclaimer.
  14 *  2. Redistributions in binary form must reproduce the above copyright
  15 *     notice, this list of conditions and the following disclaimer in the
  16 *     documentation and/or other materials provided with the distribution.
  17 *  3. Neither the name of the University nor the names of its
  18 *     contributors may be used to endorse or promote products derived
  19 *     from this software without specific prior written permission.
  20 *
  21 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  22 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  23 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  26 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  27 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  28 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32 */
  33
  34#include <linux/sunrpc/clnt.h>
  35#include <linux/sunrpc/xprt.h>
  36#include <linux/sunrpc/svc_xprt.h>
  37#include <linux/slab.h>
  38#include "nfsd.h"
  39#include "state.h"
  40#include "netns.h"
  41#include "xdr4cb.h"
  42
  43#define NFSDDBG_FACILITY                NFSDDBG_PROC
  44
  45static void nfsd4_mark_cb_fault(struct nfs4_client *, int reason);
  46
  47#define NFSPROC4_CB_NULL 0
  48#define NFSPROC4_CB_COMPOUND 1
  49
  50/* Index of predefined Linux callback client operations */
  51
  52struct nfs4_cb_compound_hdr {
  53        /* args */
  54        u32             ident;  /* minorversion 0 only */
  55        u32             nops;
  56        __be32          *nops_p;
  57        u32             minorversion;
  58        /* res */
  59        int             status;
  60};
  61
  62/*
  63 * Handle decode buffer overflows out-of-line.
  64 */
  65static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
  66{
  67        dprintk("NFS: %s prematurely hit the end of our receive buffer. "
  68                "Remaining buffer length is %tu words.\n",
  69                func, xdr->end - xdr->p);
  70}
  71
  72static __be32 *xdr_encode_empty_array(__be32 *p)
  73{
  74        *p++ = xdr_zero;
  75        return p;
  76}
  77
  78/*
  79 * Encode/decode NFSv4 CB basic data types
  80 *
  81 * Basic NFSv4 callback data types are defined in section 15 of RFC
  82 * 3530: "Network File System (NFS) version 4 Protocol" and section
  83 * 20 of RFC 5661: "Network File System (NFS) Version 4 Minor Version
  84 * 1 Protocol"
  85 */
  86
  87/*
  88 *      nfs_cb_opnum4
  89 *
  90 *      enum nfs_cb_opnum4 {
  91 *              OP_CB_GETATTR           = 3,
  92 *                ...
  93 *      };
  94 */
  95enum nfs_cb_opnum4 {
  96        OP_CB_GETATTR                   = 3,
  97        OP_CB_RECALL                    = 4,
  98        OP_CB_LAYOUTRECALL              = 5,
  99        OP_CB_NOTIFY                    = 6,
 100        OP_CB_PUSH_DELEG                = 7,
 101        OP_CB_RECALL_ANY                = 8,
 102        OP_CB_RECALLABLE_OBJ_AVAIL      = 9,
 103        OP_CB_RECALL_SLOT               = 10,
 104        OP_CB_SEQUENCE                  = 11,
 105        OP_CB_WANTS_CANCELLED           = 12,
 106        OP_CB_NOTIFY_LOCK               = 13,
 107        OP_CB_NOTIFY_DEVICEID           = 14,
 108        OP_CB_ILLEGAL                   = 10044
 109};
 110
 111static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op)
 112{
 113        __be32 *p;
 114
 115        p = xdr_reserve_space(xdr, 4);
 116        *p = cpu_to_be32(op);
 117}
 118
 119/*
 120 * nfs_fh4
 121 *
 122 *      typedef opaque nfs_fh4<NFS4_FHSIZE>;
 123 */
 124static void encode_nfs_fh4(struct xdr_stream *xdr, const struct knfsd_fh *fh)
 125{
 126        u32 length = fh->fh_size;
 127        __be32 *p;
 128
 129        BUG_ON(length > NFS4_FHSIZE);
 130        p = xdr_reserve_space(xdr, 4 + length);
 131        xdr_encode_opaque(p, &fh->fh_base, length);
 132}
 133
 134/*
 135 * stateid4
 136 *
 137 *      struct stateid4 {
 138 *              uint32_t        seqid;
 139 *              opaque          other[12];
 140 *      };
 141 */
 142static void encode_stateid4(struct xdr_stream *xdr, const stateid_t *sid)
 143{
 144        __be32 *p;
 145
 146        p = xdr_reserve_space(xdr, NFS4_STATEID_SIZE);
 147        *p++ = cpu_to_be32(sid->si_generation);
 148        xdr_encode_opaque_fixed(p, &sid->si_opaque, NFS4_STATEID_OTHER_SIZE);
 149}
 150
 151/*
 152 * sessionid4
 153 *
 154 *      typedef opaque sessionid4[NFS4_SESSIONID_SIZE];
 155 */
 156static void encode_sessionid4(struct xdr_stream *xdr,
 157                              const struct nfsd4_session *session)
 158{
 159        __be32 *p;
 160
 161        p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN);
 162        xdr_encode_opaque_fixed(p, session->se_sessionid.data,
 163                                        NFS4_MAX_SESSIONID_LEN);
 164}
 165
 166/*
 167 * nfsstat4
 168 */
 169static const struct {
 170        int stat;
 171        int errno;
 172} nfs_cb_errtbl[] = {
 173        { NFS4_OK,              0               },
 174        { NFS4ERR_PERM,         -EPERM          },
 175        { NFS4ERR_NOENT,        -ENOENT         },
 176        { NFS4ERR_IO,           -EIO            },
 177        { NFS4ERR_NXIO,         -ENXIO          },
 178        { NFS4ERR_ACCESS,       -EACCES         },
 179        { NFS4ERR_EXIST,        -EEXIST         },
 180        { NFS4ERR_XDEV,         -EXDEV          },
 181        { NFS4ERR_NOTDIR,       -ENOTDIR        },
 182        { NFS4ERR_ISDIR,        -EISDIR         },
 183        { NFS4ERR_INVAL,        -EINVAL         },
 184        { NFS4ERR_FBIG,         -EFBIG          },
 185        { NFS4ERR_NOSPC,        -ENOSPC         },
 186        { NFS4ERR_ROFS,         -EROFS          },
 187        { NFS4ERR_MLINK,        -EMLINK         },
 188        { NFS4ERR_NAMETOOLONG,  -ENAMETOOLONG   },
 189        { NFS4ERR_NOTEMPTY,     -ENOTEMPTY      },
 190        { NFS4ERR_DQUOT,        -EDQUOT         },
 191        { NFS4ERR_STALE,        -ESTALE         },
 192        { NFS4ERR_BADHANDLE,    -EBADHANDLE     },
 193        { NFS4ERR_BAD_COOKIE,   -EBADCOOKIE     },
 194        { NFS4ERR_NOTSUPP,      -ENOTSUPP       },
 195        { NFS4ERR_TOOSMALL,     -ETOOSMALL      },
 196        { NFS4ERR_SERVERFAULT,  -ESERVERFAULT   },
 197        { NFS4ERR_BADTYPE,      -EBADTYPE       },
 198        { NFS4ERR_LOCKED,       -EAGAIN         },
 199        { NFS4ERR_RESOURCE,     -EREMOTEIO      },
 200        { NFS4ERR_SYMLINK,      -ELOOP          },
 201        { NFS4ERR_OP_ILLEGAL,   -EOPNOTSUPP     },
 202        { NFS4ERR_DEADLOCK,     -EDEADLK        },
 203        { -1,                   -EIO            }
 204};
 205
 206/*
 207 * If we cannot translate the error, the recovery routines should
 208 * handle it.
 209 *
 210 * Note: remaining NFSv4 error codes have values > 10000, so should
 211 * not conflict with native Linux error codes.
 212 */
 213static int nfs_cb_stat_to_errno(int status)
 214{
 215        int i;
 216
 217        for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) {
 218                if (nfs_cb_errtbl[i].stat == status)
 219                        return nfs_cb_errtbl[i].errno;
 220        }
 221
 222        dprintk("NFSD: Unrecognized NFS CB status value: %u\n", status);
 223        return -status;
 224}
 225
 226static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
 227                               int *status)
 228{
 229        __be32 *p;
 230        u32 op;
 231
 232        p = xdr_inline_decode(xdr, 4 + 4);
 233        if (unlikely(p == NULL))
 234                goto out_overflow;
 235        op = be32_to_cpup(p++);
 236        if (unlikely(op != expected))
 237                goto out_unexpected;
 238        *status = nfs_cb_stat_to_errno(be32_to_cpup(p));
 239        return 0;
 240out_overflow:
 241        print_overflow_msg(__func__, xdr);
 242        return -EIO;
 243out_unexpected:
 244        dprintk("NFSD: Callback server returned operation %d but "
 245                "we issued a request for %d\n", op, expected);
 246        return -EIO;
 247}
 248
 249/*
 250 * CB_COMPOUND4args
 251 *
 252 *      struct CB_COMPOUND4args {
 253 *              utf8str_cs      tag;
 254 *              uint32_t        minorversion;
 255 *              uint32_t        callback_ident;
 256 *              nfs_cb_argop4   argarray<>;
 257 *      };
 258*/
 259static void encode_cb_compound4args(struct xdr_stream *xdr,
 260                                    struct nfs4_cb_compound_hdr *hdr)
 261{
 262        __be32 * p;
 263
 264        p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
 265        p = xdr_encode_empty_array(p);          /* empty tag */
 266        *p++ = cpu_to_be32(hdr->minorversion);
 267        *p++ = cpu_to_be32(hdr->ident);
 268
 269        hdr->nops_p = p;
 270        *p = cpu_to_be32(hdr->nops);            /* argarray element count */
 271}
 272
 273/*
 274 * Update argarray element count
 275 */
 276static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr)
 277{
 278        BUG_ON(hdr->nops > NFS4_MAX_BACK_CHANNEL_OPS);
 279        *hdr->nops_p = cpu_to_be32(hdr->nops);
 280}
 281
 282/*
 283 * CB_COMPOUND4res
 284 *
 285 *      struct CB_COMPOUND4res {
 286 *              nfsstat4        status;
 287 *              utf8str_cs      tag;
 288 *              nfs_cb_resop4   resarray<>;
 289 *      };
 290 */
 291static int decode_cb_compound4res(struct xdr_stream *xdr,
 292                                  struct nfs4_cb_compound_hdr *hdr)
 293{
 294        u32 length;
 295        __be32 *p;
 296
 297        p = xdr_inline_decode(xdr, 4 + 4);
 298        if (unlikely(p == NULL))
 299                goto out_overflow;
 300        hdr->status = be32_to_cpup(p++);
 301        /* Ignore the tag */
 302        length = be32_to_cpup(p++);
 303        p = xdr_inline_decode(xdr, length + 4);
 304        if (unlikely(p == NULL))
 305                goto out_overflow;
 306        hdr->nops = be32_to_cpup(p);
 307        return 0;
 308out_overflow:
 309        print_overflow_msg(__func__, xdr);
 310        return -EIO;
 311}
 312
 313/*
 314 * CB_RECALL4args
 315 *
 316 *      struct CB_RECALL4args {
 317 *              stateid4        stateid;
 318 *              bool            truncate;
 319 *              nfs_fh4         fh;
 320 *      };
 321 */
 322static void encode_cb_recall4args(struct xdr_stream *xdr,
 323                                  const struct nfs4_delegation *dp,
 324                                  struct nfs4_cb_compound_hdr *hdr)
 325{
 326        __be32 *p;
 327
 328        encode_nfs_cb_opnum4(xdr, OP_CB_RECALL);
 329        encode_stateid4(xdr, &dp->dl_stid.sc_stateid);
 330
 331        p = xdr_reserve_space(xdr, 4);
 332        *p++ = xdr_zero;                        /* truncate */
 333
 334        encode_nfs_fh4(xdr, &dp->dl_stid.sc_file->fi_fhandle);
 335
 336        hdr->nops++;
 337}
 338
 339/*
 340 * CB_SEQUENCE4args
 341 *
 342 *      struct CB_SEQUENCE4args {
 343 *              sessionid4              csa_sessionid;
 344 *              sequenceid4             csa_sequenceid;
 345 *              slotid4                 csa_slotid;
 346 *              slotid4                 csa_highest_slotid;
 347 *              bool                    csa_cachethis;
 348 *              referring_call_list4    csa_referring_call_lists<>;
 349 *      };
 350 */
 351static void encode_cb_sequence4args(struct xdr_stream *xdr,
 352                                    const struct nfsd4_callback *cb,
 353                                    struct nfs4_cb_compound_hdr *hdr)
 354{
 355        struct nfsd4_session *session = cb->cb_clp->cl_cb_session;
 356        __be32 *p;
 357
 358        if (hdr->minorversion == 0)
 359                return;
 360
 361        encode_nfs_cb_opnum4(xdr, OP_CB_SEQUENCE);
 362        encode_sessionid4(xdr, session);
 363
 364        p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4 + 4);
 365        *p++ = cpu_to_be32(session->se_cb_seq_nr);      /* csa_sequenceid */
 366        *p++ = xdr_zero;                        /* csa_slotid */
 367        *p++ = xdr_zero;                        /* csa_highest_slotid */
 368        *p++ = xdr_zero;                        /* csa_cachethis */
 369        xdr_encode_empty_array(p);              /* csa_referring_call_lists */
 370
 371        hdr->nops++;
 372}
 373
 374/*
 375 * CB_SEQUENCE4resok
 376 *
 377 *      struct CB_SEQUENCE4resok {
 378 *              sessionid4      csr_sessionid;
 379 *              sequenceid4     csr_sequenceid;
 380 *              slotid4         csr_slotid;
 381 *              slotid4         csr_highest_slotid;
 382 *              slotid4         csr_target_highest_slotid;
 383 *      };
 384 *
 385 *      union CB_SEQUENCE4res switch (nfsstat4 csr_status) {
 386 *      case NFS4_OK:
 387 *              CB_SEQUENCE4resok       csr_resok4;
 388 *      default:
 389 *              void;
 390 *      };
 391 *
 392 * Our current back channel implmentation supports a single backchannel
 393 * with a single slot.
 394 */
 395static int decode_cb_sequence4resok(struct xdr_stream *xdr,
 396                                    struct nfsd4_callback *cb)
 397{
 398        struct nfsd4_session *session = cb->cb_clp->cl_cb_session;
 399        struct nfs4_sessionid id;
 400        int status;
 401        __be32 *p;
 402        u32 dummy;
 403
 404        status = -ESERVERFAULT;
 405
 406        /*
 407         * If the server returns different values for sessionID, slotID or
 408         * sequence number, the server is looney tunes.
 409         */
 410        p = xdr_inline_decode(xdr, NFS4_MAX_SESSIONID_LEN + 4 + 4 + 4 + 4);
 411        if (unlikely(p == NULL))
 412                goto out_overflow;
 413        memcpy(id.data, p, NFS4_MAX_SESSIONID_LEN);
 414        if (memcmp(id.data, session->se_sessionid.data,
 415                                        NFS4_MAX_SESSIONID_LEN) != 0) {
 416                dprintk("NFS: %s Invalid session id\n", __func__);
 417                goto out;
 418        }
 419        p += XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN);
 420
 421        dummy = be32_to_cpup(p++);
 422        if (dummy != session->se_cb_seq_nr) {
 423                dprintk("NFS: %s Invalid sequence number\n", __func__);
 424                goto out;
 425        }
 426
 427        dummy = be32_to_cpup(p++);
 428        if (dummy != 0) {
 429                dprintk("NFS: %s Invalid slotid\n", __func__);
 430                goto out;
 431        }
 432
 433        /*
 434         * FIXME: process highest slotid and target highest slotid
 435         */
 436        status = 0;
 437out:
 438        if (status)
 439                nfsd4_mark_cb_fault(cb->cb_clp, status);
 440        return status;
 441out_overflow:
 442        print_overflow_msg(__func__, xdr);
 443        return -EIO;
 444}
 445
 446static int decode_cb_sequence4res(struct xdr_stream *xdr,
 447                                  struct nfsd4_callback *cb)
 448{
 449        int status;
 450
 451        if (cb->cb_minorversion == 0)
 452                return 0;
 453
 454        status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &cb->cb_status);
 455        if (unlikely(status || cb->cb_status))
 456                return status;
 457
 458        cb->cb_update_seq_nr = true;
 459        return decode_cb_sequence4resok(xdr, cb);
 460}
 461
 462/*
 463 * NFSv4.0 and NFSv4.1 XDR encode functions
 464 *
 465 * NFSv4.0 callback argument types are defined in section 15 of RFC
 466 * 3530: "Network File System (NFS) version 4 Protocol" and section 20
 467 * of RFC 5661:  "Network File System (NFS) Version 4 Minor Version 1
 468 * Protocol".
 469 */
 470
 471/*
 472 * NB: Without this zero space reservation, callbacks over krb5p fail
 473 */
 474static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
 475                                 void *__unused)
 476{
 477        xdr_reserve_space(xdr, 0);
 478}
 479
 480/*
 481 * 20.2. Operation 4: CB_RECALL - Recall a Delegation
 482 */
 483static void nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, struct xdr_stream *xdr,
 484                                   const struct nfsd4_callback *cb)
 485{
 486        const struct nfs4_delegation *dp = cb_to_delegation(cb);
 487        struct nfs4_cb_compound_hdr hdr = {
 488                .ident = cb->cb_clp->cl_cb_ident,
 489                .minorversion = cb->cb_minorversion,
 490        };
 491
 492        encode_cb_compound4args(xdr, &hdr);
 493        encode_cb_sequence4args(xdr, cb, &hdr);
 494        encode_cb_recall4args(xdr, dp, &hdr);
 495        encode_cb_nops(&hdr);
 496}
 497
 498
 499/*
 500 * NFSv4.0 and NFSv4.1 XDR decode functions
 501 *
 502 * NFSv4.0 callback result types are defined in section 15 of RFC
 503 * 3530: "Network File System (NFS) version 4 Protocol" and section 20
 504 * of RFC 5661:  "Network File System (NFS) Version 4 Minor Version 1
 505 * Protocol".
 506 */
 507
 508static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr,
 509                                void *__unused)
 510{
 511        return 0;
 512}
 513
 514/*
 515 * 20.2. Operation 4: CB_RECALL - Recall a Delegation
 516 */
 517static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp,
 518                                  struct xdr_stream *xdr,
 519                                  struct nfsd4_callback *cb)
 520{
 521        struct nfs4_cb_compound_hdr hdr;
 522        int status;
 523
 524        status = decode_cb_compound4res(xdr, &hdr);
 525        if (unlikely(status))
 526                return status;
 527
 528        if (cb != NULL) {
 529                status = decode_cb_sequence4res(xdr, cb);
 530                if (unlikely(status || cb->cb_status))
 531                        return status;
 532        }
 533
 534        return decode_cb_op_status(xdr, OP_CB_RECALL, &cb->cb_status);
 535}
 536
 537#ifdef CONFIG_NFSD_PNFS
 538/*
 539 * CB_LAYOUTRECALL4args
 540 *
 541 *      struct layoutrecall_file4 {
 542 *              nfs_fh4         lor_fh;
 543 *              offset4         lor_offset;
 544 *              length4         lor_length;
 545 *              stateid4        lor_stateid;
 546 *      };
 547 *
 548 *      union layoutrecall4 switch(layoutrecall_type4 lor_recalltype) {
 549 *      case LAYOUTRECALL4_FILE:
 550 *              layoutrecall_file4 lor_layout;
 551 *      case LAYOUTRECALL4_FSID:
 552 *              fsid4              lor_fsid;
 553 *      case LAYOUTRECALL4_ALL:
 554 *              void;
 555 *      };
 556 *
 557 *      struct CB_LAYOUTRECALL4args {
 558 *              layouttype4             clora_type;
 559 *              layoutiomode4           clora_iomode;
 560 *              bool                    clora_changed;
 561 *              layoutrecall4           clora_recall;
 562 *      };
 563 */
 564static void encode_cb_layout4args(struct xdr_stream *xdr,
 565                                  const struct nfs4_layout_stateid *ls,
 566                                  struct nfs4_cb_compound_hdr *hdr)
 567{
 568        __be32 *p;
 569
 570        BUG_ON(hdr->minorversion == 0);
 571
 572        p = xdr_reserve_space(xdr, 5 * 4);
 573        *p++ = cpu_to_be32(OP_CB_LAYOUTRECALL);
 574        *p++ = cpu_to_be32(ls->ls_layout_type);
 575        *p++ = cpu_to_be32(IOMODE_ANY);
 576        *p++ = cpu_to_be32(1);
 577        *p = cpu_to_be32(RETURN_FILE);
 578
 579        encode_nfs_fh4(xdr, &ls->ls_stid.sc_file->fi_fhandle);
 580
 581        p = xdr_reserve_space(xdr, 2 * 8);
 582        p = xdr_encode_hyper(p, 0);
 583        xdr_encode_hyper(p, NFS4_MAX_UINT64);
 584
 585        encode_stateid4(xdr, &ls->ls_recall_sid);
 586
 587        hdr->nops++;
 588}
 589
 590static void nfs4_xdr_enc_cb_layout(struct rpc_rqst *req,
 591                                   struct xdr_stream *xdr,
 592                                   const struct nfsd4_callback *cb)
 593{
 594        const struct nfs4_layout_stateid *ls =
 595                container_of(cb, struct nfs4_layout_stateid, ls_recall);
 596        struct nfs4_cb_compound_hdr hdr = {
 597                .ident = 0,
 598                .minorversion = cb->cb_minorversion,
 599        };
 600
 601        encode_cb_compound4args(xdr, &hdr);
 602        encode_cb_sequence4args(xdr, cb, &hdr);
 603        encode_cb_layout4args(xdr, ls, &hdr);
 604        encode_cb_nops(&hdr);
 605}
 606
 607static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp,
 608                                  struct xdr_stream *xdr,
 609                                  struct nfsd4_callback *cb)
 610{
 611        struct nfs4_cb_compound_hdr hdr;
 612        int status;
 613
 614        status = decode_cb_compound4res(xdr, &hdr);
 615        if (unlikely(status))
 616                return status;
 617
 618        if (cb) {
 619                status = decode_cb_sequence4res(xdr, cb);
 620                if (unlikely(status || cb->cb_status))
 621                        return status;
 622        }
 623        return decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &cb->cb_status);
 624}
 625#endif /* CONFIG_NFSD_PNFS */
 626
 627/*
 628 * RPC procedure tables
 629 */
 630#define PROC(proc, call, argtype, restype)                              \
 631[NFSPROC4_CLNT_##proc] = {                                              \
 632        .p_proc    = NFSPROC4_CB_##call,                                \
 633        .p_encode  = (kxdreproc_t)nfs4_xdr_enc_##argtype,               \
 634        .p_decode  = (kxdrdproc_t)nfs4_xdr_dec_##restype,               \
 635        .p_arglen  = NFS4_enc_##argtype##_sz,                           \
 636        .p_replen  = NFS4_dec_##restype##_sz,                           \
 637        .p_statidx = NFSPROC4_CB_##call,                                \
 638        .p_name    = #proc,                                             \
 639}
 640
 641static struct rpc_procinfo nfs4_cb_procedures[] = {
 642        PROC(CB_NULL,   NULL,           cb_null,        cb_null),
 643        PROC(CB_RECALL, COMPOUND,       cb_recall,      cb_recall),
 644#ifdef CONFIG_NFSD_PNFS
 645        PROC(CB_LAYOUT, COMPOUND,       cb_layout,      cb_layout),
 646#endif
 647};
 648
 649static struct rpc_version nfs_cb_version4 = {
 650/*
 651 * Note on the callback rpc program version number: despite language in rfc
 652 * 5661 section 18.36.3 requiring servers to use 4 in this field, the
 653 * official xdr descriptions for both 4.0 and 4.1 specify version 1, and
 654 * in practice that appears to be what implementations use.  The section
 655 * 18.36.3 language is expected to be fixed in an erratum.
 656 */
 657        .number                 = 1,
 658        .nrprocs                = ARRAY_SIZE(nfs4_cb_procedures),
 659        .procs                  = nfs4_cb_procedures
 660};
 661
 662static const struct rpc_version *nfs_cb_version[] = {
 663        &nfs_cb_version4,
 664};
 665
 666static const struct rpc_program cb_program;
 667
 668static struct rpc_stat cb_stats = {
 669        .program                = &cb_program
 670};
 671
 672#define NFS4_CALLBACK 0x40000000
 673static const struct rpc_program cb_program = {
 674        .name                   = "nfs4_cb",
 675        .number                 = NFS4_CALLBACK,
 676        .nrvers                 = ARRAY_SIZE(nfs_cb_version),
 677        .version                = nfs_cb_version,
 678        .stats                  = &cb_stats,
 679        .pipe_dir_name          = "nfsd4_cb",
 680};
 681
 682static int max_cb_time(struct net *net)
 683{
 684        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 685        return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
 686}
 687
 688static struct rpc_cred *callback_cred;
 689
 690int set_callback_cred(void)
 691{
 692        if (callback_cred)
 693                return 0;
 694        callback_cred = rpc_lookup_machine_cred("nfs");
 695        if (!callback_cred)
 696                return -ENOMEM;
 697        return 0;
 698}
 699
 700static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
 701{
 702        if (clp->cl_minorversion == 0) {
 703                return get_rpccred(callback_cred);
 704        } else {
 705                struct rpc_auth *auth = client->cl_auth;
 706                struct auth_cred acred = {};
 707
 708                acred.uid = ses->se_cb_sec.uid;
 709                acred.gid = ses->se_cb_sec.gid;
 710                return auth->au_ops->lookup_cred(client->cl_auth, &acred, 0);
 711        }
 712}
 713
 714static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args)
 715{
 716        struct rpc_xprt *xprt;
 717
 718        if (args->protocol != XPRT_TRANSPORT_BC_TCP)
 719                return rpc_create(args);
 720
 721        xprt = args->bc_xprt->xpt_bc_xprt;
 722        if (xprt) {
 723                xprt_get(xprt);
 724                return rpc_create_xprt(args, xprt);
 725        }
 726
 727        return rpc_create(args);
 728}
 729
 730static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
 731{
 732        int maxtime = max_cb_time(clp->net);
 733        struct rpc_timeout      timeparms = {
 734                .to_initval     = maxtime,
 735                .to_retries     = 0,
 736                .to_maxval      = maxtime,
 737        };
 738        struct rpc_create_args args = {
 739                .net            = clp->net,
 740                .address        = (struct sockaddr *) &conn->cb_addr,
 741                .addrsize       = conn->cb_addrlen,
 742                .saddress       = (struct sockaddr *) &conn->cb_saddr,
 743                .timeout        = &timeparms,
 744                .program        = &cb_program,
 745                .version        = 0,
 746                .flags          = (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
 747        };
 748        struct rpc_clnt *client;
 749        struct rpc_cred *cred;
 750
 751        if (clp->cl_minorversion == 0) {
 752                if (!clp->cl_cred.cr_principal &&
 753                                (clp->cl_cred.cr_flavor >= RPC_AUTH_GSS_KRB5))
 754                        return -EINVAL;
 755                args.client_name = clp->cl_cred.cr_principal;
 756                args.prognumber = conn->cb_prog;
 757                args.protocol = XPRT_TRANSPORT_TCP;
 758                args.authflavor = clp->cl_cred.cr_flavor;
 759                clp->cl_cb_ident = conn->cb_ident;
 760        } else {
 761                if (!conn->cb_xprt)
 762                        return -EINVAL;
 763                clp->cl_cb_conn.cb_xprt = conn->cb_xprt;
 764                clp->cl_cb_session = ses;
 765                args.bc_xprt = conn->cb_xprt;
 766                args.prognumber = clp->cl_cb_session->se_cb_prog;
 767                args.protocol = conn->cb_xprt->xpt_class->xcl_ident |
 768                                XPRT_TRANSPORT_BC;
 769                args.authflavor = ses->se_cb_sec.flavor;
 770        }
 771        /* Create RPC client */
 772        client = create_backchannel_client(&args);
 773        if (IS_ERR(client)) {
 774                dprintk("NFSD: couldn't create callback client: %ld\n",
 775                        PTR_ERR(client));
 776                return PTR_ERR(client);
 777        }
 778        cred = get_backchannel_cred(clp, client, ses);
 779        if (IS_ERR(cred)) {
 780                rpc_shutdown_client(client);
 781                return PTR_ERR(cred);
 782        }
 783        clp->cl_cb_client = client;
 784        clp->cl_cb_cred = cred;
 785        return 0;
 786}
 787
 788static void warn_no_callback_path(struct nfs4_client *clp, int reason)
 789{
 790        dprintk("NFSD: warning: no callback path to client %.*s: error %d\n",
 791                (int)clp->cl_name.len, clp->cl_name.data, reason);
 792}
 793
 794static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
 795{
 796        clp->cl_cb_state = NFSD4_CB_DOWN;
 797        warn_no_callback_path(clp, reason);
 798}
 799
 800static void nfsd4_mark_cb_fault(struct nfs4_client *clp, int reason)
 801{
 802        clp->cl_cb_state = NFSD4_CB_FAULT;
 803        warn_no_callback_path(clp, reason);
 804}
 805
 806static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
 807{
 808        struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
 809
 810        if (task->tk_status)
 811                nfsd4_mark_cb_down(clp, task->tk_status);
 812        else
 813                clp->cl_cb_state = NFSD4_CB_UP;
 814}
 815
 816static const struct rpc_call_ops nfsd4_cb_probe_ops = {
 817        /* XXX: release method to ensure we set the cb channel down if
 818         * necessary on early failure? */
 819        .rpc_call_done = nfsd4_cb_probe_done,
 820};
 821
 822static struct workqueue_struct *callback_wq;
 823
 824/*
 825 * Poke the callback thread to process any updates to the callback
 826 * parameters, and send a null probe.
 827 */
 828void nfsd4_probe_callback(struct nfs4_client *clp)
 829{
 830        clp->cl_cb_state = NFSD4_CB_UNKNOWN;
 831        set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags);
 832        nfsd4_run_cb(&clp->cl_cb_null);
 833}
 834
 835void nfsd4_probe_callback_sync(struct nfs4_client *clp)
 836{
 837        nfsd4_probe_callback(clp);
 838        flush_workqueue(callback_wq);
 839}
 840
 841void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
 842{
 843        clp->cl_cb_state = NFSD4_CB_UNKNOWN;
 844        spin_lock(&clp->cl_lock);
 845        memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn));
 846        spin_unlock(&clp->cl_lock);
 847}
 848
 849/*
 850 * There's currently a single callback channel slot.
 851 * If the slot is available, then mark it busy.  Otherwise, set the
 852 * thread for sleeping on the callback RPC wait queue.
 853 */
 854static bool nfsd41_cb_get_slot(struct nfs4_client *clp, struct rpc_task *task)
 855{
 856        if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
 857                rpc_sleep_on(&clp->cl_cb_waitq, task, NULL);
 858                /* Race breaker */
 859                if (test_and_set_bit(0, &clp->cl_cb_slot_busy) != 0) {
 860                        dprintk("%s slot is busy\n", __func__);
 861                        return false;
 862                }
 863                rpc_wake_up_queued_task(&clp->cl_cb_waitq, task);
 864        }
 865        return true;
 866}
 867
 868/*
 869 * TODO: cb_sequence should support referring call lists, cachethis, multiple
 870 * slots, and mark callback channel down on communication errors.
 871 */
 872static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
 873{
 874        struct nfsd4_callback *cb = calldata;
 875        struct nfs4_client *clp = cb->cb_clp;
 876        u32 minorversion = clp->cl_minorversion;
 877
 878        cb->cb_minorversion = minorversion;
 879        cb->cb_update_seq_nr = false;
 880        cb->cb_status = 0;
 881        if (minorversion) {
 882                if (!nfsd41_cb_get_slot(clp, task))
 883                        return;
 884        }
 885        rpc_call_start(task);
 886}
 887
 888static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
 889{
 890        struct nfsd4_callback *cb = calldata;
 891        struct nfs4_client *clp = cb->cb_clp;
 892
 893        dprintk("%s: minorversion=%d\n", __func__,
 894                clp->cl_minorversion);
 895
 896        if (clp->cl_minorversion) {
 897                /*
 898                 * No need for lock, access serialized in nfsd4_cb_prepare
 899                 *
 900                 * RFC5661 20.9.3
 901                 * If CB_SEQUENCE returns an error, then the state of the slot
 902                 * (sequence ID, cached reply) MUST NOT change.
 903                 */
 904                if (cb->cb_update_seq_nr)
 905                        ++clp->cl_cb_session->se_cb_seq_nr;
 906
 907                clear_bit(0, &clp->cl_cb_slot_busy);
 908                rpc_wake_up_next(&clp->cl_cb_waitq);
 909                dprintk("%s: freed slot, new seqid=%d\n", __func__,
 910                        clp->cl_cb_session->se_cb_seq_nr);
 911        }
 912
 913        /*
 914         * If the backchannel connection was shut down while this
 915         * task was queued, we need to resubmit it after setting up
 916         * a new backchannel connection.
 917         *
 918         * Note that if we lost our callback connection permanently
 919         * the submission code will error out, so we don't need to
 920         * handle that case here.
 921         */
 922        if (task->tk_flags & RPC_TASK_KILLED) {
 923                task->tk_status = 0;
 924                cb->cb_need_restart = true;
 925                return;
 926        }
 927
 928        if (cb->cb_status) {
 929                WARN_ON_ONCE(task->tk_status);
 930                task->tk_status = cb->cb_status;
 931        }
 932
 933        switch (cb->cb_ops->done(cb, task)) {
 934        case 0:
 935                task->tk_status = 0;
 936                rpc_restart_call_prepare(task);
 937                return;
 938        case 1:
 939                break;
 940        case -1:
 941                /* Network partition? */
 942                nfsd4_mark_cb_down(clp, task->tk_status);
 943                break;
 944        default:
 945                BUG();
 946        }
 947}
 948
 949static void nfsd4_cb_release(void *calldata)
 950{
 951        struct nfsd4_callback *cb = calldata;
 952
 953        if (cb->cb_need_restart)
 954                nfsd4_run_cb(cb);
 955        else
 956                cb->cb_ops->release(cb);
 957
 958}
 959
 960static const struct rpc_call_ops nfsd4_cb_ops = {
 961        .rpc_call_prepare = nfsd4_cb_prepare,
 962        .rpc_call_done = nfsd4_cb_done,
 963        .rpc_release = nfsd4_cb_release,
 964};
 965
 966int nfsd4_create_callback_queue(void)
 967{
 968        callback_wq = create_singlethread_workqueue("nfsd4_callbacks");
 969        if (!callback_wq)
 970                return -ENOMEM;
 971        return 0;
 972}
 973
 974void nfsd4_destroy_callback_queue(void)
 975{
 976        destroy_workqueue(callback_wq);
 977}
 978
 979/* must be called under the state lock */
 980void nfsd4_shutdown_callback(struct nfs4_client *clp)
 981{
 982        set_bit(NFSD4_CLIENT_CB_KILL, &clp->cl_flags);
 983        /*
 984         * Note this won't actually result in a null callback;
 985         * instead, nfsd4_run_cb_null() will detect the killed
 986         * client, destroy the rpc client, and stop:
 987         */
 988        nfsd4_run_cb(&clp->cl_cb_null);
 989        flush_workqueue(callback_wq);
 990}
 991
 992/* requires cl_lock: */
 993static struct nfsd4_conn * __nfsd4_find_backchannel(struct nfs4_client *clp)
 994{
 995        struct nfsd4_session *s;
 996        struct nfsd4_conn *c;
 997
 998        list_for_each_entry(s, &clp->cl_sessions, se_perclnt) {
 999                list_for_each_entry(c, &s->se_conns, cn_persession) {
1000                        if (c->cn_flags & NFS4_CDFC4_BACK)
1001                                return c;
1002                }
1003        }
1004        return NULL;
1005}
1006
1007static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
1008{
1009        struct nfs4_cb_conn conn;
1010        struct nfs4_client *clp = cb->cb_clp;
1011        struct nfsd4_session *ses = NULL;
1012        struct nfsd4_conn *c;
1013        int err;
1014
1015        /*
1016         * This is either an update, or the client dying; in either case,
1017         * kill the old client:
1018         */
1019        if (clp->cl_cb_client) {
1020                rpc_shutdown_client(clp->cl_cb_client);
1021                clp->cl_cb_client = NULL;
1022                put_rpccred(clp->cl_cb_cred);
1023                clp->cl_cb_cred = NULL;
1024        }
1025        if (clp->cl_cb_conn.cb_xprt) {
1026                svc_xprt_put(clp->cl_cb_conn.cb_xprt);
1027                clp->cl_cb_conn.cb_xprt = NULL;
1028        }
1029        if (test_bit(NFSD4_CLIENT_CB_KILL, &clp->cl_flags))
1030                return;
1031        spin_lock(&clp->cl_lock);
1032        /*
1033         * Only serialized callback code is allowed to clear these
1034         * flags; main nfsd code can only set them:
1035         */
1036        BUG_ON(!(clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK));
1037        clear_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_flags);
1038        memcpy(&conn, &cb->cb_clp->cl_cb_conn, sizeof(struct nfs4_cb_conn));
1039        c = __nfsd4_find_backchannel(clp);
1040        if (c) {
1041                svc_xprt_get(c->cn_xprt);
1042                conn.cb_xprt = c->cn_xprt;
1043                ses = c->cn_session;
1044        }
1045        spin_unlock(&clp->cl_lock);
1046
1047        err = setup_callback_client(clp, &conn, ses);
1048        if (err) {
1049                nfsd4_mark_cb_down(clp, err);
1050                return;
1051        }
1052}
1053
1054static void
1055nfsd4_run_cb_work(struct work_struct *work)
1056{
1057        struct nfsd4_callback *cb =
1058                container_of(work, struct nfsd4_callback, cb_work);
1059        struct nfs4_client *clp = cb->cb_clp;
1060        struct rpc_clnt *clnt;
1061
1062        if (cb->cb_need_restart) {
1063                cb->cb_need_restart = false;
1064        } else {
1065                if (cb->cb_ops && cb->cb_ops->prepare)
1066                        cb->cb_ops->prepare(cb);
1067        }
1068
1069        if (clp->cl_flags & NFSD4_CLIENT_CB_FLAG_MASK)
1070                nfsd4_process_cb_update(cb);
1071
1072        clnt = clp->cl_cb_client;
1073        if (!clnt) {
1074                /* Callback channel broken, or client killed; give up: */
1075                if (cb->cb_ops && cb->cb_ops->release)
1076                        cb->cb_ops->release(cb);
1077                return;
1078        }
1079
1080        /*
1081         * Don't send probe messages for 4.1 or later.
1082         */
1083        if (!cb->cb_ops && clp->cl_minorversion) {
1084                clp->cl_cb_state = NFSD4_CB_UP;
1085                return;
1086        }
1087
1088        cb->cb_msg.rpc_cred = clp->cl_cb_cred;
1089        rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
1090                        cb->cb_ops ? &nfsd4_cb_ops : &nfsd4_cb_probe_ops, cb);
1091}
1092
1093void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
1094                struct nfsd4_callback_ops *ops, enum nfsd4_cb_op op)
1095{
1096        cb->cb_clp = clp;
1097        cb->cb_msg.rpc_proc = &nfs4_cb_procedures[op];
1098        cb->cb_msg.rpc_argp = cb;
1099        cb->cb_msg.rpc_resp = cb;
1100        cb->cb_ops = ops;
1101        INIT_WORK(&cb->cb_work, nfsd4_run_cb_work);
1102        cb->cb_status = 0;
1103        cb->cb_update_seq_nr = false;
1104        cb->cb_need_restart = false;
1105}
1106
1107void nfsd4_run_cb(struct nfsd4_callback *cb)
1108{
1109        queue_work(callback_wq, &cb->cb_work);
1110}
1111