Skip to content

Commit 9eb190f

Browse files
olgakorn1J. Bruce Fields
authored andcommitted
NFSD CB_OFFLOAD xdr
Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
1 parent 6bf4ca7 commit 9eb190f

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

fs/nfsd/nfs4callback.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "state.h"
4040
#include "netns.h"
4141
#include "xdr4cb.h"
42+
#include "xdr4.h"
4243

4344
#define NFSDDBG_FACILITY NFSDDBG_PROC
4445

@@ -105,6 +106,7 @@ enum nfs_cb_opnum4 {
105106
OP_CB_WANTS_CANCELLED = 12,
106107
OP_CB_NOTIFY_LOCK = 13,
107108
OP_CB_NOTIFY_DEVICEID = 14,
109+
OP_CB_OFFLOAD = 15,
108110
OP_CB_ILLEGAL = 10044
109111
};
110112

@@ -682,6 +684,101 @@ static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp,
682684
return decode_cb_op_status(xdr, OP_CB_NOTIFY_LOCK, &cb->cb_status);
683685
}
684686

687+
/*
688+
* struct write_response4 {
689+
* stateid4 wr_callback_id<1>;
690+
* length4 wr_count;
691+
* stable_how4 wr_committed;
692+
* verifier4 wr_writeverf;
693+
* };
694+
* union offload_info4 switch (nfsstat4 coa_status) {
695+
* case NFS4_OK:
696+
* write_response4 coa_resok4;
697+
* default:
698+
* length4 coa_bytes_copied;
699+
* };
700+
* struct CB_OFFLOAD4args {
701+
* nfs_fh4 coa_fh;
702+
* stateid4 coa_stateid;
703+
* offload_info4 coa_offload_info;
704+
* };
705+
*/
706+
static void encode_offload_info4(struct xdr_stream *xdr,
707+
__be32 nfserr,
708+
const struct nfsd4_copy *cp)
709+
{
710+
__be32 *p;
711+
712+
p = xdr_reserve_space(xdr, 4);
713+
*p++ = nfserr;
714+
if (!nfserr) {
715+
p = xdr_reserve_space(xdr, 4 + 8 + 4 + NFS4_VERIFIER_SIZE);
716+
p = xdr_encode_empty_array(p);
717+
p = xdr_encode_hyper(p, cp->cp_res.wr_bytes_written);
718+
*p++ = cpu_to_be32(cp->cp_res.wr_stable_how);
719+
p = xdr_encode_opaque_fixed(p, cp->cp_res.wr_verifier.data,
720+
NFS4_VERIFIER_SIZE);
721+
} else {
722+
p = xdr_reserve_space(xdr, 8);
723+
/* We always return success if bytes were written */
724+
p = xdr_encode_hyper(p, 0);
725+
}
726+
}
727+
728+
static void encode_cb_offload4args(struct xdr_stream *xdr,
729+
__be32 nfserr,
730+
const struct knfsd_fh *fh,
731+
const struct nfsd4_copy *cp,
732+
struct nfs4_cb_compound_hdr *hdr)
733+
{
734+
__be32 *p;
735+
736+
p = xdr_reserve_space(xdr, 4);
737+
*p++ = cpu_to_be32(OP_CB_OFFLOAD);
738+
encode_nfs_fh4(xdr, fh);
739+
encode_stateid4(xdr, &cp->cp_res.cb_stateid);
740+
encode_offload_info4(xdr, nfserr, cp);
741+
742+
hdr->nops++;
743+
}
744+
745+
static void nfs4_xdr_enc_cb_offload(struct rpc_rqst *req,
746+
struct xdr_stream *xdr,
747+
const void *data)
748+
{
749+
const struct nfsd4_callback *cb = data;
750+
const struct nfsd4_copy *cp =
751+
container_of(cb, struct nfsd4_copy, cp_cb);
752+
struct nfs4_cb_compound_hdr hdr = {
753+
.ident = 0,
754+
.minorversion = cb->cb_clp->cl_minorversion,
755+
};
756+
757+
encode_cb_compound4args(xdr, &hdr);
758+
encode_cb_sequence4args(xdr, cb, &hdr);
759+
encode_cb_offload4args(xdr, cp->nfserr, &cp->fh, cp, &hdr);
760+
encode_cb_nops(&hdr);
761+
}
762+
763+
static int nfs4_xdr_dec_cb_offload(struct rpc_rqst *rqstp,
764+
struct xdr_stream *xdr,
765+
void *data)
766+
{
767+
struct nfsd4_callback *cb = data;
768+
struct nfs4_cb_compound_hdr hdr;
769+
int status;
770+
771+
status = decode_cb_compound4res(xdr, &hdr);
772+
if (unlikely(status))
773+
return status;
774+
775+
if (cb) {
776+
status = decode_cb_sequence4res(xdr, cb);
777+
if (unlikely(status || cb->cb_seq_status))
778+
return status;
779+
}
780+
return decode_cb_op_status(xdr, OP_CB_OFFLOAD, &cb->cb_status);
781+
}
685782
/*
686783
* RPC procedure tables
687784
*/
@@ -703,6 +800,7 @@ static const struct rpc_procinfo nfs4_cb_procedures[] = {
703800
PROC(CB_LAYOUT, COMPOUND, cb_layout, cb_layout),
704801
#endif
705802
PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock),
803+
PROC(CB_OFFLOAD, COMPOUND, cb_offload, cb_offload),
706804
};
707805

708806
static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)];

fs/nfsd/state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ enum nfsd4_cb_op {
573573
NFSPROC4_CLNT_CB_NULL = 0,
574574
NFSPROC4_CLNT_CB_RECALL,
575575
NFSPROC4_CLNT_CB_LAYOUT,
576+
NFSPROC4_CLNT_CB_OFFLOAD,
576577
NFSPROC4_CLNT_CB_SEQUENCE,
577578
NFSPROC4_CLNT_CB_NOTIFY_LOCK,
578579
};

fs/nfsd/xdr4.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ struct nfsd42_write_res {
511511
u64 wr_bytes_written;
512512
u32 wr_stable_how;
513513
nfs4_verifier wr_verifier;
514+
stateid_t cb_stateid;
514515
};
515516

516517
struct nfsd4_copy {
@@ -526,6 +527,11 @@ struct nfsd4_copy {
526527

527528
/* response */
528529
struct nfsd42_write_res cp_res;
530+
531+
/* for cb_offload */
532+
struct nfsd4_callback cp_cb;
533+
__be32 nfserr;
534+
struct knfsd_fh fh;
529535
};
530536

531537
struct nfsd4_seek {

fs/nfsd/xdr4cb.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,13 @@
3838
#define NFS4_dec_cb_notify_lock_sz (cb_compound_dec_hdr_sz + \
3939
cb_sequence_dec_sz + \
4040
op_dec_sz)
41+
#define enc_cb_offload_info_sz (1 + 1 + 2 + 1 + \
42+
XDR_QUADLEN(NFS4_VERIFIER_SIZE))
43+
#define NFS4_enc_cb_offload_sz (cb_compound_enc_hdr_sz + \
44+
cb_sequence_enc_sz + \
45+
enc_nfs4_fh_sz + \
46+
enc_stateid_sz + \
47+
enc_cb_offload_info_sz)
48+
#define NFS4_dec_cb_offload_sz (cb_compound_dec_hdr_sz + \
49+
cb_sequence_dec_sz + \
50+
op_dec_sz)

0 commit comments

Comments
 (0)