diff options
Diffstat (limited to 'fs/nfs/nfs4xdr.c')
-rw-r--r-- | fs/nfs/nfs4xdr.c | 179 |
1 files changed, 36 insertions, 143 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index e13b59d8d9aa..005d03c5d274 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -362,25 +362,19 @@ static int nfs4_stat_to_errno(int); | |||
362 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) | 362 | XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5) |
363 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) | 363 | #define encode_reclaim_complete_maxsz (op_encode_hdr_maxsz + 4) |
364 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) | 364 | #define decode_reclaim_complete_maxsz (op_decode_hdr_maxsz + 4) |
365 | #define encode_getdevicelist_maxsz (op_encode_hdr_maxsz + 4 + \ | 365 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + \ |
366 | encode_verifier_maxsz) | 366 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE) + \ |
367 | #define decode_getdevicelist_maxsz (op_decode_hdr_maxsz + \ | 367 | 1 /* layout type */ + \ |
368 | 2 /* nfs_cookie4 gdlr_cookie */ + \ | 368 | 1 /* maxcount */ + \ |
369 | decode_verifier_maxsz \ | 369 | 1 /* bitmap size */ + \ |
370 | /* verifier4 gdlr_verifier */ + \ | 370 | 1 /* notification bitmap length */ + \ |
371 | 1 /* gdlr_deviceid_list count */ + \ | 371 | 1 /* notification bitmap, word 0 */) |
372 | XDR_QUADLEN(NFS4_PNFS_GETDEVLIST_MAXNUM * \ | ||
373 | NFS4_DEVICEID4_SIZE) \ | ||
374 | /* gdlr_deviceid_list */ + \ | ||
375 | 1 /* bool gdlr_eof */) | ||
376 | #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \ | ||
377 | XDR_QUADLEN(NFS4_DEVICEID4_SIZE)) | ||
378 | #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ | 372 | #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \ |
379 | 1 /* layout type */ + \ | 373 | 1 /* layout type */ + \ |
380 | 1 /* opaque devaddr4 length */ + \ | 374 | 1 /* opaque devaddr4 length */ + \ |
381 | /* devaddr4 payload is read into page */ \ | 375 | /* devaddr4 payload is read into page */ \ |
382 | 1 /* notification bitmap length */ + \ | 376 | 1 /* notification bitmap length */ + \ |
383 | 1 /* notification bitmap */) | 377 | 1 /* notification bitmap, word 0 */) |
384 | #define encode_layoutget_maxsz (op_encode_hdr_maxsz + 10 + \ | 378 | #define encode_layoutget_maxsz (op_encode_hdr_maxsz + 10 + \ |
385 | encode_stateid_maxsz) | 379 | encode_stateid_maxsz) |
386 | #define decode_layoutget_maxsz (op_decode_hdr_maxsz + 8 + \ | 380 | #define decode_layoutget_maxsz (op_decode_hdr_maxsz + 8 + \ |
@@ -395,7 +389,10 @@ static int nfs4_stat_to_errno(int); | |||
395 | 2 /* last byte written */ + \ | 389 | 2 /* last byte written */ + \ |
396 | 1 /* nt_timechanged (false) */ + \ | 390 | 1 /* nt_timechanged (false) */ + \ |
397 | 1 /* layoutupdate4 layout type */ + \ | 391 | 1 /* layoutupdate4 layout type */ + \ |
398 | 1 /* NULL filelayout layoutupdate4 payload */) | 392 | 1 /* layoutupdate4 opaqueue len */) |
393 | /* the actual content of layoutupdate4 should | ||
394 | be allocated by drivers and spliced in | ||
395 | using xdr_write_pages */ | ||
399 | #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) | 396 | #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3) |
400 | #define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \ | 397 | #define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \ |
401 | encode_stateid_maxsz + \ | 398 | encode_stateid_maxsz + \ |
@@ -809,14 +806,6 @@ static int nfs4_stat_to_errno(int); | |||
809 | #define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ | 806 | #define NFS4_dec_reclaim_complete_sz (compound_decode_hdr_maxsz + \ |
810 | decode_sequence_maxsz + \ | 807 | decode_sequence_maxsz + \ |
811 | decode_reclaim_complete_maxsz) | 808 | decode_reclaim_complete_maxsz) |
812 | #define NFS4_enc_getdevicelist_sz (compound_encode_hdr_maxsz + \ | ||
813 | encode_sequence_maxsz + \ | ||
814 | encode_putfh_maxsz + \ | ||
815 | encode_getdevicelist_maxsz) | ||
816 | #define NFS4_dec_getdevicelist_sz (compound_decode_hdr_maxsz + \ | ||
817 | decode_sequence_maxsz + \ | ||
818 | decode_putfh_maxsz + \ | ||
819 | decode_getdevicelist_maxsz) | ||
820 | #define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ | 809 | #define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz + \ |
821 | encode_sequence_maxsz +\ | 810 | encode_sequence_maxsz +\ |
822 | encode_getdeviceinfo_maxsz) | 811 | encode_getdeviceinfo_maxsz) |
@@ -1927,24 +1916,6 @@ static void encode_sequence(struct xdr_stream *xdr, | |||
1927 | 1916 | ||
1928 | #ifdef CONFIG_NFS_V4_1 | 1917 | #ifdef CONFIG_NFS_V4_1 |
1929 | static void | 1918 | static void |
1930 | encode_getdevicelist(struct xdr_stream *xdr, | ||
1931 | const struct nfs4_getdevicelist_args *args, | ||
1932 | struct compound_hdr *hdr) | ||
1933 | { | ||
1934 | __be32 *p; | ||
1935 | nfs4_verifier dummy = { | ||
1936 | .data = "dummmmmy", | ||
1937 | }; | ||
1938 | |||
1939 | encode_op_hdr(xdr, OP_GETDEVICELIST, decode_getdevicelist_maxsz, hdr); | ||
1940 | p = reserve_space(xdr, 16); | ||
1941 | *p++ = cpu_to_be32(args->layoutclass); | ||
1942 | *p++ = cpu_to_be32(NFS4_PNFS_GETDEVLIST_MAXNUM); | ||
1943 | xdr_encode_hyper(p, 0ULL); /* cookie */ | ||
1944 | encode_nfs4_verifier(xdr, &dummy); | ||
1945 | } | ||
1946 | |||
1947 | static void | ||
1948 | encode_getdeviceinfo(struct xdr_stream *xdr, | 1919 | encode_getdeviceinfo(struct xdr_stream *xdr, |
1949 | const struct nfs4_getdeviceinfo_args *args, | 1920 | const struct nfs4_getdeviceinfo_args *args, |
1950 | struct compound_hdr *hdr) | 1921 | struct compound_hdr *hdr) |
@@ -1952,12 +1923,15 @@ encode_getdeviceinfo(struct xdr_stream *xdr, | |||
1952 | __be32 *p; | 1923 | __be32 *p; |
1953 | 1924 | ||
1954 | encode_op_hdr(xdr, OP_GETDEVICEINFO, decode_getdeviceinfo_maxsz, hdr); | 1925 | encode_op_hdr(xdr, OP_GETDEVICEINFO, decode_getdeviceinfo_maxsz, hdr); |
1955 | p = reserve_space(xdr, 12 + NFS4_DEVICEID4_SIZE); | 1926 | p = reserve_space(xdr, NFS4_DEVICEID4_SIZE + 4 + 4); |
1956 | p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data, | 1927 | p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data, |
1957 | NFS4_DEVICEID4_SIZE); | 1928 | NFS4_DEVICEID4_SIZE); |
1958 | *p++ = cpu_to_be32(args->pdev->layout_type); | 1929 | *p++ = cpu_to_be32(args->pdev->layout_type); |
1959 | *p++ = cpu_to_be32(args->pdev->maxcount); /* gdia_maxcount */ | 1930 | *p++ = cpu_to_be32(args->pdev->maxcount); /* gdia_maxcount */ |
1960 | *p++ = cpu_to_be32(0); /* bitmap length 0 */ | 1931 | |
1932 | p = reserve_space(xdr, 4 + 4); | ||
1933 | *p++ = cpu_to_be32(1); /* bitmap length */ | ||
1934 | *p++ = cpu_to_be32(NOTIFY_DEVICEID4_CHANGE | NOTIFY_DEVICEID4_DELETE); | ||
1961 | } | 1935 | } |
1962 | 1936 | ||
1963 | static void | 1937 | static void |
@@ -1990,7 +1964,7 @@ encode_layoutget(struct xdr_stream *xdr, | |||
1990 | static int | 1964 | static int |
1991 | encode_layoutcommit(struct xdr_stream *xdr, | 1965 | encode_layoutcommit(struct xdr_stream *xdr, |
1992 | struct inode *inode, | 1966 | struct inode *inode, |
1993 | const struct nfs4_layoutcommit_args *args, | 1967 | struct nfs4_layoutcommit_args *args, |
1994 | struct compound_hdr *hdr) | 1968 | struct compound_hdr *hdr) |
1995 | { | 1969 | { |
1996 | __be32 *p; | 1970 | __be32 *p; |
@@ -2011,11 +1985,16 @@ encode_layoutcommit(struct xdr_stream *xdr, | |||
2011 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ | 1985 | *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ |
2012 | *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ | 1986 | *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ |
2013 | 1987 | ||
2014 | if (NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit) | 1988 | if (NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit) { |
2015 | NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit( | 1989 | NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit( |
2016 | NFS_I(inode)->layout, xdr, args); | 1990 | NFS_I(inode)->layout, xdr, args); |
2017 | else | 1991 | } else { |
2018 | encode_uint32(xdr, 0); /* no layout-type payload */ | 1992 | encode_uint32(xdr, args->layoutupdate_len); |
1993 | if (args->layoutupdate_pages) { | ||
1994 | xdr_write_pages(xdr, args->layoutupdate_pages, 0, | ||
1995 | args->layoutupdate_len); | ||
1996 | } | ||
1997 | } | ||
2019 | 1998 | ||
2020 | return 0; | 1999 | return 0; |
2021 | } | 2000 | } |
@@ -2893,24 +2872,6 @@ static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, | |||
2893 | } | 2872 | } |
2894 | 2873 | ||
2895 | /* | 2874 | /* |
2896 | * Encode GETDEVICELIST request | ||
2897 | */ | ||
2898 | static void nfs4_xdr_enc_getdevicelist(struct rpc_rqst *req, | ||
2899 | struct xdr_stream *xdr, | ||
2900 | struct nfs4_getdevicelist_args *args) | ||
2901 | { | ||
2902 | struct compound_hdr hdr = { | ||
2903 | .minorversion = nfs4_xdr_minorversion(&args->seq_args), | ||
2904 | }; | ||
2905 | |||
2906 | encode_compound_hdr(xdr, req, &hdr); | ||
2907 | encode_sequence(xdr, &args->seq_args, &hdr); | ||
2908 | encode_putfh(xdr, args->fh, &hdr); | ||
2909 | encode_getdevicelist(xdr, args, &hdr); | ||
2910 | encode_nops(&hdr); | ||
2911 | } | ||
2912 | |||
2913 | /* | ||
2914 | * Encode GETDEVICEINFO request | 2875 | * Encode GETDEVICEINFO request |
2915 | */ | 2876 | */ |
2916 | static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, | 2877 | static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, |
@@ -5765,54 +5726,6 @@ out_overflow: | |||
5765 | } | 5726 | } |
5766 | 5727 | ||
5767 | #if defined(CONFIG_NFS_V4_1) | 5728 | #if defined(CONFIG_NFS_V4_1) |
5768 | /* | ||
5769 | * TODO: Need to handle case when EOF != true; | ||
5770 | */ | ||
5771 | static int decode_getdevicelist(struct xdr_stream *xdr, | ||
5772 | struct pnfs_devicelist *res) | ||
5773 | { | ||
5774 | __be32 *p; | ||
5775 | int status, i; | ||
5776 | nfs4_verifier verftemp; | ||
5777 | |||
5778 | status = decode_op_hdr(xdr, OP_GETDEVICELIST); | ||
5779 | if (status) | ||
5780 | return status; | ||
5781 | |||
5782 | p = xdr_inline_decode(xdr, 8 + 8 + 4); | ||
5783 | if (unlikely(!p)) | ||
5784 | goto out_overflow; | ||
5785 | |||
5786 | /* TODO: Skip cookie for now */ | ||
5787 | p += 2; | ||
5788 | |||
5789 | /* Read verifier */ | ||
5790 | p = xdr_decode_opaque_fixed(p, verftemp.data, NFS4_VERIFIER_SIZE); | ||
5791 | |||
5792 | res->num_devs = be32_to_cpup(p); | ||
5793 | |||
5794 | dprintk("%s: num_dev %d\n", __func__, res->num_devs); | ||
5795 | |||
5796 | if (res->num_devs > NFS4_PNFS_GETDEVLIST_MAXNUM) { | ||
5797 | printk(KERN_ERR "NFS: %s too many result dev_num %u\n", | ||
5798 | __func__, res->num_devs); | ||
5799 | return -EIO; | ||
5800 | } | ||
5801 | |||
5802 | p = xdr_inline_decode(xdr, | ||
5803 | res->num_devs * NFS4_DEVICEID4_SIZE + 4); | ||
5804 | if (unlikely(!p)) | ||
5805 | goto out_overflow; | ||
5806 | for (i = 0; i < res->num_devs; i++) | ||
5807 | p = xdr_decode_opaque_fixed(p, res->dev_id[i].data, | ||
5808 | NFS4_DEVICEID4_SIZE); | ||
5809 | res->eof = be32_to_cpup(p); | ||
5810 | return 0; | ||
5811 | out_overflow: | ||
5812 | print_overflow_msg(__func__, xdr); | ||
5813 | return -EIO; | ||
5814 | } | ||
5815 | |||
5816 | static int decode_getdeviceinfo(struct xdr_stream *xdr, | 5729 | static int decode_getdeviceinfo(struct xdr_stream *xdr, |
5817 | struct pnfs_device *pdev) | 5730 | struct pnfs_device *pdev) |
5818 | { | 5731 | { |
@@ -5862,9 +5775,16 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, | |||
5862 | p = xdr_inline_decode(xdr, 4 * len); | 5775 | p = xdr_inline_decode(xdr, 4 * len); |
5863 | if (unlikely(!p)) | 5776 | if (unlikely(!p)) |
5864 | goto out_overflow; | 5777 | goto out_overflow; |
5865 | for (i = 0; i < len; i++, p++) { | 5778 | |
5866 | if (be32_to_cpup(p)) { | 5779 | if (be32_to_cpup(p++) & |
5867 | dprintk("%s: notifications not supported\n", | 5780 | ~(NOTIFY_DEVICEID4_CHANGE | NOTIFY_DEVICEID4_DELETE)) { |
5781 | dprintk("%s: unsupported notification\n", | ||
5782 | __func__); | ||
5783 | } | ||
5784 | |||
5785 | for (i = 1; i < len; i++) { | ||
5786 | if (be32_to_cpup(p++)) { | ||
5787 | dprintk("%s: unsupported notification\n", | ||
5868 | __func__); | 5788 | __func__); |
5869 | return -EIO; | 5789 | return -EIO; |
5870 | } | 5790 | } |
@@ -7097,32 +7017,6 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, | |||
7097 | } | 7017 | } |
7098 | 7018 | ||
7099 | /* | 7019 | /* |
7100 | * Decode GETDEVICELIST response | ||
7101 | */ | ||
7102 | static int nfs4_xdr_dec_getdevicelist(struct rpc_rqst *rqstp, | ||
7103 | struct xdr_stream *xdr, | ||
7104 | struct nfs4_getdevicelist_res *res) | ||
7105 | { | ||
7106 | struct compound_hdr hdr; | ||
7107 | int status; | ||
7108 | |||
7109 | dprintk("encoding getdevicelist!\n"); | ||
7110 | |||
7111 | status = decode_compound_hdr(xdr, &hdr); | ||
7112 | if (status != 0) | ||
7113 | goto out; | ||
7114 | status = decode_sequence(xdr, &res->seq_res, rqstp); | ||
7115 | if (status != 0) | ||
7116 | goto out; | ||
7117 | status = decode_putfh(xdr); | ||
7118 | if (status != 0) | ||
7119 | goto out; | ||
7120 | status = decode_getdevicelist(xdr, res->devlist); | ||
7121 | out: | ||
7122 | return status; | ||
7123 | } | ||
7124 | |||
7125 | /* | ||
7126 | * Decode GETDEVINFO response | 7020 | * Decode GETDEVINFO response |
7127 | */ | 7021 | */ |
7128 | static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, | 7022 | static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, |
@@ -7490,7 +7384,6 @@ struct rpc_procinfo nfs4_procedures[] = { | |||
7490 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), | 7384 | PROC(SECINFO_NO_NAME, enc_secinfo_no_name, dec_secinfo_no_name), |
7491 | PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), | 7385 | PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), |
7492 | PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), | 7386 | PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), |
7493 | PROC(GETDEVICELIST, enc_getdevicelist, dec_getdevicelist), | ||
7494 | PROC(BIND_CONN_TO_SESSION, | 7387 | PROC(BIND_CONN_TO_SESSION, |
7495 | enc_bind_conn_to_session, dec_bind_conn_to_session), | 7388 | enc_bind_conn_to_session, dec_bind_conn_to_session), |
7496 | PROC(DESTROY_CLIENTID, enc_destroy_clientid, dec_destroy_clientid), | 7389 | PROC(DESTROY_CLIENTID, enc_destroy_clientid, dec_destroy_clientid), |