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 #include "nfs42.h" 8 9 #define encode_fallocate_maxsz (encode_stateid_maxsz + \ 10 2 /* offset */ + \ 11 2 /* length */) 12 #define encode_allocate_maxsz (op_encode_hdr_maxsz + \ 13 encode_fallocate_maxsz) 14 #define decode_allocate_maxsz (op_decode_hdr_maxsz) 15 #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \ 16 encode_fallocate_maxsz) 17 #define decode_deallocate_maxsz (op_decode_hdr_maxsz) 18 #define encode_seek_maxsz (op_encode_hdr_maxsz + \ 19 encode_stateid_maxsz + \ 20 2 /* offset */ + \ 21 1 /* whence */) 22 #define decode_seek_maxsz (op_decode_hdr_maxsz + \ 23 1 /* eof */ + \ 24 1 /* whence */ + \ 25 2 /* offset */ + \ 26 2 /* length */) 27 #define encode_io_info_maxsz 4 28 #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \ 29 2 /* offset */ + \ 30 2 /* length */ + \ 31 encode_stateid_maxsz + \ 32 encode_io_info_maxsz + \ 33 encode_io_info_maxsz + \ 34 1 /* opaque devaddr4 length */ + \ 35 XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE)) 36 #define decode_layoutstats_maxsz (op_decode_hdr_maxsz) 37 38 #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \ 39 encode_putfh_maxsz + \ 40 encode_allocate_maxsz + \ 41 encode_getattr_maxsz) 42 #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \ 43 decode_putfh_maxsz + \ 44 decode_allocate_maxsz + \ 45 decode_getattr_maxsz) 46 #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \ 47 encode_putfh_maxsz + \ 48 encode_deallocate_maxsz + \ 49 encode_getattr_maxsz) 50 #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \ 51 decode_putfh_maxsz + \ 52 decode_deallocate_maxsz + \ 53 decode_getattr_maxsz) 54 #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \ 55 encode_putfh_maxsz + \ 56 encode_seek_maxsz) 57 #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \ 58 decode_putfh_maxsz + \ 59 decode_seek_maxsz) 60 #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \ 61 encode_sequence_maxsz + \ 62 encode_putfh_maxsz + \ 63 PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz) 64 #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \ 65 decode_sequence_maxsz + \ 66 decode_putfh_maxsz + \ 67 PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz) 68 69 70 static void encode_fallocate(struct xdr_stream *xdr, 71 struct nfs42_falloc_args *args) 72 { 73 encode_nfs4_stateid(xdr, &args->falloc_stateid); 74 encode_uint64(xdr, args->falloc_offset); 75 encode_uint64(xdr, args->falloc_length); 76 } 77 78 static void encode_allocate(struct xdr_stream *xdr, 79 struct nfs42_falloc_args *args, 80 struct compound_hdr *hdr) 81 { 82 encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); 83 encode_fallocate(xdr, args); 84 } 85 86 static void encode_deallocate(struct xdr_stream *xdr, 87 struct nfs42_falloc_args *args, 88 struct compound_hdr *hdr) 89 { 90 encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); 91 encode_fallocate(xdr, args); 92 } 93 94 static void encode_seek(struct xdr_stream *xdr, 95 struct nfs42_seek_args *args, 96 struct compound_hdr *hdr) 97 { 98 encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); 99 encode_nfs4_stateid(xdr, &args->sa_stateid); 100 encode_uint64(xdr, args->sa_offset); 101 encode_uint32(xdr, args->sa_what); 102 } 103 104 static void encode_layoutstats(struct xdr_stream *xdr, 105 struct nfs42_layoutstat_args *args, 106 struct nfs42_layoutstat_devinfo *devinfo, 107 struct compound_hdr *hdr) 108 { 109 __be32 *p; 110 111 encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr); 112 p = reserve_space(xdr, 8 + 8); 113 p = xdr_encode_hyper(p, devinfo->offset); 114 p = xdr_encode_hyper(p, devinfo->length); 115 encode_nfs4_stateid(xdr, &args->stateid); 116 p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4); 117 p = xdr_encode_hyper(p, devinfo->read_count); 118 p = xdr_encode_hyper(p, devinfo->read_bytes); 119 p = xdr_encode_hyper(p, devinfo->write_count); 120 p = xdr_encode_hyper(p, devinfo->write_bytes); 121 p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data, 122 NFS4_DEVICEID4_SIZE); 123 /* Encode layoutupdate4 */ 124 *p++ = cpu_to_be32(devinfo->layout_type); 125 if (devinfo->layoutstats_encode != NULL) 126 devinfo->layoutstats_encode(xdr, args, devinfo); 127 else 128 encode_uint32(xdr, 0); 129 } 130 131 /* 132 * Encode ALLOCATE request 133 */ 134 static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, 135 struct xdr_stream *xdr, 136 struct nfs42_falloc_args *args) 137 { 138 struct compound_hdr hdr = { 139 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 140 }; 141 142 encode_compound_hdr(xdr, req, &hdr); 143 encode_sequence(xdr, &args->seq_args, &hdr); 144 encode_putfh(xdr, args->falloc_fh, &hdr); 145 encode_allocate(xdr, args, &hdr); 146 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 147 encode_nops(&hdr); 148 } 149 150 /* 151 * Encode DEALLOCATE request 152 */ 153 static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, 154 struct xdr_stream *xdr, 155 struct nfs42_falloc_args *args) 156 { 157 struct compound_hdr hdr = { 158 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 159 }; 160 161 encode_compound_hdr(xdr, req, &hdr); 162 encode_sequence(xdr, &args->seq_args, &hdr); 163 encode_putfh(xdr, args->falloc_fh, &hdr); 164 encode_deallocate(xdr, args, &hdr); 165 encode_getfattr(xdr, args->falloc_bitmask, &hdr); 166 encode_nops(&hdr); 167 } 168 169 /* 170 * Encode SEEK request 171 */ 172 static void nfs4_xdr_enc_seek(struct rpc_rqst *req, 173 struct xdr_stream *xdr, 174 struct nfs42_seek_args *args) 175 { 176 struct compound_hdr hdr = { 177 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 178 }; 179 180 encode_compound_hdr(xdr, req, &hdr); 181 encode_sequence(xdr, &args->seq_args, &hdr); 182 encode_putfh(xdr, args->sa_fh, &hdr); 183 encode_seek(xdr, args, &hdr); 184 encode_nops(&hdr); 185 } 186 187 /* 188 * Encode LAYOUTSTATS request 189 */ 190 static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, 191 struct xdr_stream *xdr, 192 struct nfs42_layoutstat_args *args) 193 { 194 int i; 195 196 struct compound_hdr hdr = { 197 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 198 }; 199 200 encode_compound_hdr(xdr, req, &hdr); 201 encode_sequence(xdr, &args->seq_args, &hdr); 202 encode_putfh(xdr, args->fh, &hdr); 203 WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 204 for (i = 0; i < args->num_dev; i++) 205 encode_layoutstats(xdr, args, &args->devinfo[i], &hdr); 206 encode_nops(&hdr); 207 } 208 209 static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 210 { 211 return decode_op_hdr(xdr, OP_ALLOCATE); 212 } 213 214 static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res) 215 { 216 return decode_op_hdr(xdr, OP_DEALLOCATE); 217 } 218 219 static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) 220 { 221 int status; 222 __be32 *p; 223 224 status = decode_op_hdr(xdr, OP_SEEK); 225 if (status) 226 return status; 227 228 p = xdr_inline_decode(xdr, 4 + 8); 229 if (unlikely(!p)) 230 goto out_overflow; 231 232 res->sr_eof = be32_to_cpup(p++); 233 p = xdr_decode_hyper(p, &res->sr_offset); 234 return 0; 235 236 out_overflow: 237 print_overflow_msg(__func__, xdr); 238 return -EIO; 239 } 240 241 static int decode_layoutstats(struct xdr_stream *xdr, 242 struct nfs42_layoutstat_res *res) 243 { 244 return decode_op_hdr(xdr, OP_LAYOUTSTATS); 245 } 246 247 /* 248 * Decode ALLOCATE request 249 */ 250 static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, 251 struct xdr_stream *xdr, 252 struct nfs42_falloc_res *res) 253 { 254 struct compound_hdr hdr; 255 int status; 256 257 status = decode_compound_hdr(xdr, &hdr); 258 if (status) 259 goto out; 260 status = decode_sequence(xdr, &res->seq_res, rqstp); 261 if (status) 262 goto out; 263 status = decode_putfh(xdr); 264 if (status) 265 goto out; 266 status = decode_allocate(xdr, res); 267 if (status) 268 goto out; 269 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 270 out: 271 return status; 272 } 273 274 /* 275 * Decode DEALLOCATE request 276 */ 277 static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, 278 struct xdr_stream *xdr, 279 struct nfs42_falloc_res *res) 280 { 281 struct compound_hdr hdr; 282 int status; 283 284 status = decode_compound_hdr(xdr, &hdr); 285 if (status) 286 goto out; 287 status = decode_sequence(xdr, &res->seq_res, rqstp); 288 if (status) 289 goto out; 290 status = decode_putfh(xdr); 291 if (status) 292 goto out; 293 status = decode_deallocate(xdr, res); 294 if (status) 295 goto out; 296 decode_getfattr(xdr, res->falloc_fattr, res->falloc_server); 297 out: 298 return status; 299 } 300 301 /* 302 * Decode SEEK request 303 */ 304 static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, 305 struct xdr_stream *xdr, 306 struct nfs42_seek_res *res) 307 { 308 struct compound_hdr hdr; 309 int status; 310 311 status = decode_compound_hdr(xdr, &hdr); 312 if (status) 313 goto out; 314 status = decode_sequence(xdr, &res->seq_res, rqstp); 315 if (status) 316 goto out; 317 status = decode_putfh(xdr); 318 if (status) 319 goto out; 320 status = decode_seek(xdr, res); 321 out: 322 return status; 323 } 324 325 /* 326 * Decode LAYOUTSTATS request 327 */ 328 static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, 329 struct xdr_stream *xdr, 330 struct nfs42_layoutstat_res *res) 331 { 332 struct compound_hdr hdr; 333 int status, i; 334 335 status = decode_compound_hdr(xdr, &hdr); 336 if (status) 337 goto out; 338 status = decode_sequence(xdr, &res->seq_res, rqstp); 339 if (status) 340 goto out; 341 status = decode_putfh(xdr); 342 if (status) 343 goto out; 344 WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV); 345 for (i = 0; i < res->num_dev; i++) { 346 status = decode_layoutstats(xdr, res); 347 if (status) 348 goto out; 349 } 350 out: 351 res->rpc_status = status; 352 return status; 353 } 354 355 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */ 356