aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r--fs/nfs/nfs4xdr.c131
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
1857static void 1876static void
1877encode_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
1896static void
1858encode_getdeviceinfo(struct xdr_stream *xdr, 1897encode_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 */
2819static 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 */
2780static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, 2837static 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 */
5331static 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;
5371out_overflow:
5372 print_overflow_msg(__func__, xdr);
5373 return -EIO;
5374}
5271 5375
5272static int decode_getdeviceinfo(struct xdr_stream *xdr, 5376static 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 */
6651static 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);
6670out:
6671 return status;
6672}
6673
6674/*
6545 * Decode GETDEVINFO response 6675 * Decode GETDEVINFO response
6546 */ 6676 */
6547static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, 6677static 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