diff options
Diffstat (limited to 'fs/nfsd/nfs4callback.c')
| -rw-r--r-- | fs/nfsd/nfs4callback.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 7cbdf1b2e4ab..58277859a467 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
| @@ -546,6 +546,102 @@ out: | |||
| 546 | return status; | 546 | return status; |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | #ifdef CONFIG_NFSD_PNFS | ||
| 550 | /* | ||
| 551 | * CB_LAYOUTRECALL4args | ||
| 552 | * | ||
| 553 | * struct layoutrecall_file4 { | ||
| 554 | * nfs_fh4 lor_fh; | ||
| 555 | * offset4 lor_offset; | ||
| 556 | * length4 lor_length; | ||
| 557 | * stateid4 lor_stateid; | ||
| 558 | * }; | ||
| 559 | * | ||
| 560 | * union layoutrecall4 switch(layoutrecall_type4 lor_recalltype) { | ||
| 561 | * case LAYOUTRECALL4_FILE: | ||
| 562 | * layoutrecall_file4 lor_layout; | ||
| 563 | * case LAYOUTRECALL4_FSID: | ||
| 564 | * fsid4 lor_fsid; | ||
| 565 | * case LAYOUTRECALL4_ALL: | ||
| 566 | * void; | ||
| 567 | * }; | ||
| 568 | * | ||
| 569 | * struct CB_LAYOUTRECALL4args { | ||
| 570 | * layouttype4 clora_type; | ||
| 571 | * layoutiomode4 clora_iomode; | ||
| 572 | * bool clora_changed; | ||
| 573 | * layoutrecall4 clora_recall; | ||
| 574 | * }; | ||
| 575 | */ | ||
| 576 | static void encode_cb_layout4args(struct xdr_stream *xdr, | ||
| 577 | const struct nfs4_layout_stateid *ls, | ||
| 578 | struct nfs4_cb_compound_hdr *hdr) | ||
| 579 | { | ||
| 580 | __be32 *p; | ||
| 581 | |||
| 582 | BUG_ON(hdr->minorversion == 0); | ||
| 583 | |||
| 584 | p = xdr_reserve_space(xdr, 5 * 4); | ||
| 585 | *p++ = cpu_to_be32(OP_CB_LAYOUTRECALL); | ||
| 586 | *p++ = cpu_to_be32(ls->ls_layout_type); | ||
| 587 | *p++ = cpu_to_be32(IOMODE_ANY); | ||
| 588 | *p++ = cpu_to_be32(1); | ||
| 589 | *p = cpu_to_be32(RETURN_FILE); | ||
| 590 | |||
| 591 | encode_nfs_fh4(xdr, &ls->ls_stid.sc_file->fi_fhandle); | ||
| 592 | |||
| 593 | p = xdr_reserve_space(xdr, 2 * 8); | ||
| 594 | p = xdr_encode_hyper(p, 0); | ||
| 595 | xdr_encode_hyper(p, NFS4_MAX_UINT64); | ||
| 596 | |||
| 597 | encode_stateid4(xdr, &ls->ls_recall_sid); | ||
| 598 | |||
| 599 | hdr->nops++; | ||
| 600 | } | ||
| 601 | |||
| 602 | static void nfs4_xdr_enc_cb_layout(struct rpc_rqst *req, | ||
| 603 | struct xdr_stream *xdr, | ||
| 604 | const struct nfsd4_callback *cb) | ||
| 605 | { | ||
| 606 | const struct nfs4_layout_stateid *ls = | ||
| 607 | container_of(cb, struct nfs4_layout_stateid, ls_recall); | ||
| 608 | struct nfs4_cb_compound_hdr hdr = { | ||
| 609 | .ident = 0, | ||
| 610 | .minorversion = cb->cb_minorversion, | ||
| 611 | }; | ||
| 612 | |||
| 613 | encode_cb_compound4args(xdr, &hdr); | ||
| 614 | encode_cb_sequence4args(xdr, cb, &hdr); | ||
| 615 | encode_cb_layout4args(xdr, ls, &hdr); | ||
| 616 | encode_cb_nops(&hdr); | ||
| 617 | } | ||
| 618 | |||
| 619 | static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp, | ||
| 620 | struct xdr_stream *xdr, | ||
| 621 | struct nfsd4_callback *cb) | ||
| 622 | { | ||
| 623 | struct nfs4_cb_compound_hdr hdr; | ||
| 624 | enum nfsstat4 nfserr; | ||
| 625 | int status; | ||
| 626 | |||
| 627 | status = decode_cb_compound4res(xdr, &hdr); | ||
| 628 | if (unlikely(status)) | ||
| 629 | goto out; | ||
| 630 | if (cb) { | ||
| 631 | status = decode_cb_sequence4res(xdr, cb); | ||
| 632 | if (unlikely(status)) | ||
| 633 | goto out; | ||
| 634 | } | ||
| 635 | status = decode_cb_op_status(xdr, OP_CB_LAYOUTRECALL, &nfserr); | ||
| 636 | if (unlikely(status)) | ||
| 637 | goto out; | ||
| 638 | if (unlikely(nfserr != NFS4_OK)) | ||
| 639 | status = nfs_cb_stat_to_errno(nfserr); | ||
| 640 | out: | ||
| 641 | return status; | ||
| 642 | } | ||
| 643 | #endif /* CONFIG_NFSD_PNFS */ | ||
| 644 | |||
| 549 | /* | 645 | /* |
| 550 | * RPC procedure tables | 646 | * RPC procedure tables |
| 551 | */ | 647 | */ |
| @@ -563,6 +659,9 @@ out: | |||
| 563 | static struct rpc_procinfo nfs4_cb_procedures[] = { | 659 | static struct rpc_procinfo nfs4_cb_procedures[] = { |
| 564 | PROC(CB_NULL, NULL, cb_null, cb_null), | 660 | PROC(CB_NULL, NULL, cb_null, cb_null), |
| 565 | PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall), | 661 | PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall), |
| 662 | #ifdef CONFIG_NFSD_PNFS | ||
| 663 | PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout), | ||
| 664 | #endif | ||
| 566 | }; | 665 | }; |
| 567 | 666 | ||
| 568 | static struct rpc_version nfs_cb_version4 = { | 667 | static struct rpc_version nfs_cb_version4 = { |
