/* * Encode ALLOCATE request */ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_falloc_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->falloc_fh, &hdr); encode_allocate(xdr, args, &hdr); encode_getfattr(xdr, args->falloc_bitmask, &hdr); encode_nops(&hdr); } /* * Encode DEALLOCATE request */ static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_falloc_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->falloc_fh, &hdr); encode_deallocate(xdr, args, &hdr); encode_getfattr(xdr, args->falloc_bitmask, &hdr); encode_nops(&hdr); } /* * Encode SEEK request */ static void nfs4_xdr_enc_seek(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_seek_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->sa_fh, &hdr); encode_seek(xdr, args, &hdr); encode_nops(&hdr); } /* * Encode LAYOUTSTATS request */ static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_layoutstat_args *args) { int i; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->fh, &hdr); WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); for (i = 0; i < args->num_dev; i++) encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); encode_nops(&hdr); } static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) { return decode_op_hdr(xdr, OP_ALLOCATE); } static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) { return decode_op_hdr(xdr, OP_DEALLOCATE); } static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) { int status; __be32 *p; status = decode_op_hdr(xdr, OP_SEEK); if (status) return status; p = xdr_inline_decode(xdr, 4 + 8); if (unlikely(!p)) goto out_overflow; res->sr_eof = be32_to_cpup(p++); p = xdr_decode_hyper(p, &res->sr_offset); return 0; out_overflow: print_overflow_msg(__func__, xdr); return -EIO; } static int decode_layoutstats(struct xdr_stream *xdr) { return decode_op_hdr(xdr, OP_LAYOUTSTATS); } /* * Decode ALLOCATE request */ static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_falloc_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_allocate(xdr, res); if (status) goto out; decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); out: return status; } /* * Decode DEALLOCATE request */ static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_falloc_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_deallocate(xdr, res); if (status) goto out; decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); out: return status; } /* * Decode SEEK request */ static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_seek_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_seek(xdr, res); out: return status; } /* * Decode LAYOUTSTATS request */ static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_layoutstat_res *res) { struct compound_hdr hdr; int status, i; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); for (i = 0; i < res->num_dev; i++) { status = decode_layoutstats(xdr); if (status) goto out; } out: res->rpc_status = status; return status; }
/* * Encode ALLOCATE request */ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_falloc_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->falloc_fh, &hdr); encode_allocate(xdr, args, &hdr); encode_getfattr(xdr, args->falloc_bitmask, &hdr); encode_nops(&hdr); } /* * Encode COPY request */ static void nfs4_xdr_enc_copy(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_copy_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->src_fh, &hdr); encode_savefh(xdr, &hdr); encode_putfh(xdr, args->dst_fh, &hdr); encode_copy(xdr, args, &hdr); encode_nops(&hdr); } /* * Encode DEALLOCATE request */ static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_falloc_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->falloc_fh, &hdr); encode_deallocate(xdr, args, &hdr); encode_getfattr(xdr, args->falloc_bitmask, &hdr); encode_nops(&hdr); } /* * Encode SEEK request */ static void nfs4_xdr_enc_seek(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_seek_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->sa_fh, &hdr); encode_seek(xdr, args, &hdr); encode_nops(&hdr); } /* * Encode LAYOUTSTATS request */ static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_layoutstat_args *args) { int i; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->fh, &hdr); WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); for (i = 0; i < args->num_dev; i++) encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); encode_nops(&hdr); } /* * Encode CLONE request */ static void nfs4_xdr_enc_clone(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs42_clone_args *args) { struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->src_fh, &hdr); encode_savefh(xdr, &hdr); encode_putfh(xdr, args->dst_fh, &hdr); encode_clone(xdr, args, &hdr); encode_getfattr(xdr, args->dst_bitmask, &hdr); encode_nops(&hdr); } static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) { return decode_op_hdr(xdr, OP_ALLOCATE); } static int decode_write_response(struct xdr_stream *xdr, struct nfs42_write_res *res) { __be32 *p; p = xdr_inline_decode(xdr, 4 + 8 + 4); if (unlikely(!p)) goto out_overflow; /* * We never use asynchronous mode, so warn if a server returns * a stateid. */ if (unlikely(*p != 0)) { pr_err_once("%s: server has set unrequested " "asynchronous mode\n", __func__); return -EREMOTEIO; } p++; p = xdr_decode_hyper(p, &res->count); res->verifier.committed = be32_to_cpup(p); return decode_verifier(xdr, &res->verifier.verifier); out_overflow: print_overflow_msg(__func__, xdr); return -EIO; } static int decode_copy_requirements(struct xdr_stream *xdr, struct nfs42_copy_res *res) { __be32 *p; p = xdr_inline_decode(xdr, 4 + 4); if (unlikely(!p)) goto out_overflow; res->consecutive = be32_to_cpup(p++); res->synchronous = be32_to_cpup(p++); return 0; out_overflow: print_overflow_msg(__func__, xdr); return -EIO; } static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) { int status; status = decode_op_hdr(xdr, OP_COPY); if (status == NFS4ERR_OFFLOAD_NO_REQS) { status = decode_copy_requirements(xdr, res); if (status) return status; return NFS4ERR_OFFLOAD_NO_REQS; } else if (status) return status; status = decode_write_response(xdr, &res->write_res); if (status) return status; return decode_copy_requirements(xdr, res); } static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) { return decode_op_hdr(xdr, OP_DEALLOCATE); } static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) { int status; __be32 *p; status = decode_op_hdr(xdr, OP_SEEK); if (status) return status; p = xdr_inline_decode(xdr, 4 + 8); if (unlikely(!p)) goto out_overflow; res->sr_eof = be32_to_cpup(p++); p = xdr_decode_hyper(p, &res->sr_offset); return 0; out_overflow: print_overflow_msg(__func__, xdr); return -EIO; } static int decode_layoutstats(struct xdr_stream *xdr) { return decode_op_hdr(xdr, OP_LAYOUTSTATS); } static int decode_clone(struct xdr_stream *xdr) { return decode_op_hdr(xdr, OP_CLONE); } /* * Decode ALLOCATE request */ static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_falloc_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_allocate(xdr, res); if (status) goto out; decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); out: return status; } /* * Decode COPY response */ static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_copy_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_savefh(xdr); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_copy(xdr, res); out: return status; } /* * Decode DEALLOCATE request */ static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_falloc_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_deallocate(xdr, res); if (status) goto out; decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); out: return status; } /* * Decode SEEK request */ static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_seek_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_seek(xdr, res); out: return status; } /* * Decode LAYOUTSTATS request */ static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_layoutstat_res *res) { struct compound_hdr hdr; int status, i; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); for (i = 0; i < res->num_dev; i++) { status = decode_layoutstats(xdr); if (status) goto out; } out: res->rpc_status = status; return status; } /* * Decode CLONE request */ static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs42_clone_res *res) { struct compound_hdr hdr; int status; status = decode_compound_hdr(xdr, &hdr); if (status) goto out; status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_savefh(xdr); if (status) goto out; status = decode_putfh(xdr); if (status) goto out; status = decode_clone(xdr); if (status) goto out; status = decode_getfattr(xdr, res->dst_fattr, res->server); out: res->rpc_status = status; return status; }