nfs42xdr.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2014 Anna Schumaker <Anna.Schumaker@Netapp.com>
  4. */
  5. #ifndef __LINUX_FS_NFS_NFS4_2XDR_H
  6. #define __LINUX_FS_NFS_NFS4_2XDR_H
  7. #include "nfs42.h"
  8. #define encode_fallocate_maxsz (encode_stateid_maxsz + \
  9. 2 /* offset */ + \
  10. 2 /* length */)
  11. #define NFS42_WRITE_RES_SIZE (1 /* wr_callback_id size */ +\
  12. XDR_QUADLEN(NFS4_STATEID_SIZE) + \
  13. 2 /* wr_count */ + \
  14. 1 /* wr_committed */ + \
  15. XDR_QUADLEN(NFS4_VERIFIER_SIZE))
  16. #define encode_allocate_maxsz (op_encode_hdr_maxsz + \
  17. encode_fallocate_maxsz)
  18. #define decode_allocate_maxsz (op_decode_hdr_maxsz)
  19. #define encode_copy_maxsz (op_encode_hdr_maxsz + \
  20. XDR_QUADLEN(NFS4_STATEID_SIZE) + \
  21. XDR_QUADLEN(NFS4_STATEID_SIZE) + \
  22. 2 + 2 + 2 + 1 + 1 + 1)
  23. #define decode_copy_maxsz (op_decode_hdr_maxsz + \
  24. NFS42_WRITE_RES_SIZE + \
  25. 1 /* cr_consecutive */ + \
  26. 1 /* cr_synchronous */)
  27. #define encode_offload_cancel_maxsz (op_encode_hdr_maxsz + \
  28. XDR_QUADLEN(NFS4_STATEID_SIZE))
  29. #define decode_offload_cancel_maxsz (op_decode_hdr_maxsz)
  30. #define encode_deallocate_maxsz (op_encode_hdr_maxsz + \
  31. encode_fallocate_maxsz)
  32. #define decode_deallocate_maxsz (op_decode_hdr_maxsz)
  33. #define encode_seek_maxsz (op_encode_hdr_maxsz + \
  34. encode_stateid_maxsz + \
  35. 2 /* offset */ + \
  36. 1 /* whence */)
  37. #define decode_seek_maxsz (op_decode_hdr_maxsz + \
  38. 1 /* eof */ + \
  39. 1 /* whence */ + \
  40. 2 /* offset */ + \
  41. 2 /* length */)
  42. #define encode_io_info_maxsz 4
  43. #define encode_layoutstats_maxsz (op_decode_hdr_maxsz + \
  44. 2 /* offset */ + \
  45. 2 /* length */ + \
  46. encode_stateid_maxsz + \
  47. encode_io_info_maxsz + \
  48. encode_io_info_maxsz + \
  49. 1 /* opaque devaddr4 length */ + \
  50. XDR_QUADLEN(PNFS_LAYOUTSTATS_MAXSIZE))
  51. #define decode_layoutstats_maxsz (op_decode_hdr_maxsz)
  52. #define encode_clone_maxsz (encode_stateid_maxsz + \
  53. encode_stateid_maxsz + \
  54. 2 /* src offset */ + \
  55. 2 /* dst offset */ + \
  56. 2 /* count */)
  57. #define decode_clone_maxsz (op_decode_hdr_maxsz)
  58. #define NFS4_enc_allocate_sz (compound_encode_hdr_maxsz + \
  59. encode_sequence_maxsz + \
  60. encode_putfh_maxsz + \
  61. encode_allocate_maxsz + \
  62. encode_getattr_maxsz)
  63. #define NFS4_dec_allocate_sz (compound_decode_hdr_maxsz + \
  64. decode_sequence_maxsz + \
  65. decode_putfh_maxsz + \
  66. decode_allocate_maxsz + \
  67. decode_getattr_maxsz)
  68. #define NFS4_enc_copy_sz (compound_encode_hdr_maxsz + \
  69. encode_sequence_maxsz + \
  70. encode_putfh_maxsz + \
  71. encode_savefh_maxsz + \
  72. encode_putfh_maxsz + \
  73. encode_copy_maxsz + \
  74. encode_commit_maxsz)
  75. #define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
  76. decode_sequence_maxsz + \
  77. decode_putfh_maxsz + \
  78. decode_savefh_maxsz + \
  79. decode_putfh_maxsz + \
  80. decode_copy_maxsz + \
  81. decode_commit_maxsz)
  82. #define NFS4_enc_offload_cancel_sz (compound_encode_hdr_maxsz + \
  83. encode_sequence_maxsz + \
  84. encode_putfh_maxsz + \
  85. encode_offload_cancel_maxsz)
  86. #define NFS4_dec_offload_cancel_sz (compound_decode_hdr_maxsz + \
  87. decode_sequence_maxsz + \
  88. decode_putfh_maxsz + \
  89. decode_offload_cancel_maxsz)
  90. #define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
  91. encode_sequence_maxsz + \
  92. encode_putfh_maxsz + \
  93. encode_deallocate_maxsz + \
  94. encode_getattr_maxsz)
  95. #define NFS4_dec_deallocate_sz (compound_decode_hdr_maxsz + \
  96. decode_sequence_maxsz + \
  97. decode_putfh_maxsz + \
  98. decode_deallocate_maxsz + \
  99. decode_getattr_maxsz)
  100. #define NFS4_enc_seek_sz (compound_encode_hdr_maxsz + \
  101. encode_sequence_maxsz + \
  102. encode_putfh_maxsz + \
  103. encode_seek_maxsz)
  104. #define NFS4_dec_seek_sz (compound_decode_hdr_maxsz + \
  105. decode_sequence_maxsz + \
  106. decode_putfh_maxsz + \
  107. decode_seek_maxsz)
  108. #define NFS4_enc_layoutstats_sz (compound_encode_hdr_maxsz + \
  109. encode_sequence_maxsz + \
  110. encode_putfh_maxsz + \
  111. PNFS_LAYOUTSTATS_MAXDEV * encode_layoutstats_maxsz)
  112. #define NFS4_dec_layoutstats_sz (compound_decode_hdr_maxsz + \
  113. decode_sequence_maxsz + \
  114. decode_putfh_maxsz + \
  115. PNFS_LAYOUTSTATS_MAXDEV * decode_layoutstats_maxsz)
  116. #define NFS4_enc_clone_sz (compound_encode_hdr_maxsz + \
  117. encode_sequence_maxsz + \
  118. encode_putfh_maxsz + \
  119. encode_savefh_maxsz + \
  120. encode_putfh_maxsz + \
  121. encode_clone_maxsz + \
  122. encode_getattr_maxsz)
  123. #define NFS4_dec_clone_sz (compound_decode_hdr_maxsz + \
  124. decode_sequence_maxsz + \
  125. decode_putfh_maxsz + \
  126. decode_savefh_maxsz + \
  127. decode_putfh_maxsz + \
  128. decode_clone_maxsz + \
  129. decode_getattr_maxsz)
  130. static void encode_fallocate(struct xdr_stream *xdr,
  131. const struct nfs42_falloc_args *args)
  132. {
  133. encode_nfs4_stateid(xdr, &args->falloc_stateid);
  134. encode_uint64(xdr, args->falloc_offset);
  135. encode_uint64(xdr, args->falloc_length);
  136. }
  137. static void encode_allocate(struct xdr_stream *xdr,
  138. const struct nfs42_falloc_args *args,
  139. struct compound_hdr *hdr)
  140. {
  141. encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr);
  142. encode_fallocate(xdr, args);
  143. }
  144. static void encode_copy(struct xdr_stream *xdr,
  145. const struct nfs42_copy_args *args,
  146. struct compound_hdr *hdr)
  147. {
  148. encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr);
  149. encode_nfs4_stateid(xdr, &args->src_stateid);
  150. encode_nfs4_stateid(xdr, &args->dst_stateid);
  151. encode_uint64(xdr, args->src_pos);
  152. encode_uint64(xdr, args->dst_pos);
  153. encode_uint64(xdr, args->count);
  154. encode_uint32(xdr, 1); /* consecutive = true */
  155. encode_uint32(xdr, args->sync);
  156. encode_uint32(xdr, 0); /* src server list */
  157. }
  158. static void encode_offload_cancel(struct xdr_stream *xdr,
  159. const struct nfs42_offload_status_args *args,
  160. struct compound_hdr *hdr)
  161. {
  162. encode_op_hdr(xdr, OP_OFFLOAD_CANCEL, decode_offload_cancel_maxsz, hdr);
  163. encode_nfs4_stateid(xdr, &args->osa_stateid);
  164. }
  165. static void encode_deallocate(struct xdr_stream *xdr,
  166. const struct nfs42_falloc_args *args,
  167. struct compound_hdr *hdr)
  168. {
  169. encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr);
  170. encode_fallocate(xdr, args);
  171. }
  172. static void encode_seek(struct xdr_stream *xdr,
  173. const struct nfs42_seek_args *args,
  174. struct compound_hdr *hdr)
  175. {
  176. encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr);
  177. encode_nfs4_stateid(xdr, &args->sa_stateid);
  178. encode_uint64(xdr, args->sa_offset);
  179. encode_uint32(xdr, args->sa_what);
  180. }
  181. static void encode_layoutstats(struct xdr_stream *xdr,
  182. const struct nfs42_layoutstat_args *args,
  183. struct nfs42_layoutstat_devinfo *devinfo,
  184. struct compound_hdr *hdr)
  185. {
  186. __be32 *p;
  187. encode_op_hdr(xdr, OP_LAYOUTSTATS, decode_layoutstats_maxsz, hdr);
  188. p = reserve_space(xdr, 8 + 8);
  189. p = xdr_encode_hyper(p, devinfo->offset);
  190. p = xdr_encode_hyper(p, devinfo->length);
  191. encode_nfs4_stateid(xdr, &args->stateid);
  192. p = reserve_space(xdr, 4*8 + NFS4_DEVICEID4_SIZE + 4);
  193. p = xdr_encode_hyper(p, devinfo->read_count);
  194. p = xdr_encode_hyper(p, devinfo->read_bytes);
  195. p = xdr_encode_hyper(p, devinfo->write_count);
  196. p = xdr_encode_hyper(p, devinfo->write_bytes);
  197. p = xdr_encode_opaque_fixed(p, devinfo->dev_id.data,
  198. NFS4_DEVICEID4_SIZE);
  199. /* Encode layoutupdate4 */
  200. *p++ = cpu_to_be32(devinfo->layout_type);
  201. if (devinfo->ld_private.ops)
  202. devinfo->ld_private.ops->encode(xdr, args,
  203. &devinfo->ld_private);
  204. else
  205. encode_uint32(xdr, 0);
  206. }
  207. static void encode_clone(struct xdr_stream *xdr,
  208. const struct nfs42_clone_args *args,
  209. struct compound_hdr *hdr)
  210. {
  211. __be32 *p;
  212. encode_op_hdr(xdr, OP_CLONE, decode_clone_maxsz, hdr);
  213. encode_nfs4_stateid(xdr, &args->src_stateid);
  214. encode_nfs4_stateid(xdr, &args->dst_stateid);
  215. p = reserve_space(xdr, 3*8);
  216. p = xdr_encode_hyper(p, args->src_offset);
  217. p = xdr_encode_hyper(p, args->dst_offset);
  218. xdr_encode_hyper(p, args->count);
  219. }
  220. /*
  221. * Encode ALLOCATE request
  222. */
  223. static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
  224. struct xdr_stream *xdr,
  225. const void *data)
  226. {
  227. const struct nfs42_falloc_args *args = data;
  228. struct compound_hdr hdr = {
  229. .minorversion = nfs4_xdr_minorversion(&args->seq_args),
  230. };
  231. encode_compound_hdr(xdr, req, &hdr);
  232. encode_sequence(xdr, &args->seq_args, &hdr);
  233. encode_putfh(xdr, args->falloc_fh, &hdr);
  234. encode_allocate(xdr, args, &hdr);
  235. encode_getfattr(xdr, args->falloc_bitmask, &hdr);
  236. encode_nops(&hdr);
  237. }
  238. static void encode_copy_commit(struct xdr_stream *xdr,
  239. const struct nfs42_copy_args *args,
  240. struct compound_hdr *hdr)
  241. {
  242. __be32 *p;
  243. encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
  244. p = reserve_space(xdr, 12);
  245. p = xdr_encode_hyper(p, args->dst_pos);
  246. *p = cpu_to_be32(args->count);
  247. }
  248. /*
  249. * Encode COPY request
  250. */
  251. static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
  252. struct xdr_stream *xdr,
  253. const void *data)
  254. {
  255. const struct nfs42_copy_args *args = data;
  256. struct compound_hdr hdr = {
  257. .minorversion = nfs4_xdr_minorversion(&args->seq_args),
  258. };
  259. encode_compound_hdr(xdr, req, &hdr);
  260. encode_sequence(xdr, &args->seq_args, &hdr);
  261. encode_putfh(xdr, args->src_fh, &hdr);
  262. encode_savefh(xdr, &hdr);
  263. encode_putfh(xdr, args->dst_fh, &hdr);
  264. encode_copy(xdr, args, &hdr);
  265. if (args->sync)
  266. encode_copy_commit(xdr, args, &hdr);
  267. encode_nops(&hdr);
  268. }
  269. /*
  270. * Encode OFFLOAD_CANEL request
  271. */
  272. static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
  273. struct xdr_stream *xdr,
  274. const void *data)
  275. {
  276. const struct nfs42_offload_status_args *args = data;
  277. struct compound_hdr hdr = {
  278. .minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
  279. };
  280. encode_compound_hdr(xdr, req, &hdr);
  281. encode_sequence(xdr, &args->osa_seq_args, &hdr);
  282. encode_putfh(xdr, args->osa_src_fh, &hdr);
  283. encode_offload_cancel(xdr, args, &hdr);
  284. encode_nops(&hdr);
  285. }
  286. /*
  287. * Encode DEALLOCATE request
  288. */
  289. static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req,
  290. struct xdr_stream *xdr,
  291. const void *data)
  292. {
  293. const struct nfs42_falloc_args *args = data;
  294. struct compound_hdr hdr = {
  295. .minorversion = nfs4_xdr_minorversion(&args->seq_args),
  296. };
  297. encode_compound_hdr(xdr, req, &hdr);
  298. encode_sequence(xdr, &args->seq_args, &hdr);
  299. encode_putfh(xdr, args->falloc_fh, &hdr);
  300. encode_deallocate(xdr, args, &hdr);
  301. encode_getfattr(xdr, args->falloc_bitmask, &hdr);
  302. encode_nops(&hdr);
  303. }
  304. /*
  305. * Encode SEEK request
  306. */
  307. static void nfs4_xdr_enc_seek(struct rpc_rqst *req,
  308. struct xdr_stream *xdr,
  309. const void *data)
  310. {
  311. const struct nfs42_seek_args *args = data;
  312. struct compound_hdr hdr = {
  313. .minorversion = nfs4_xdr_minorversion(&args->seq_args),
  314. };
  315. encode_compound_hdr(xdr, req, &hdr);
  316. encode_sequence(xdr, &args->seq_args, &hdr);
  317. encode_putfh(xdr, args->sa_fh, &hdr);
  318. encode_seek(xdr, args, &hdr);
  319. encode_nops(&hdr);
  320. }
  321. /*
  322. * Encode LAYOUTSTATS request
  323. */
  324. static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req,
  325. struct xdr_stream *xdr,
  326. const void *data)
  327. {
  328. const struct nfs42_layoutstat_args *args = data;
  329. int i;
  330. struct compound_hdr hdr = {
  331. .minorversion = nfs4_xdr_minorversion(&args->seq_args),
  332. };
  333. encode_compound_hdr(xdr, req, &hdr);
  334. encode_sequence(xdr, &args->seq_args, &hdr);
  335. encode_putfh(xdr, args->fh, &hdr);
  336. WARN_ON(args->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
  337. for (i = 0; i < args->num_dev; i++)
  338. encode_layoutstats(xdr, args, &args->devinfo[i], &hdr);
  339. encode_nops(&hdr);
  340. }
  341. /*
  342. * Encode CLONE request
  343. */
  344. static void nfs4_xdr_enc_clone(struct rpc_rqst *req,
  345. struct xdr_stream *xdr,
  346. const void *data)
  347. {
  348. const struct nfs42_clone_args *args = data;
  349. struct compound_hdr hdr = {
  350. .minorversion = nfs4_xdr_minorversion(&args->seq_args),
  351. };
  352. encode_compound_hdr(xdr, req, &hdr);
  353. encode_sequence(xdr, &args->seq_args, &hdr);
  354. encode_putfh(xdr, args->src_fh, &hdr);
  355. encode_savefh(xdr, &hdr);
  356. encode_putfh(xdr, args->dst_fh, &hdr);
  357. encode_clone(xdr, args, &hdr);
  358. encode_getfattr(xdr, args->dst_bitmask, &hdr);
  359. encode_nops(&hdr);
  360. }
  361. static int decode_allocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
  362. {
  363. return decode_op_hdr(xdr, OP_ALLOCATE);
  364. }
  365. static int decode_write_response(struct xdr_stream *xdr,
  366. struct nfs42_write_res *res)
  367. {
  368. __be32 *p;
  369. int status, count;
  370. p = xdr_inline_decode(xdr, 4);
  371. if (unlikely(!p))
  372. goto out_overflow;
  373. count = be32_to_cpup(p);
  374. if (count > 1)
  375. return -EREMOTEIO;
  376. else if (count == 1) {
  377. status = decode_opaque_fixed(xdr, &res->stateid,
  378. NFS4_STATEID_SIZE);
  379. if (unlikely(status))
  380. goto out_overflow;
  381. }
  382. p = xdr_inline_decode(xdr, 8 + 4);
  383. if (unlikely(!p))
  384. goto out_overflow;
  385. p = xdr_decode_hyper(p, &res->count);
  386. res->verifier.committed = be32_to_cpup(p);
  387. return decode_verifier(xdr, &res->verifier.verifier);
  388. out_overflow:
  389. print_overflow_msg(__func__, xdr);
  390. return -EIO;
  391. }
  392. static int decode_copy_requirements(struct xdr_stream *xdr,
  393. struct nfs42_copy_res *res) {
  394. __be32 *p;
  395. p = xdr_inline_decode(xdr, 4 + 4);
  396. if (unlikely(!p))
  397. goto out_overflow;
  398. res->consecutive = be32_to_cpup(p++);
  399. res->synchronous = be32_to_cpup(p++);
  400. return 0;
  401. out_overflow:
  402. print_overflow_msg(__func__, xdr);
  403. return -EIO;
  404. }
  405. static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res)
  406. {
  407. int status;
  408. status = decode_op_hdr(xdr, OP_COPY);
  409. if (status == NFS4ERR_OFFLOAD_NO_REQS) {
  410. status = decode_copy_requirements(xdr, res);
  411. if (status)
  412. return status;
  413. return NFS4ERR_OFFLOAD_NO_REQS;
  414. } else if (status)
  415. return status;
  416. status = decode_write_response(xdr, &res->write_res);
  417. if (status)
  418. return status;
  419. return decode_copy_requirements(xdr, res);
  420. }
  421. static int decode_offload_cancel(struct xdr_stream *xdr,
  422. struct nfs42_offload_status_res *res)
  423. {
  424. return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
  425. }
  426. static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *res)
  427. {
  428. return decode_op_hdr(xdr, OP_DEALLOCATE);
  429. }
  430. static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res)
  431. {
  432. int status;
  433. __be32 *p;
  434. status = decode_op_hdr(xdr, OP_SEEK);
  435. if (status)
  436. return status;
  437. p = xdr_inline_decode(xdr, 4 + 8);
  438. if (unlikely(!p))
  439. goto out_overflow;
  440. res->sr_eof = be32_to_cpup(p++);
  441. p = xdr_decode_hyper(p, &res->sr_offset);
  442. return 0;
  443. out_overflow:
  444. print_overflow_msg(__func__, xdr);
  445. return -EIO;
  446. }
  447. static int decode_layoutstats(struct xdr_stream *xdr)
  448. {
  449. return decode_op_hdr(xdr, OP_LAYOUTSTATS);
  450. }
  451. static int decode_clone(struct xdr_stream *xdr)
  452. {
  453. return decode_op_hdr(xdr, OP_CLONE);
  454. }
  455. /*
  456. * Decode ALLOCATE request
  457. */
  458. static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp,
  459. struct xdr_stream *xdr,
  460. void *data)
  461. {
  462. struct nfs42_falloc_res *res = data;
  463. struct compound_hdr hdr;
  464. int status;
  465. status = decode_compound_hdr(xdr, &hdr);
  466. if (status)
  467. goto out;
  468. status = decode_sequence(xdr, &res->seq_res, rqstp);
  469. if (status)
  470. goto out;
  471. status = decode_putfh(xdr);
  472. if (status)
  473. goto out;
  474. status = decode_allocate(xdr, res);
  475. if (status)
  476. goto out;
  477. decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
  478. out:
  479. return status;
  480. }
  481. /*
  482. * Decode COPY response
  483. */
  484. static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
  485. struct xdr_stream *xdr,
  486. void *data)
  487. {
  488. struct nfs42_copy_res *res = data;
  489. struct compound_hdr hdr;
  490. int status;
  491. status = decode_compound_hdr(xdr, &hdr);
  492. if (status)
  493. goto out;
  494. status = decode_sequence(xdr, &res->seq_res, rqstp);
  495. if (status)
  496. goto out;
  497. status = decode_putfh(xdr);
  498. if (status)
  499. goto out;
  500. status = decode_savefh(xdr);
  501. if (status)
  502. goto out;
  503. status = decode_putfh(xdr);
  504. if (status)
  505. goto out;
  506. status = decode_copy(xdr, res);
  507. if (status)
  508. goto out;
  509. if (res->commit_res.verf)
  510. status = decode_commit(xdr, &res->commit_res);
  511. out:
  512. return status;
  513. }
  514. /*
  515. * Decode OFFLOAD_CANCEL response
  516. */
  517. static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
  518. struct xdr_stream *xdr,
  519. void *data)
  520. {
  521. struct nfs42_offload_status_res *res = data;
  522. struct compound_hdr hdr;
  523. int status;
  524. status = decode_compound_hdr(xdr, &hdr);
  525. if (status)
  526. goto out;
  527. status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
  528. if (status)
  529. goto out;
  530. status = decode_putfh(xdr);
  531. if (status)
  532. goto out;
  533. status = decode_offload_cancel(xdr, res);
  534. out:
  535. return status;
  536. }
  537. /*
  538. * Decode DEALLOCATE request
  539. */
  540. static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp,
  541. struct xdr_stream *xdr,
  542. void *data)
  543. {
  544. struct nfs42_falloc_res *res = data;
  545. struct compound_hdr hdr;
  546. int status;
  547. status = decode_compound_hdr(xdr, &hdr);
  548. if (status)
  549. goto out;
  550. status = decode_sequence(xdr, &res->seq_res, rqstp);
  551. if (status)
  552. goto out;
  553. status = decode_putfh(xdr);
  554. if (status)
  555. goto out;
  556. status = decode_deallocate(xdr, res);
  557. if (status)
  558. goto out;
  559. decode_getfattr(xdr, res->falloc_fattr, res->falloc_server);
  560. out:
  561. return status;
  562. }
  563. /*
  564. * Decode SEEK request
  565. */
  566. static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp,
  567. struct xdr_stream *xdr,
  568. void *data)
  569. {
  570. struct nfs42_seek_res *res = data;
  571. struct compound_hdr hdr;
  572. int status;
  573. status = decode_compound_hdr(xdr, &hdr);
  574. if (status)
  575. goto out;
  576. status = decode_sequence(xdr, &res->seq_res, rqstp);
  577. if (status)
  578. goto out;
  579. status = decode_putfh(xdr);
  580. if (status)
  581. goto out;
  582. status = decode_seek(xdr, res);
  583. out:
  584. return status;
  585. }
  586. /*
  587. * Decode LAYOUTSTATS request
  588. */
  589. static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp,
  590. struct xdr_stream *xdr,
  591. void *data)
  592. {
  593. struct nfs42_layoutstat_res *res = data;
  594. struct compound_hdr hdr;
  595. int status, i;
  596. status = decode_compound_hdr(xdr, &hdr);
  597. if (status)
  598. goto out;
  599. status = decode_sequence(xdr, &res->seq_res, rqstp);
  600. if (status)
  601. goto out;
  602. status = decode_putfh(xdr);
  603. if (status)
  604. goto out;
  605. WARN_ON(res->num_dev > PNFS_LAYOUTSTATS_MAXDEV);
  606. for (i = 0; i < res->num_dev; i++) {
  607. status = decode_layoutstats(xdr);
  608. if (status)
  609. goto out;
  610. }
  611. out:
  612. res->rpc_status = status;
  613. return status;
  614. }
  615. /*
  616. * Decode CLONE request
  617. */
  618. static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp,
  619. struct xdr_stream *xdr,
  620. void *data)
  621. {
  622. struct nfs42_clone_res *res = data;
  623. struct compound_hdr hdr;
  624. int status;
  625. status = decode_compound_hdr(xdr, &hdr);
  626. if (status)
  627. goto out;
  628. status = decode_sequence(xdr, &res->seq_res, rqstp);
  629. if (status)
  630. goto out;
  631. status = decode_putfh(xdr);
  632. if (status)
  633. goto out;
  634. status = decode_savefh(xdr);
  635. if (status)
  636. goto out;
  637. status = decode_putfh(xdr);
  638. if (status)
  639. goto out;
  640. status = decode_clone(xdr);
  641. if (status)
  642. goto out;
  643. status = decode_getfattr(xdr, res->dst_fattr, res->server);
  644. out:
  645. res->rpc_status = status;
  646. return status;
  647. }
  648. #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */