1 /* 2 * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com> 3 */ 4 #ifndef __LINUX_FS_NFS_NFS4_2XDR_H 5 #define __LINUX_FS_NFS_NFS4_2XDR_H 6 7 #define encode_seek_maxsz (op_encode_hdr_maxsz + \ 8 encode_stateid_maxsz + \ 9 2 /* offset */ + \ 10 1 /* whence */) 11 #define decode_seek_maxsz (op_decode_hdr_maxsz + \ 12 1 /* eof */ + \ 13 1 /* whence */ + \ 14 2 /* offset */ + \ 15 2 /* length */) 16 17 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 18 encode_putfh_maxsz + \ 19 encode_seek_maxsz) 20 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ 21 decode_putfh_maxsz + \ 22 decode_seek_maxsz) 23 24 25 static void encode_seek(struct xdr_stream *xdr, 26 struct nfs42_seek_args *args, 27 struct compound_hdr *hdr) 28 { 29 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); 30 encode_nfs4_stateid(xdr, &args->sa_stateid); 31 encode_uint64(xdr, args->sa_offset); 32 encode_uint32(xdr, args->sa_what); 33 } 34 35 /* 36 * Encode SEEK request 37 */ 38 static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 39 struct xdr_stream *xdr, 40 struct nfs42_seek_args *args) 41 { 42 struct compound_hdr hdr = { 43 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 44 }; 45 46 encode_compound_hdr(xdr, req, &hdr); 47 encode_sequence(xdr, &args->seq_args, &hdr); 48 encode_putfh(xdr, args->sa_fh, &hdr); 49 encode_seek(xdr, args, &hdr); 50 encode_nops(&hdr); 51 } 52 53 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 54 { 55 int status; 56 __be32 *p; 57 58 status = decode_op_hdr(xdr, OP_SEEK); 59 if (status) 60 return status; 61 62 p = xdr_inline_decode(xdr, 4 + 8); 63 if (unlikely(!p)) 64 goto out_overflow; 65 66 res->sr_eof = be32_to_cpup(p++); 67 p = xdr_decode_hyper(p, &res->sr_offset); 68 return 0; 69 70 out_overflow: 71 print_overflow_msg(__func__, xdr); 72 return -EIO; 73 } 74 75 /* 76 * Decode SEEK request 77 */ 78 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 79 struct xdr_stream *xdr, 80 struct nfs42_seek_res *res) 81 { 82 struct compound_hdr hdr; 83 int status; 84 85 status = decode_compound_hdr(xdr, &hdr); 86 if (status) 87 goto out; 88 status = decode_sequence(xdr, &res->seq_res, rqstp); 89 if (status) 90 goto out; 91 status = decode_putfh(xdr); 92 if (status) 93 goto out; 94 status = decode_seek(xdr, res); 95 out: 96 return status; 97 } 98 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ 99