Loading fs/nfs/callback.h +12 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,18 @@ struct cb_notify_lock_args { extern __be32 nfs4_callback_notify_lock(void *argp, void *resp, struct cb_process_state *cps); #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 struct cb_offloadargs { struct nfs_fh coa_fh; nfs4_stateid coa_stateid; uint32_t error; uint64_t wr_count; struct nfs_writeverf wr_writeverf; }; extern __be32 nfs4_callback_offload(void *args, void *dummy, struct cb_process_state *cps); #endif /* CONFIG_NFS_V4_2 */ extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); extern __be32 nfs4_callback_getattr(void *argp, void *resp, struct cb_process_state *cps); Loading fs/nfs/callback_proc.c +7 −0 Original line number Diff line number Diff line Loading @@ -661,3 +661,10 @@ __be32 nfs4_callback_notify_lock(void *argp, void *resp, return htonl(NFS4_OK); } #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 __be32 nfs4_callback_offload(void *args, void *dummy, struct cb_process_state *cps) { return 0; } #endif /* CONFIG_NFS_V4_2 */ fs/nfs/callback_xdr.c +79 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ #define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #define CB_OP_NOTIFY_LOCK_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 #define CB_OP_OFFLOAD_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #endif /* CONFIG_NFS_V4_2 */ #define NFSDBG_FACILITY NFSDBG_CALLBACK Loading Loading @@ -527,7 +530,72 @@ static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, } #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 static __be32 decode_write_response(struct xdr_stream *xdr, struct cb_offloadargs *args) { __be32 *p; /* skip the always zero field */ p = read_buf(xdr, 4); if (unlikely(!p)) goto out; p++; /* decode count, stable_how, verifier */ p = xdr_inline_decode(xdr, 8 + 4); if (unlikely(!p)) goto out; p = xdr_decode_hyper(p, &args->wr_count); args->wr_writeverf.committed = be32_to_cpup(p); p = xdr_inline_decode(xdr, NFS4_VERIFIER_SIZE); if (likely(p)) { memcpy(&args->wr_writeverf.verifier.data[0], p, NFS4_VERIFIER_SIZE); return 0; } out: return htonl(NFS4ERR_RESOURCE); } static __be32 decode_offload_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, void *data) { struct cb_offloadargs *args = data; __be32 *p; __be32 status; /* decode fh */ status = decode_fh(xdr, &args->coa_fh); if (unlikely(status != 0)) return status; /* decode stateid */ status = decode_stateid(xdr, &args->coa_stateid); if (unlikely(status != 0)) return status; /* decode status */ p = read_buf(xdr, 4); if (unlikely(!p)) goto out; args->error = ntohl(*p++); if (!args->error) { status = decode_write_response(xdr, args); if (unlikely(status != 0)) return status; } else { p = xdr_inline_decode(xdr, 8); if (unlikely(!p)) goto out; p = xdr_decode_hyper(p, &args->wr_count); } return 0; out: return htonl(NFS4ERR_RESOURCE); } #endif /* CONFIG_NFS_V4_2 */ static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) { if (unlikely(xdr_stream_encode_opaque(xdr, str, len) < 0)) Loading Loading @@ -773,7 +841,10 @@ preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op) if (status != htonl(NFS4ERR_OP_ILLEGAL)) return status; if (op_nr == OP_CB_OFFLOAD) if (op_nr == OP_CB_OFFLOAD) { *op = &callback_ops[op_nr]; return htonl(NFS_OK); } else return htonl(NFS4ERR_NOTSUPP); return htonl(NFS4ERR_OP_ILLEGAL); } Loading Loading @@ -974,6 +1045,13 @@ static struct callback_op callback_ops[] = { .res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ, }, #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 [OP_CB_OFFLOAD] = { .process_op = nfs4_callback_offload, .decode_args = decode_offload_args, .res_maxsize = CB_OP_OFFLOAD_RES_MAXSZ, }, #endif /* CONFIG_NFS_V4_2 */ }; /* Loading Loading
fs/nfs/callback.h +12 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,18 @@ struct cb_notify_lock_args { extern __be32 nfs4_callback_notify_lock(void *argp, void *resp, struct cb_process_state *cps); #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 struct cb_offloadargs { struct nfs_fh coa_fh; nfs4_stateid coa_stateid; uint32_t error; uint64_t wr_count; struct nfs_writeverf wr_writeverf; }; extern __be32 nfs4_callback_offload(void *args, void *dummy, struct cb_process_state *cps); #endif /* CONFIG_NFS_V4_2 */ extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); extern __be32 nfs4_callback_getattr(void *argp, void *resp, struct cb_process_state *cps); Loading
fs/nfs/callback_proc.c +7 −0 Original line number Diff line number Diff line Loading @@ -661,3 +661,10 @@ __be32 nfs4_callback_notify_lock(void *argp, void *resp, return htonl(NFS4_OK); } #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 __be32 nfs4_callback_offload(void *args, void *dummy, struct cb_process_state *cps) { return 0; } #endif /* CONFIG_NFS_V4_2 */
fs/nfs/callback_xdr.c +79 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,9 @@ #define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #define CB_OP_NOTIFY_LOCK_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 #define CB_OP_OFFLOAD_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #endif /* CONFIG_NFS_V4_2 */ #define NFSDBG_FACILITY NFSDBG_CALLBACK Loading Loading @@ -527,7 +530,72 @@ static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, } #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 static __be32 decode_write_response(struct xdr_stream *xdr, struct cb_offloadargs *args) { __be32 *p; /* skip the always zero field */ p = read_buf(xdr, 4); if (unlikely(!p)) goto out; p++; /* decode count, stable_how, verifier */ p = xdr_inline_decode(xdr, 8 + 4); if (unlikely(!p)) goto out; p = xdr_decode_hyper(p, &args->wr_count); args->wr_writeverf.committed = be32_to_cpup(p); p = xdr_inline_decode(xdr, NFS4_VERIFIER_SIZE); if (likely(p)) { memcpy(&args->wr_writeverf.verifier.data[0], p, NFS4_VERIFIER_SIZE); return 0; } out: return htonl(NFS4ERR_RESOURCE); } static __be32 decode_offload_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, void *data) { struct cb_offloadargs *args = data; __be32 *p; __be32 status; /* decode fh */ status = decode_fh(xdr, &args->coa_fh); if (unlikely(status != 0)) return status; /* decode stateid */ status = decode_stateid(xdr, &args->coa_stateid); if (unlikely(status != 0)) return status; /* decode status */ p = read_buf(xdr, 4); if (unlikely(!p)) goto out; args->error = ntohl(*p++); if (!args->error) { status = decode_write_response(xdr, args); if (unlikely(status != 0)) return status; } else { p = xdr_inline_decode(xdr, 8); if (unlikely(!p)) goto out; p = xdr_decode_hyper(p, &args->wr_count); } return 0; out: return htonl(NFS4ERR_RESOURCE); } #endif /* CONFIG_NFS_V4_2 */ static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) { if (unlikely(xdr_stream_encode_opaque(xdr, str, len) < 0)) Loading Loading @@ -773,7 +841,10 @@ preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op) if (status != htonl(NFS4ERR_OP_ILLEGAL)) return status; if (op_nr == OP_CB_OFFLOAD) if (op_nr == OP_CB_OFFLOAD) { *op = &callback_ops[op_nr]; return htonl(NFS_OK); } else return htonl(NFS4ERR_NOTSUPP); return htonl(NFS4ERR_OP_ILLEGAL); } Loading Loading @@ -974,6 +1045,13 @@ static struct callback_op callback_ops[] = { .res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ, }, #endif /* CONFIG_NFS_V4_1 */ #ifdef CONFIG_NFS_V4_2 [OP_CB_OFFLOAD] = { .process_op = nfs4_callback_offload, .decode_args = decode_offload_args, .res_maxsize = CB_OP_OFFLOAD_RES_MAXSZ, }, #endif /* CONFIG_NFS_V4_2 */ }; /* Loading