diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index b851b560a6f8..5f769f8d05b0 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -314,6 +314,17 @@ static int nfs4_stat_to_errno(int); | |||
314 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) | 314 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) |
315 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) | 315 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) |
316 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) | 316 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) |
317 | #define encode_getdevicelist_maxsz (op_encode_hdr_maxsz + 4 + \ | ||
318 | encode_verifier_maxsz) | ||
319 | #define decode_getdevicelist_maxsz (op_decode_hdr_maxsz + \ | ||
320 | 2 /* nfs_cookie4 gdlr_cookie */ + \ | ||
321 | decode_verifier_maxsz \ | ||
322 | /* verifier4 gdlr_verifier */ + \ | ||
323 | 1 /* gdlr_deviceid_list count */ + \ | ||
324 | XDR_QUADLEN(NFS4_PNFS_GETDEVLIST_MAXNUM * \ | ||
325 | NFS4_DEVICEID4_SIZE) \ | ||
326 | /* gdlr_deviceid_list */ + \ | ||
327 | 1 /* bool gdlr_eof */) | ||
317 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \ | 328 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \ |
318 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE)) | 329 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE)) |
319 | #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ | 330 | #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ |
@@ -748,6 +759,14 @@ static int nfs4_stat_to_errno(int); | |||
748 | #define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ | 759 | #define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ |
749 | decode_sequence_maxsz + \ | 760 | decode_sequence_maxsz + \ |
750 | decode_reclaim_complete_maxsz) | 761 | decode_reclaim_complete_maxsz) |
762 | #define NFS4_enc_getdevicelist_sz (compound_encode_hdr_maxsz + \ | ||
763 | encode_sequence_maxsz + \ | ||
764 | encode_putfh_maxsz + \ | ||
765 | encode_getdevicelist_maxsz) | ||
766 | #define NFS4_dec_getdevicelist_sz (compound_decode_hdr_maxsz + \ | ||
767 | decode_sequence_maxsz + \ | ||
768 | decode_putfh_maxsz + \ | ||
769 | decode_getdevicelist_maxsz) | ||
751 | #define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ | 770 | #define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ |
752 | encode_sequence_maxsz +\ | 771 | encode_sequence_maxsz +\ |
753 | encode_getdeviceinfo_maxsz) | 772 | encode_getdeviceinfo_maxsz) |
@@ -1855,6 +1874,26 @@ static void encode_sequence(struct xdr_stream *xdr, | |||
1855 | 1874 | ||
1856 | #ifdef CONFIG_NFS_V4_1 | 1875 | #ifdef CONFIG_NFS_V4_1 |
1857 | static void | 1876 | static void |
1877 | encode_getdevicelist(struct xdr_stream *xdr, | ||
1878 | const struct nfs4_getdevicelist_args *args, | ||
1879 | struct compound_hdr *hdr) | ||
1880 | { | ||
1881 | __be32 *p; | ||
1882 | nfs4_verifier dummy = { | ||
1883 | .data = "dummmmmy", | ||
1884 | }; | ||
1885 | |||
1886 | p = reserve_space(xdr, 20); | ||
1887 | *p++ = cpu_to_be32(OP_GETDEVICELIST); | ||
1888 | *p++ = cpu_to_be32(args->layoutclass); | ||
1889 | *p++ = cpu_to_be32(NFS4_PNFS_GETDEVLIST_MAXNUM); | ||
1890 | xdr_encode_hyper(p, 0ULL); /* cookie */ | ||
1891 | encode_nfs4_verifier(xdr, &dummy); | ||
1892 | hdr->nops++; | ||
1893 | hdr->replen += decode_getdevicelist_maxsz; | ||
1894 | } | ||
1895 | |||
1896 | static void | ||
1858 | encode_getdeviceinfo(struct xdr_stream *xdr, | 1897 | encode_getdeviceinfo(struct xdr_stream *xdr, |
1859 | const struct nfs4_getdeviceinfo_args *args, | 1898 | const struct nfs4_getdeviceinfo_args *args, |
1860 | struct compound_hdr *hdr) | 1899 | struct compound_hdr *hdr) |
@@ -2775,6 +2814,24 @@ static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, | |||
2775 | } | 2814 | } |
2776 | 2815 | ||
2777 | /* | 2816 | /* |
2817 | * Encode GETDEVICELIST request | ||
2818 | */ | ||
2819 | static void nfs4_xdr_enc_getdevicelist(struct rpc_rqst *req, | ||
2820 | struct xdr_stream *xdr, | ||
2821 | struct nfs4_getdevicelist_args *args) | ||
2822 | { | ||
2823 | struct compound_hdr hdr = { | ||
2824 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2825 | }; | ||
2826 | |||
2827 | encode_compound_hdr(xdr, req, &hdr); | ||
2828 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2829 | encode_putfh(xdr, args->fh, &hdr); | ||
2830 | encode_getdevicelist(xdr, args, &hdr); | ||
2831 | encode_nops(&hdr); | ||
2832 | } | ||
2833 | |||
2834 | /* | ||
2778 | * Encode GETDEVICEINFO request | 2835 | * Encode GETDEVICEINFO request |
2779 | */ | 2836 | */ |
2780 | static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, | 2837 | static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, |
@@ -5268,6 +5325,53 @@ out_overflow: | |||
5268 | } | 5325 | } |
5269 | 5326 | ||
5270 | #if defined(CONFIG_NFS_V4_1) | 5327 | #if defined(CONFIG_NFS_V4_1) |
5328 | /* | ||
5329 | * TODO: Need to handle case when EOF != true; | ||
5330 | */ | ||
5331 | static int decode_getdevicelist(struct xdr_stream *xdr, | ||
5332 | struct pnfs_devicelist *res) | ||
5333 | { | ||
5334 | __be32 *p; | ||
5335 | int status, i; | ||
5336 | struct nfs_writeverf verftemp; | ||
5337 | |||
5338 | status = decode_op_hdr(xdr, OP_GETDEVICELIST); | ||
5339 | if (status) | ||
5340 | return status; | ||
5341 | |||
5342 | p = xdr_inline_decode(xdr, 8 + 8 + 4); | ||
5343 | if (unlikely(!p)) | ||
5344 | goto out_overflow; | ||
5345 | |||
5346 | /* TODO: Skip cookie for now */ | ||
5347 | p += 2; | ||
5348 | |||
5349 | /* Read verifier */ | ||
5350 | p = xdr_decode_opaque_fixed(p, verftemp.verifier, 8); | ||
5351 | |||
5352 | res->num_devs = be32_to_cpup(p); | ||
5353 | |||
5354 | dprintk("%s: num_dev %d\n", __func__, res->num_devs); | ||
5355 | |||
5356 | if (res->num_devs > NFS4_PNFS_GETDEVLIST_MAXNUM) { | ||
5357 | printk(KERN_ERR "%s too many result dev_num %u\n", | ||
5358 | __func__, res->num_devs); | ||
5359 | return -EIO; | ||
5360 | } | ||
5361 | |||
5362 | p = xdr_inline_decode(xdr, | ||
5363 | res->num_devs * NFS4_DEVICEID4_SIZE + 4); | ||
5364 | if (unlikely(!p)) | ||
5365 | goto out_overflow; | ||
5366 | for (i = 0; i < res->num_devs; i++) | ||
5367 | p = xdr_decode_opaque_fixed(p, res->dev_id[i].data, | ||
5368 | NFS4_DEVICEID4_SIZE); | ||
5369 | res->eof = be32_to_cpup(p); | ||
5370 | return 0; | ||
5371 | out_overflow: | ||
5372 | print_overflow_msg(__func__, xdr); | ||
5373 | return -EIO; | ||
5374 | } | ||
5271 | 5375 | ||
5272 | static int decode_getdeviceinfo(struct xdr_stream *xdr, | 5376 | static int decode_getdeviceinfo(struct xdr_stream *xdr, |
5273 | struct pnfs_device *pdev) | 5377 | struct pnfs_device *pdev) |
@@ -6542,6 +6646,32 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, | |||
6542 | } | 6646 | } |
6543 | 6647 | ||
6544 | /* | 6648 | /* |
6649 | * Decode GETDEVICELIST response | ||
6650 | */ | ||
6651 | static int nfs4_xdr_dec_getdevicelist(struct rpc_rqst *rqstp, | ||
6652 | struct xdr_stream *xdr, | ||
6653 | struct nfs4_getdevicelist_res *res) | ||
6654 | { | ||
6655 | struct compound_hdr hdr; | ||
6656 | int status; | ||
6657 | |||
6658 | dprintk("encoding getdevicelist!\n"); | ||
6659 | |||
6660 | status = decode_compound_hdr(xdr, &hdr); | ||
6661 | if (status != 0) | ||
6662 | goto out; | ||
6663 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
6664 | if (status != 0) | ||
6665 | goto out; | ||
6666 | status = decode_putfh(xdr); | ||
6667 | if (status != 0) | ||
6668 | goto out; | ||
6669 | status = decode_getdevicelist(xdr, res->devlist); | ||
6670 | out: | ||
6671 | return status; | ||
6672 | } | ||
6673 | |||
6674 | /* | ||
6545 | * Decode GETDEVINFO response | 6675 | * Decode GETDEVINFO response |
6546 | */ | 6676 | */ |
6547 | static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, | 6677 | static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, |
@@ -6908,6 +7038,7 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
6908 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), | 7038 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), |
6909 | PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), | 7039 | PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), |
6910 | PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), | 7040 | PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), |
7041 | PROC(GETDEVICELIST, enc_getdevicelist, dec_getdevicelist), | ||
6911 | #endif /* CONFIG_NFS_V4_1 */ | 7042 | #endif /* CONFIG_NFS_V4_1 */ |
6912 | }; | 7043 | }; |
6913 | 7044 | ||