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.c452
1 files changed, 336 insertions, 116 deletions
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index c74fdb114b48..ee4a74db95d0 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -53,9 +53,11 @@
53#include <linux/nfs4.h> 53#include <linux/nfs4.h>
54#include <linux/nfs_fs.h> 54#include <linux/nfs_fs.h>
55#include <linux/nfs_idmap.h> 55#include <linux/nfs_idmap.h>
56
56#include "nfs4_fs.h" 57#include "nfs4_fs.h"
57#include "internal.h" 58#include "internal.h"
58#include "pnfs.h" 59#include "pnfs.h"
60#include "netns.h"
59 61
60#define NFSDBG_FACILITY NFSDBG_XDR 62#define NFSDBG_FACILITY NFSDBG_XDR
61 63
@@ -74,7 +76,7 @@ static int nfs4_stat_to_errno(int);
74/* lock,open owner id: 76/* lock,open owner id:
75 * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2) 77 * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2)
76 */ 78 */
77#define open_owner_id_maxsz (1 + 1 + 4) 79#define open_owner_id_maxsz (1 + 2 + 1 + 1 + 2)
78#define lock_owner_id_maxsz (1 + 1 + 4) 80#define lock_owner_id_maxsz (1 + 1 + 4)
79#define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 81#define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
80#define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) 82#define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2))
@@ -99,9 +101,12 @@ static int nfs4_stat_to_errno(int);
99#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) 101#define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
100#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 102#define nfs4_owner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
101#define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) 103#define nfs4_group_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ))
104/* We support only one layout type per file system */
105#define decode_mdsthreshold_maxsz (1 + 1 + nfs4_fattr_bitmap_maxsz + 1 + 8)
102/* This is based on getfattr, which uses the most attributes: */ 106/* This is based on getfattr, which uses the most attributes: */
103#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \ 107#define nfs4_fattr_value_maxsz (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
104 3 + 3 + 3 + nfs4_owner_maxsz + nfs4_group_maxsz)) 108 3 + 3 + 3 + nfs4_owner_maxsz + \
109 nfs4_group_maxsz + decode_mdsthreshold_maxsz))
105#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \ 110#define nfs4_fattr_maxsz (nfs4_fattr_bitmap_maxsz + \
106 nfs4_fattr_value_maxsz) 111 nfs4_fattr_value_maxsz)
107#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz) 112#define decode_getattr_maxsz (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
@@ -321,8 +326,20 @@ static int nfs4_stat_to_errno(int);
321 1 /* csr_flags */ + \ 326 1 /* csr_flags */ + \
322 decode_channel_attrs_maxsz + \ 327 decode_channel_attrs_maxsz + \
323 decode_channel_attrs_maxsz) 328 decode_channel_attrs_maxsz)
329#define encode_bind_conn_to_session_maxsz (op_encode_hdr_maxsz + \
330 /* bctsa_sessid */ \
331 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
332 1 /* bctsa_dir */ + \
333 1 /* bctsa_use_conn_in_rdma_mode */)
334#define decode_bind_conn_to_session_maxsz (op_decode_hdr_maxsz + \
335 /* bctsr_sessid */ \
336 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
337 1 /* bctsr_dir */ + \
338 1 /* bctsr_use_conn_in_rdma_mode */)
324#define encode_destroy_session_maxsz (op_encode_hdr_maxsz + 4) 339#define encode_destroy_session_maxsz (op_encode_hdr_maxsz + 4)
325#define decode_destroy_session_maxsz (op_decode_hdr_maxsz) 340#define decode_destroy_session_maxsz (op_decode_hdr_maxsz)
341#define encode_destroy_clientid_maxsz (op_encode_hdr_maxsz + 2)
342#define decode_destroy_clientid_maxsz (op_decode_hdr_maxsz)
326#define encode_sequence_maxsz (op_encode_hdr_maxsz + \ 343#define encode_sequence_maxsz (op_encode_hdr_maxsz + \
327 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4) 344 XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
328#define decode_sequence_maxsz (op_decode_hdr_maxsz + \ 345#define decode_sequence_maxsz (op_decode_hdr_maxsz + \
@@ -421,30 +438,22 @@ static int nfs4_stat_to_errno(int);
421#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \ 438#define NFS4_enc_commit_sz (compound_encode_hdr_maxsz + \
422 encode_sequence_maxsz + \ 439 encode_sequence_maxsz + \
423 encode_putfh_maxsz + \ 440 encode_putfh_maxsz + \
424 encode_commit_maxsz + \ 441 encode_commit_maxsz)
425 encode_getattr_maxsz)
426#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \ 442#define NFS4_dec_commit_sz (compound_decode_hdr_maxsz + \
427 decode_sequence_maxsz + \ 443 decode_sequence_maxsz + \
428 decode_putfh_maxsz + \ 444 decode_putfh_maxsz + \
429 decode_commit_maxsz + \ 445 decode_commit_maxsz)
430 decode_getattr_maxsz)
431#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \ 446#define NFS4_enc_open_sz (compound_encode_hdr_maxsz + \
432 encode_sequence_maxsz + \ 447 encode_sequence_maxsz + \
433 encode_putfh_maxsz + \ 448 encode_putfh_maxsz + \
434 encode_savefh_maxsz + \
435 encode_open_maxsz + \ 449 encode_open_maxsz + \
436 encode_getfh_maxsz + \ 450 encode_getfh_maxsz + \
437 encode_getattr_maxsz + \
438 encode_restorefh_maxsz + \
439 encode_getattr_maxsz) 451 encode_getattr_maxsz)
440#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \ 452#define NFS4_dec_open_sz (compound_decode_hdr_maxsz + \
441 decode_sequence_maxsz + \ 453 decode_sequence_maxsz + \
442 decode_putfh_maxsz + \ 454 decode_putfh_maxsz + \
443 decode_savefh_maxsz + \
444 decode_open_maxsz + \ 455 decode_open_maxsz + \
445 decode_getfh_maxsz + \ 456 decode_getfh_maxsz + \
446 decode_getattr_maxsz + \
447 decode_restorefh_maxsz + \
448 decode_getattr_maxsz) 457 decode_getattr_maxsz)
449#define NFS4_enc_open_confirm_sz \ 458#define NFS4_enc_open_confirm_sz \
450 (compound_encode_hdr_maxsz + \ 459 (compound_encode_hdr_maxsz + \
@@ -595,47 +604,37 @@ static int nfs4_stat_to_errno(int);
595#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \ 604#define NFS4_enc_remove_sz (compound_encode_hdr_maxsz + \
596 encode_sequence_maxsz + \ 605 encode_sequence_maxsz + \
597 encode_putfh_maxsz + \ 606 encode_putfh_maxsz + \
598 encode_remove_maxsz + \ 607 encode_remove_maxsz)
599 encode_getattr_maxsz)
600#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \ 608#define NFS4_dec_remove_sz (compound_decode_hdr_maxsz + \
601 decode_sequence_maxsz + \ 609 decode_sequence_maxsz + \
602 decode_putfh_maxsz + \ 610 decode_putfh_maxsz + \
603 decode_remove_maxsz + \ 611 decode_remove_maxsz)
604 decode_getattr_maxsz)
605#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \ 612#define NFS4_enc_rename_sz (compound_encode_hdr_maxsz + \
606 encode_sequence_maxsz + \ 613 encode_sequence_maxsz + \
607 encode_putfh_maxsz + \ 614 encode_putfh_maxsz + \
608 encode_savefh_maxsz + \ 615 encode_savefh_maxsz + \
609 encode_putfh_maxsz + \ 616 encode_putfh_maxsz + \
610 encode_rename_maxsz + \ 617 encode_rename_maxsz)
611 encode_getattr_maxsz + \
612 encode_restorefh_maxsz + \
613 encode_getattr_maxsz)
614#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \ 618#define NFS4_dec_rename_sz (compound_decode_hdr_maxsz + \
615 decode_sequence_maxsz + \ 619 decode_sequence_maxsz + \
616 decode_putfh_maxsz + \ 620 decode_putfh_maxsz + \
617 decode_savefh_maxsz + \ 621 decode_savefh_maxsz + \
618 decode_putfh_maxsz + \ 622 decode_putfh_maxsz + \
619 decode_rename_maxsz + \ 623 decode_rename_maxsz)
620 decode_getattr_maxsz + \
621 decode_restorefh_maxsz + \
622 decode_getattr_maxsz)
623#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \ 624#define NFS4_enc_link_sz (compound_encode_hdr_maxsz + \
624 encode_sequence_maxsz + \ 625 encode_sequence_maxsz + \
625 encode_putfh_maxsz + \ 626 encode_putfh_maxsz + \
626 encode_savefh_maxsz + \ 627 encode_savefh_maxsz + \
627 encode_putfh_maxsz + \ 628 encode_putfh_maxsz + \
628 encode_link_maxsz + \ 629 encode_link_maxsz + \
629 decode_getattr_maxsz + \
630 encode_restorefh_maxsz + \ 630 encode_restorefh_maxsz + \
631 decode_getattr_maxsz) 631 encode_getattr_maxsz)
632#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \ 632#define NFS4_dec_link_sz (compound_decode_hdr_maxsz + \
633 decode_sequence_maxsz + \ 633 decode_sequence_maxsz + \
634 decode_putfh_maxsz + \ 634 decode_putfh_maxsz + \
635 decode_savefh_maxsz + \ 635 decode_savefh_maxsz + \
636 decode_putfh_maxsz + \ 636 decode_putfh_maxsz + \
637 decode_link_maxsz + \ 637 decode_link_maxsz + \
638 decode_getattr_maxsz + \
639 decode_restorefh_maxsz + \ 638 decode_restorefh_maxsz + \
640 decode_getattr_maxsz) 639 decode_getattr_maxsz)
641#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \ 640#define NFS4_enc_symlink_sz (compound_encode_hdr_maxsz + \
@@ -653,20 +652,14 @@ static int nfs4_stat_to_errno(int);
653#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \ 652#define NFS4_enc_create_sz (compound_encode_hdr_maxsz + \
654 encode_sequence_maxsz + \ 653 encode_sequence_maxsz + \
655 encode_putfh_maxsz + \ 654 encode_putfh_maxsz + \
656 encode_savefh_maxsz + \
657 encode_create_maxsz + \ 655 encode_create_maxsz + \
658 encode_getfh_maxsz + \ 656 encode_getfh_maxsz + \
659 encode_getattr_maxsz + \
660 encode_restorefh_maxsz + \
661 encode_getattr_maxsz) 657 encode_getattr_maxsz)
662#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \ 658#define NFS4_dec_create_sz (compound_decode_hdr_maxsz + \
663 decode_sequence_maxsz + \ 659 decode_sequence_maxsz + \
664 decode_putfh_maxsz + \ 660 decode_putfh_maxsz + \
665 decode_savefh_maxsz + \
666 decode_create_maxsz + \ 661 decode_create_maxsz + \
667 decode_getfh_maxsz + \ 662 decode_getfh_maxsz + \
668 decode_getattr_maxsz + \
669 decode_restorefh_maxsz + \
670 decode_getattr_maxsz) 663 decode_getattr_maxsz)
671#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \ 664#define NFS4_enc_pathconf_sz (compound_encode_hdr_maxsz + \
672 encode_sequence_maxsz + \ 665 encode_sequence_maxsz + \
@@ -738,6 +731,12 @@ static int nfs4_stat_to_errno(int);
738 decode_putfh_maxsz + \ 731 decode_putfh_maxsz + \
739 decode_secinfo_maxsz) 732 decode_secinfo_maxsz)
740#if defined(CONFIG_NFS_V4_1) 733#if defined(CONFIG_NFS_V4_1)
734#define NFS4_enc_bind_conn_to_session_sz \
735 (compound_encode_hdr_maxsz + \
736 encode_bind_conn_to_session_maxsz)
737#define NFS4_dec_bind_conn_to_session_sz \
738 (compound_decode_hdr_maxsz + \
739 decode_bind_conn_to_session_maxsz)
741#define NFS4_enc_exchange_id_sz \ 740#define NFS4_enc_exchange_id_sz \
742 (compound_encode_hdr_maxsz + \ 741 (compound_encode_hdr_maxsz + \
743 encode_exchange_id_maxsz) 742 encode_exchange_id_maxsz)
@@ -754,6 +753,10 @@ static int nfs4_stat_to_errno(int);
754 encode_destroy_session_maxsz) 753 encode_destroy_session_maxsz)
755#define NFS4_dec_destroy_session_sz (compound_decode_hdr_maxsz + \ 754#define NFS4_dec_destroy_session_sz (compound_decode_hdr_maxsz + \
756 decode_destroy_session_maxsz) 755 decode_destroy_session_maxsz)
756#define NFS4_enc_destroy_clientid_sz (compound_encode_hdr_maxsz + \
757 encode_destroy_clientid_maxsz)
758#define NFS4_dec_destroy_clientid_sz (compound_decode_hdr_maxsz + \
759 decode_destroy_clientid_maxsz)
757#define NFS4_enc_sequence_sz \ 760#define NFS4_enc_sequence_sz \
758 (compound_decode_hdr_maxsz + \ 761 (compound_decode_hdr_maxsz + \
759 encode_sequence_maxsz) 762 encode_sequence_maxsz)
@@ -1103,7 +1106,7 @@ static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg
1103 encode_nfs4_stateid(xdr, arg->stateid); 1106 encode_nfs4_stateid(xdr, arg->stateid);
1104} 1107}
1105 1108
1106static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr) 1109static void encode_commit(struct xdr_stream *xdr, const struct nfs_commitargs *args, struct compound_hdr *hdr)
1107{ 1110{
1108 __be32 *p; 1111 __be32 *p;
1109 1112
@@ -1194,6 +1197,16 @@ static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct c
1194 bitmask[1] & nfs4_fattr_bitmap[1], hdr); 1197 bitmask[1] & nfs4_fattr_bitmap[1], hdr);
1195} 1198}
1196 1199
1200static void encode_getfattr_open(struct xdr_stream *xdr, const u32 *bitmask,
1201 struct compound_hdr *hdr)
1202{
1203 encode_getattr_three(xdr,
1204 bitmask[0] & nfs4_fattr_bitmap[0],
1205 bitmask[1] & nfs4_fattr_bitmap[1],
1206 bitmask[2] & FATTR4_WORD2_MDSTHRESHOLD,
1207 hdr);
1208}
1209
1197static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr) 1210static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1198{ 1211{
1199 encode_getattr_three(xdr, 1212 encode_getattr_three(xdr,
@@ -1340,12 +1353,13 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena
1340 */ 1353 */
1341 encode_nfs4_seqid(xdr, arg->seqid); 1354 encode_nfs4_seqid(xdr, arg->seqid);
1342 encode_share_access(xdr, arg->fmode); 1355 encode_share_access(xdr, arg->fmode);
1343 p = reserve_space(xdr, 32); 1356 p = reserve_space(xdr, 36);
1344 p = xdr_encode_hyper(p, arg->clientid); 1357 p = xdr_encode_hyper(p, arg->clientid);
1345 *p++ = cpu_to_be32(20); 1358 *p++ = cpu_to_be32(24);
1346 p = xdr_encode_opaque_fixed(p, "open id:", 8); 1359 p = xdr_encode_opaque_fixed(p, "open id:", 8);
1347 *p++ = cpu_to_be32(arg->server->s_dev); 1360 *p++ = cpu_to_be32(arg->server->s_dev);
1348 xdr_encode_hyper(p, arg->id); 1361 *p++ = cpu_to_be32(arg->id.uniquifier);
1362 xdr_encode_hyper(p, arg->id.create_time);
1349} 1363}
1350 1364
1351static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) 1365static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
@@ -1677,6 +1691,20 @@ static void encode_secinfo(struct xdr_stream *xdr, const struct qstr *name, stru
1677 1691
1678#if defined(CONFIG_NFS_V4_1) 1692#if defined(CONFIG_NFS_V4_1)
1679/* NFSv4.1 operations */ 1693/* NFSv4.1 operations */
1694static void encode_bind_conn_to_session(struct xdr_stream *xdr,
1695 struct nfs4_session *session,
1696 struct compound_hdr *hdr)
1697{
1698 __be32 *p;
1699
1700 encode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION,
1701 decode_bind_conn_to_session_maxsz, hdr);
1702 encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
1703 p = xdr_reserve_space(xdr, 8);
1704 *p++ = cpu_to_be32(NFS4_CDFC4_BACK_OR_BOTH);
1705 *p = 0; /* use_conn_in_rdma_mode = False */
1706}
1707
1680static void encode_exchange_id(struct xdr_stream *xdr, 1708static void encode_exchange_id(struct xdr_stream *xdr,
1681 struct nfs41_exchange_id_args *args, 1709 struct nfs41_exchange_id_args *args,
1682 struct compound_hdr *hdr) 1710 struct compound_hdr *hdr)
@@ -1725,6 +1753,7 @@ static void encode_create_session(struct xdr_stream *xdr,
1725 char machine_name[NFS4_MAX_MACHINE_NAME_LEN]; 1753 char machine_name[NFS4_MAX_MACHINE_NAME_LEN];
1726 uint32_t len; 1754 uint32_t len;
1727 struct nfs_client *clp = args->client; 1755 struct nfs_client *clp = args->client;
1756 struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
1728 u32 max_resp_sz_cached; 1757 u32 max_resp_sz_cached;
1729 1758
1730 /* 1759 /*
@@ -1766,7 +1795,7 @@ static void encode_create_session(struct xdr_stream *xdr,
1766 *p++ = cpu_to_be32(RPC_AUTH_UNIX); /* auth_sys */ 1795 *p++ = cpu_to_be32(RPC_AUTH_UNIX); /* auth_sys */
1767 1796
1768 /* authsys_parms rfc1831 */ 1797 /* authsys_parms rfc1831 */
1769 *p++ = cpu_to_be32((u32)clp->cl_boot_time.tv_nsec); /* stamp */ 1798 *p++ = (__be32)nn->boot_time.tv_nsec; /* stamp */
1770 p = xdr_encode_opaque(p, machine_name, len); 1799 p = xdr_encode_opaque(p, machine_name, len);
1771 *p++ = cpu_to_be32(0); /* UID */ 1800 *p++ = cpu_to_be32(0); /* UID */
1772 *p++ = cpu_to_be32(0); /* GID */ 1801 *p++ = cpu_to_be32(0); /* GID */
@@ -1781,6 +1810,14 @@ static void encode_destroy_session(struct xdr_stream *xdr,
1781 encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN); 1810 encode_opaque_fixed(xdr, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
1782} 1811}
1783 1812
1813static void encode_destroy_clientid(struct xdr_stream *xdr,
1814 uint64_t clientid,
1815 struct compound_hdr *hdr)
1816{
1817 encode_op_hdr(xdr, OP_DESTROY_CLIENTID, decode_destroy_clientid_maxsz, hdr);
1818 encode_uint64(xdr, clientid);
1819}
1820
1784static void encode_reclaim_complete(struct xdr_stream *xdr, 1821static void encode_reclaim_complete(struct xdr_stream *xdr,
1785 struct nfs41_reclaim_complete_args *args, 1822 struct nfs41_reclaim_complete_args *args,
1786 struct compound_hdr *hdr) 1823 struct compound_hdr *hdr)
@@ -2063,7 +2100,6 @@ static void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr,
2063 encode_sequence(xdr, &args->seq_args, &hdr); 2100 encode_sequence(xdr, &args->seq_args, &hdr);
2064 encode_putfh(xdr, args->fh, &hdr); 2101 encode_putfh(xdr, args->fh, &hdr);
2065 encode_remove(xdr, &args->name, &hdr); 2102 encode_remove(xdr, &args->name, &hdr);
2066 encode_getfattr(xdr, args->bitmask, &hdr);
2067 encode_nops(&hdr); 2103 encode_nops(&hdr);
2068} 2104}
2069 2105
@@ -2083,9 +2119,6 @@ static void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr,
2083 encode_savefh(xdr, &hdr); 2119 encode_savefh(xdr, &hdr);
2084 encode_putfh(xdr, args->new_dir, &hdr); 2120 encode_putfh(xdr, args->new_dir, &hdr);
2085 encode_rename(xdr, args->old_name, args->new_name, &hdr); 2121 encode_rename(xdr, args->old_name, args->new_name, &hdr);
2086 encode_getfattr(xdr, args->bitmask, &hdr);
2087 encode_restorefh(xdr, &hdr);
2088 encode_getfattr(xdr, args->bitmask, &hdr);
2089 encode_nops(&hdr); 2122 encode_nops(&hdr);
2090} 2123}
2091 2124
@@ -2105,7 +2138,6 @@ static void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr,
2105 encode_savefh(xdr, &hdr); 2138 encode_savefh(xdr, &hdr);
2106 encode_putfh(xdr, args->dir_fh, &hdr); 2139 encode_putfh(xdr, args->dir_fh, &hdr);
2107 encode_link(xdr, args->name, &hdr); 2140 encode_link(xdr, args->name, &hdr);
2108 encode_getfattr(xdr, args->bitmask, &hdr);
2109 encode_restorefh(xdr, &hdr); 2141 encode_restorefh(xdr, &hdr);
2110 encode_getfattr(xdr, args->bitmask, &hdr); 2142 encode_getfattr(xdr, args->bitmask, &hdr);
2111 encode_nops(&hdr); 2143 encode_nops(&hdr);
@@ -2124,12 +2156,9 @@ static void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr,
2124 encode_compound_hdr(xdr, req, &hdr); 2156 encode_compound_hdr(xdr, req, &hdr);
2125 encode_sequence(xdr, &args->seq_args, &hdr); 2157 encode_sequence(xdr, &args->seq_args, &hdr);
2126 encode_putfh(xdr, args->dir_fh, &hdr); 2158 encode_putfh(xdr, args->dir_fh, &hdr);
2127 encode_savefh(xdr, &hdr);
2128 encode_create(xdr, args, &hdr); 2159 encode_create(xdr, args, &hdr);
2129 encode_getfh(xdr, &hdr); 2160 encode_getfh(xdr, &hdr);
2130 encode_getfattr(xdr, args->bitmask, &hdr); 2161 encode_getfattr(xdr, args->bitmask, &hdr);
2131 encode_restorefh(xdr, &hdr);
2132 encode_getfattr(xdr, args->bitmask, &hdr);
2133 encode_nops(&hdr); 2162 encode_nops(&hdr);
2134} 2163}
2135 2164
@@ -2190,12 +2219,9 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
2190 encode_compound_hdr(xdr, req, &hdr); 2219 encode_compound_hdr(xdr, req, &hdr);
2191 encode_sequence(xdr, &args->seq_args, &hdr); 2220 encode_sequence(xdr, &args->seq_args, &hdr);
2192 encode_putfh(xdr, args->fh, &hdr); 2221 encode_putfh(xdr, args->fh, &hdr);
2193 encode_savefh(xdr, &hdr);
2194 encode_open(xdr, args, &hdr); 2222 encode_open(xdr, args, &hdr);
2195 encode_getfh(xdr, &hdr); 2223 encode_getfh(xdr, &hdr);
2196 encode_getfattr(xdr, args->bitmask, &hdr); 2224 encode_getfattr_open(xdr, args->bitmask, &hdr);
2197 encode_restorefh(xdr, &hdr);
2198 encode_getfattr(xdr, args->dir_bitmask, &hdr);
2199 encode_nops(&hdr); 2225 encode_nops(&hdr);
2200} 2226}
2201 2227
@@ -2447,7 +2473,7 @@ static void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr,
2447 * a COMMIT request 2473 * a COMMIT request
2448 */ 2474 */
2449static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr, 2475static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr,
2450 struct nfs_writeargs *args) 2476 struct nfs_commitargs *args)
2451{ 2477{
2452 struct compound_hdr hdr = { 2478 struct compound_hdr hdr = {
2453 .minorversion = nfs4_xdr_minorversion(&args->seq_args), 2479 .minorversion = nfs4_xdr_minorversion(&args->seq_args),
@@ -2457,8 +2483,6 @@ static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr,
2457 encode_sequence(xdr, &args->seq_args, &hdr); 2483 encode_sequence(xdr, &args->seq_args, &hdr);
2458 encode_putfh(xdr, args->fh, &hdr); 2484 encode_putfh(xdr, args->fh, &hdr);
2459 encode_commit(xdr, args, &hdr); 2485 encode_commit(xdr, args, &hdr);
2460 if (args->bitmask)
2461 encode_getfattr(xdr, args->bitmask, &hdr);
2462 encode_nops(&hdr); 2486 encode_nops(&hdr);
2463} 2487}
2464 2488
@@ -2601,8 +2625,8 @@ static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req,
2601 encode_compound_hdr(xdr, req, &hdr); 2625 encode_compound_hdr(xdr, req, &hdr);
2602 encode_sequence(xdr, &args->seq_args, &hdr); 2626 encode_sequence(xdr, &args->seq_args, &hdr);
2603 encode_putfh(xdr, args->fhandle, &hdr); 2627 encode_putfh(xdr, args->fhandle, &hdr);
2604 encode_delegreturn(xdr, args->stateid, &hdr);
2605 encode_getfattr(xdr, args->bitmask, &hdr); 2628 encode_getfattr(xdr, args->bitmask, &hdr);
2629 encode_delegreturn(xdr, args->stateid, &hdr);
2606 encode_nops(&hdr); 2630 encode_nops(&hdr);
2607} 2631}
2608 2632
@@ -2650,6 +2674,22 @@ static void nfs4_xdr_enc_secinfo(struct rpc_rqst *req,
2650 2674
2651#if defined(CONFIG_NFS_V4_1) 2675#if defined(CONFIG_NFS_V4_1)
2652/* 2676/*
2677 * BIND_CONN_TO_SESSION request
2678 */
2679static void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req,
2680 struct xdr_stream *xdr,
2681 struct nfs_client *clp)
2682{
2683 struct compound_hdr hdr = {
2684 .minorversion = clp->cl_mvops->minor_version,
2685 };
2686
2687 encode_compound_hdr(xdr, req, &hdr);
2688 encode_bind_conn_to_session(xdr, clp->cl_session, &hdr);
2689 encode_nops(&hdr);
2690}
2691
2692/*
2653 * EXCHANGE_ID request 2693 * EXCHANGE_ID request
2654 */ 2694 */
2655static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, 2695static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req,
@@ -2698,6 +2738,22 @@ static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req,
2698} 2738}
2699 2739
2700/* 2740/*
2741 * a DESTROY_CLIENTID request
2742 */
2743static void nfs4_xdr_enc_destroy_clientid(struct rpc_rqst *req,
2744 struct xdr_stream *xdr,
2745 struct nfs_client *clp)
2746{
2747 struct compound_hdr hdr = {
2748 .minorversion = clp->cl_mvops->minor_version,
2749 };
2750
2751 encode_compound_hdr(xdr, req, &hdr);
2752 encode_destroy_clientid(xdr, clp->cl_clientid, &hdr);
2753 encode_nops(&hdr);
2754}
2755
2756/*
2701 * a SEQUENCE request 2757 * a SEQUENCE request
2702 */ 2758 */
2703static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr, 2759static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr,
@@ -4101,7 +4157,7 @@ static int decode_verifier(struct xdr_stream *xdr, void *verifier)
4101 return decode_opaque_fixed(xdr, verifier, NFS4_VERIFIER_SIZE); 4157 return decode_opaque_fixed(xdr, verifier, NFS4_VERIFIER_SIZE);
4102} 4158}
4103 4159
4104static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res) 4160static int decode_commit(struct xdr_stream *xdr, struct nfs_commitres *res)
4105{ 4161{
4106 int status; 4162 int status;
4107 4163
@@ -4219,6 +4275,110 @@ xdr_error:
4219 return status; 4275 return status;
4220} 4276}
4221 4277
4278static int decode_threshold_hint(struct xdr_stream *xdr,
4279 uint32_t *bitmap,
4280 uint64_t *res,
4281 uint32_t hint_bit)
4282{
4283 __be32 *p;
4284
4285 *res = 0;
4286 if (likely(bitmap[0] & hint_bit)) {
4287 p = xdr_inline_decode(xdr, 8);
4288 if (unlikely(!p))
4289 goto out_overflow;
4290 xdr_decode_hyper(p, res);
4291 }
4292 return 0;
4293out_overflow:
4294 print_overflow_msg(__func__, xdr);
4295 return -EIO;
4296}
4297
4298static int decode_first_threshold_item4(struct xdr_stream *xdr,
4299 struct nfs4_threshold *res)
4300{
4301 __be32 *p, *savep;
4302 uint32_t bitmap[3] = {0,}, attrlen;
4303 int status;
4304
4305 /* layout type */
4306 p = xdr_inline_decode(xdr, 4);
4307 if (unlikely(!p)) {
4308 print_overflow_msg(__func__, xdr);
4309 return -EIO;
4310 }
4311 res->l_type = be32_to_cpup(p);
4312
4313 /* thi_hintset bitmap */
4314 status = decode_attr_bitmap(xdr, bitmap);
4315 if (status < 0)
4316 goto xdr_error;
4317
4318 /* thi_hintlist length */
4319 status = decode_attr_length(xdr, &attrlen, &savep);
4320 if (status < 0)
4321 goto xdr_error;
4322 /* thi_hintlist */
4323 status = decode_threshold_hint(xdr, bitmap, &res->rd_sz, THRESHOLD_RD);
4324 if (status < 0)
4325 goto xdr_error;
4326 status = decode_threshold_hint(xdr, bitmap, &res->wr_sz, THRESHOLD_WR);
4327 if (status < 0)
4328 goto xdr_error;
4329 status = decode_threshold_hint(xdr, bitmap, &res->rd_io_sz,
4330 THRESHOLD_RD_IO);
4331 if (status < 0)
4332 goto xdr_error;
4333 status = decode_threshold_hint(xdr, bitmap, &res->wr_io_sz,
4334 THRESHOLD_WR_IO);
4335 if (status < 0)
4336 goto xdr_error;
4337
4338 status = verify_attr_len(xdr, savep, attrlen);
4339 res->bm = bitmap[0];
4340
4341 dprintk("%s bm=0x%x rd_sz=%llu wr_sz=%llu rd_io=%llu wr_io=%llu\n",
4342 __func__, res->bm, res->rd_sz, res->wr_sz, res->rd_io_sz,
4343 res->wr_io_sz);
4344xdr_error:
4345 dprintk("%s ret=%d!\n", __func__, status);
4346 return status;
4347}
4348
4349/*
4350 * Thresholds on pNFS direct I/O vrs MDS I/O
4351 */
4352static int decode_attr_mdsthreshold(struct xdr_stream *xdr,
4353 uint32_t *bitmap,
4354 struct nfs4_threshold *res)
4355{
4356 __be32 *p;
4357 int status = 0;
4358 uint32_t num;
4359
4360 if (unlikely(bitmap[2] & (FATTR4_WORD2_MDSTHRESHOLD - 1U)))
4361 return -EIO;
4362 if (likely(bitmap[2] & FATTR4_WORD2_MDSTHRESHOLD)) {
4363 p = xdr_inline_decode(xdr, 4);
4364 if (unlikely(!p))
4365 goto out_overflow;
4366 num = be32_to_cpup(p);
4367 if (num == 0)
4368 return 0;
4369 if (num > 1)
4370 printk(KERN_INFO "%s: Warning: Multiple pNFS layout "
4371 "drivers per filesystem not supported\n",
4372 __func__);
4373
4374 status = decode_first_threshold_item4(xdr, res);
4375 }
4376 return status;
4377out_overflow:
4378 print_overflow_msg(__func__, xdr);
4379 return -EIO;
4380}
4381
4222static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, 4382static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4223 struct nfs_fattr *fattr, struct nfs_fh *fh, 4383 struct nfs_fattr *fattr, struct nfs_fh *fh,
4224 struct nfs4_fs_locations *fs_loc, 4384 struct nfs4_fs_locations *fs_loc,
@@ -4257,8 +4417,6 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4257 status = decode_attr_error(xdr, bitmap, &err); 4417 status = decode_attr_error(xdr, bitmap, &err);
4258 if (status < 0) 4418 if (status < 0)
4259 goto xdr_error; 4419 goto xdr_error;
4260 if (err == -NFS4ERR_WRONGSEC)
4261 nfs_fixup_secinfo_attributes(fattr, fh);
4262 4420
4263 status = decode_attr_filehandle(xdr, bitmap, fh); 4421 status = decode_attr_filehandle(xdr, bitmap, fh);
4264 if (status < 0) 4422 if (status < 0)
@@ -4327,6 +4485,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
4327 goto xdr_error; 4485 goto xdr_error;
4328 fattr->valid |= status; 4486 fattr->valid |= status;
4329 4487
4488 status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold);
4489 if (status < 0)
4490 goto xdr_error;
4491
4330xdr_error: 4492xdr_error:
4331 dprintk("%s: xdr returned %d\n", __func__, -status); 4493 dprintk("%s: xdr returned %d\n", __func__, -status);
4332 return status; 4494 return status;
@@ -4901,11 +5063,19 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
4901 bitmap[3] = {0}; 5063 bitmap[3] = {0};
4902 struct kvec *iov = req->rq_rcv_buf.head; 5064 struct kvec *iov = req->rq_rcv_buf.head;
4903 int status; 5065 int status;
5066 size_t page_len = xdr->buf->page_len;
4904 5067
4905 res->acl_len = 0; 5068 res->acl_len = 0;
4906 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) 5069 if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
4907 goto out; 5070 goto out;
5071
4908 bm_p = xdr->p; 5072 bm_p = xdr->p;
5073 res->acl_data_offset = be32_to_cpup(bm_p) + 2;
5074 res->acl_data_offset <<= 2;
5075 /* Check if the acl data starts beyond the allocated buffer */
5076 if (res->acl_data_offset > page_len)
5077 return -ERANGE;
5078
4909 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) 5079 if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
4910 goto out; 5080 goto out;
4911 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) 5081 if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
@@ -4915,28 +5085,24 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
4915 return -EIO; 5085 return -EIO;
4916 if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { 5086 if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
4917 size_t hdrlen; 5087 size_t hdrlen;
4918 u32 recvd;
4919 5088
4920 /* The bitmap (xdr len + bitmaps) and the attr xdr len words 5089 /* The bitmap (xdr len + bitmaps) and the attr xdr len words
4921 * are stored with the acl data to handle the problem of 5090 * are stored with the acl data to handle the problem of
4922 * variable length bitmaps.*/ 5091 * variable length bitmaps.*/
4923 xdr->p = bm_p; 5092 xdr->p = bm_p;
4924 res->acl_data_offset = be32_to_cpup(bm_p) + 2;
4925 res->acl_data_offset <<= 2;
4926 5093
4927 /* We ignore &savep and don't do consistency checks on 5094 /* We ignore &savep and don't do consistency checks on
4928 * the attr length. Let userspace figure it out.... */ 5095 * the attr length. Let userspace figure it out.... */
4929 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; 5096 hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
4930 attrlen += res->acl_data_offset; 5097 attrlen += res->acl_data_offset;
4931 recvd = req->rq_rcv_buf.len - hdrlen; 5098 if (attrlen > page_len) {
4932 if (attrlen > recvd) {
4933 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { 5099 if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
4934 /* getxattr interface called with a NULL buf */ 5100 /* getxattr interface called with a NULL buf */
4935 res->acl_len = attrlen; 5101 res->acl_len = attrlen;
4936 goto out; 5102 goto out;
4937 } 5103 }
4938 dprintk("NFS: acl reply: attrlen %u > recvd %u\n", 5104 dprintk("NFS: acl reply: attrlen %u > page_len %zu\n",
4939 attrlen, recvd); 5105 attrlen, page_len);
4940 return -EINVAL; 5106 return -EINVAL;
4941 } 5107 }
4942 xdr_read_pages(xdr, attrlen); 5108 xdr_read_pages(xdr, attrlen);
@@ -5089,16 +5255,13 @@ out_err:
5089 return -EINVAL; 5255 return -EINVAL;
5090} 5256}
5091 5257
5092static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) 5258static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5093{ 5259{
5094 struct nfs4_secinfo_flavor *sec_flavor; 5260 struct nfs4_secinfo_flavor *sec_flavor;
5095 int status; 5261 int status;
5096 __be32 *p; 5262 __be32 *p;
5097 int i, num_flavors; 5263 int i, num_flavors;
5098 5264
5099 status = decode_op_hdr(xdr, OP_SECINFO);
5100 if (status)
5101 goto out;
5102 p = xdr_inline_decode(xdr, 4); 5265 p = xdr_inline_decode(xdr, 4);
5103 if (unlikely(!p)) 5266 if (unlikely(!p))
5104 goto out_overflow; 5267 goto out_overflow;
@@ -5124,6 +5287,7 @@ static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5124 res->flavors->num_flavors++; 5287 res->flavors->num_flavors++;
5125 } 5288 }
5126 5289
5290 status = 0;
5127out: 5291out:
5128 return status; 5292 return status;
5129out_overflow: 5293out_overflow:
@@ -5131,7 +5295,23 @@ out_overflow:
5131 return -EIO; 5295 return -EIO;
5132} 5296}
5133 5297
5298static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5299{
5300 int status = decode_op_hdr(xdr, OP_SECINFO);
5301 if (status)
5302 return status;
5303 return decode_secinfo_common(xdr, res);
5304}
5305
5134#if defined(CONFIG_NFS_V4_1) 5306#if defined(CONFIG_NFS_V4_1)
5307static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
5308{
5309 int status = decode_op_hdr(xdr, OP_SECINFO_NO_NAME);
5310 if (status)
5311 return status;
5312 return decode_secinfo_common(xdr, res);
5313}
5314
5135static int decode_exchange_id(struct xdr_stream *xdr, 5315static int decode_exchange_id(struct xdr_stream *xdr,
5136 struct nfs41_exchange_id_res *res) 5316 struct nfs41_exchange_id_res *res)
5137{ 5317{
@@ -5139,7 +5319,6 @@ static int decode_exchange_id(struct xdr_stream *xdr,
5139 uint32_t dummy; 5319 uint32_t dummy;
5140 char *dummy_str; 5320 char *dummy_str;
5141 int status; 5321 int status;
5142 struct nfs_client *clp = res->client;
5143 uint32_t impl_id_count; 5322 uint32_t impl_id_count;
5144 5323
5145 status = decode_op_hdr(xdr, OP_EXCHANGE_ID); 5324 status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
@@ -5149,36 +5328,39 @@ static int decode_exchange_id(struct xdr_stream *xdr,
5149 p = xdr_inline_decode(xdr, 8); 5328 p = xdr_inline_decode(xdr, 8);
5150 if (unlikely(!p)) 5329 if (unlikely(!p))
5151 goto out_overflow; 5330 goto out_overflow;
5152 xdr_decode_hyper(p, &clp->cl_clientid); 5331 xdr_decode_hyper(p, &res->clientid);
5153 p = xdr_inline_decode(xdr, 12); 5332 p = xdr_inline_decode(xdr, 12);
5154 if (unlikely(!p)) 5333 if (unlikely(!p))
5155 goto out_overflow; 5334 goto out_overflow;
5156 clp->cl_seqid = be32_to_cpup(p++); 5335 res->seqid = be32_to_cpup(p++);
5157 clp->cl_exchange_flags = be32_to_cpup(p++); 5336 res->flags = be32_to_cpup(p++);
5158 5337
5159 /* We ask for SP4_NONE */ 5338 /* We ask for SP4_NONE */
5160 dummy = be32_to_cpup(p); 5339 dummy = be32_to_cpup(p);
5161 if (dummy != SP4_NONE) 5340 if (dummy != SP4_NONE)
5162 return -EIO; 5341 return -EIO;
5163 5342
5164 /* Throw away minor_id */ 5343 /* server_owner4.so_minor_id */
5165 p = xdr_inline_decode(xdr, 8); 5344 p = xdr_inline_decode(xdr, 8);
5166 if (unlikely(!p)) 5345 if (unlikely(!p))
5167 goto out_overflow; 5346 goto out_overflow;
5347 p = xdr_decode_hyper(p, &res->server_owner->minor_id);
5168 5348
5169 /* Throw away Major id */ 5349 /* server_owner4.so_major_id */
5170 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 5350 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
5171 if (unlikely(status)) 5351 if (unlikely(status))
5172 return status; 5352 return status;
5353 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
5354 return -EIO;
5355 memcpy(res->server_owner->major_id, dummy_str, dummy);
5356 res->server_owner->major_id_sz = dummy;
5173 5357
5174 /* Save server_scope */ 5358 /* server_scope4 */
5175 status = decode_opaque_inline(xdr, &dummy, &dummy_str); 5359 status = decode_opaque_inline(xdr, &dummy, &dummy_str);
5176 if (unlikely(status)) 5360 if (unlikely(status))
5177 return status; 5361 return status;
5178
5179 if (unlikely(dummy > NFS4_OPAQUE_LIMIT)) 5362 if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
5180 return -EIO; 5363 return -EIO;
5181
5182 memcpy(res->server_scope->server_scope, dummy_str, dummy); 5364 memcpy(res->server_scope->server_scope, dummy_str, dummy);
5183 res->server_scope->server_scope_sz = dummy; 5365 res->server_scope->server_scope_sz = dummy;
5184 5366
@@ -5259,6 +5441,37 @@ static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid)
5259 return decode_opaque_fixed(xdr, sid->data, NFS4_MAX_SESSIONID_LEN); 5441 return decode_opaque_fixed(xdr, sid->data, NFS4_MAX_SESSIONID_LEN);
5260} 5442}
5261 5443
5444static int decode_bind_conn_to_session(struct xdr_stream *xdr,
5445 struct nfs41_bind_conn_to_session_res *res)
5446{
5447 __be32 *p;
5448 int status;
5449
5450 status = decode_op_hdr(xdr, OP_BIND_CONN_TO_SESSION);
5451 if (!status)
5452 status = decode_sessionid(xdr, &res->session->sess_id);
5453 if (unlikely(status))
5454 return status;
5455
5456 /* dir flags, rdma mode bool */
5457 p = xdr_inline_decode(xdr, 8);
5458 if (unlikely(!p))
5459 goto out_overflow;
5460
5461 res->dir = be32_to_cpup(p++);
5462 if (res->dir == 0 || res->dir > NFS4_CDFS4_BOTH)
5463 return -EIO;
5464 if (be32_to_cpup(p) == 0)
5465 res->use_conn_in_rdma_mode = false;
5466 else
5467 res->use_conn_in_rdma_mode = true;
5468
5469 return 0;
5470out_overflow:
5471 print_overflow_msg(__func__, xdr);
5472 return -EIO;
5473}
5474
5262static int decode_create_session(struct xdr_stream *xdr, 5475static int decode_create_session(struct xdr_stream *xdr,
5263 struct nfs41_create_session_res *res) 5476 struct nfs41_create_session_res *res)
5264{ 5477{
@@ -5295,6 +5508,11 @@ static int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
5295 return decode_op_hdr(xdr, OP_DESTROY_SESSION); 5508 return decode_op_hdr(xdr, OP_DESTROY_SESSION);
5296} 5509}
5297 5510
5511static int decode_destroy_clientid(struct xdr_stream *xdr, void *dummy)
5512{
5513 return decode_op_hdr(xdr, OP_DESTROY_CLIENTID);
5514}
5515
5298static int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy) 5516static int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy)
5299{ 5517{
5300 return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE); 5518 return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE);
@@ -5783,9 +6001,6 @@ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5783 if (status) 6001 if (status)
5784 goto out; 6002 goto out;
5785 status = decode_remove(xdr, &res->cinfo); 6003 status = decode_remove(xdr, &res->cinfo);
5786 if (status)
5787 goto out;
5788 decode_getfattr(xdr, res->dir_attr, res->server);
5789out: 6004out:
5790 return status; 6005 return status;
5791} 6006}
@@ -5815,15 +6030,6 @@ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5815 if (status) 6030 if (status)
5816 goto out; 6031 goto out;
5817 status = decode_rename(xdr, &res->old_cinfo, &res->new_cinfo); 6032 status = decode_rename(xdr, &res->old_cinfo, &res->new_cinfo);
5818 if (status)
5819 goto out;
5820 /* Current FH is target directory */
5821 if (decode_getfattr(xdr, res->new_fattr, res->server))
5822 goto out;
5823 status = decode_restorefh(xdr);
5824 if (status)
5825 goto out;
5826 decode_getfattr(xdr, res->old_fattr, res->server);
5827out: 6033out:
5828 return status; 6034 return status;
5829} 6035}
@@ -5859,8 +6065,6 @@ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5859 * Note order: OP_LINK leaves the directory as the current 6065 * Note order: OP_LINK leaves the directory as the current
5860 * filehandle. 6066 * filehandle.
5861 */ 6067 */
5862 if (decode_getfattr(xdr, res->dir_attr, res->server))
5863 goto out;
5864 status = decode_restorefh(xdr); 6068 status = decode_restorefh(xdr);
5865 if (status) 6069 if (status)
5866 goto out; 6070 goto out;
@@ -5887,21 +6091,13 @@ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
5887 status = decode_putfh(xdr); 6091 status = decode_putfh(xdr);
5888 if (status) 6092 if (status)
5889 goto out; 6093 goto out;
5890 status = decode_savefh(xdr);
5891 if (status)
5892 goto out;
5893 status = decode_create(xdr, &res->dir_cinfo); 6094 status = decode_create(xdr, &res->dir_cinfo);
5894 if (status) 6095 if (status)
5895 goto out; 6096 goto out;
5896 status = decode_getfh(xdr, res->fh); 6097 status = decode_getfh(xdr, res->fh);
5897 if (status) 6098 if (status)
5898 goto out; 6099 goto out;
5899 if (decode_getfattr(xdr, res->fattr, res->server)) 6100 decode_getfattr(xdr, res->fattr, res->server);
5900 goto out;
5901 status = decode_restorefh(xdr);
5902 if (status)
5903 goto out;
5904 decode_getfattr(xdr, res->dir_fattr, res->server);
5905out: 6101out:
5906 return status; 6102 return status;
5907} 6103}
@@ -6058,19 +6254,12 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6058 status = decode_putfh(xdr); 6254 status = decode_putfh(xdr);
6059 if (status) 6255 if (status)
6060 goto out; 6256 goto out;
6061 status = decode_savefh(xdr);
6062 if (status)
6063 goto out;
6064 status = decode_open(xdr, res); 6257 status = decode_open(xdr, res);
6065 if (status) 6258 if (status)
6066 goto out; 6259 goto out;
6067 if (decode_getfh(xdr, &res->fh) != 0) 6260 if (decode_getfh(xdr, &res->fh) != 0)
6068 goto out; 6261 goto out;
6069 if (decode_getfattr(xdr, res->f_attr, res->server) != 0) 6262 decode_getfattr(xdr, res->f_attr, res->server);
6070 goto out;
6071 if (decode_restorefh(xdr) != 0)
6072 goto out;
6073 decode_getfattr(xdr, res->dir_attr, res->server);
6074out: 6263out:
6075 return status; 6264 return status;
6076} 6265}
@@ -6336,7 +6525,7 @@ out:
6336 * Decode COMMIT response 6525 * Decode COMMIT response
6337 */ 6526 */
6338static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr, 6527static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6339 struct nfs_writeres *res) 6528 struct nfs_commitres *res)
6340{ 6529{
6341 struct compound_hdr hdr; 6530 struct compound_hdr hdr;
6342 int status; 6531 int status;
@@ -6351,10 +6540,6 @@ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
6351 if (status) 6540 if (status)
6352 goto out; 6541 goto out;
6353 status = decode_commit(xdr, res); 6542 status = decode_commit(xdr, res);
6354 if (status)
6355 goto out;
6356 if (res->fattr)
6357 decode_getfattr(xdr, res->fattr, res->server);
6358out: 6543out:
6359 return status; 6544 return status;
6360} 6545}
@@ -6510,10 +6695,10 @@ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp,
6510 status = decode_putfh(xdr); 6695 status = decode_putfh(xdr);
6511 if (status != 0) 6696 if (status != 0)
6512 goto out; 6697 goto out;
6513 status = decode_delegreturn(xdr); 6698 status = decode_getfattr(xdr, res->fattr, res->server);
6514 if (status != 0) 6699 if (status != 0)
6515 goto out; 6700 goto out;
6516 decode_getfattr(xdr, res->fattr, res->server); 6701 status = decode_delegreturn(xdr);
6517out: 6702out:
6518 return status; 6703 return status;
6519} 6704}
@@ -6574,6 +6759,22 @@ out:
6574 6759
6575#if defined(CONFIG_NFS_V4_1) 6760#if defined(CONFIG_NFS_V4_1)
6576/* 6761/*
6762 * Decode BIND_CONN_TO_SESSION response
6763 */
6764static int nfs4_xdr_dec_bind_conn_to_session(struct rpc_rqst *rqstp,
6765 struct xdr_stream *xdr,
6766 void *res)
6767{
6768 struct compound_hdr hdr;
6769 int status;
6770
6771 status = decode_compound_hdr(xdr, &hdr);
6772 if (!status)
6773 status = decode_bind_conn_to_session(xdr, res);
6774 return status;
6775}
6776
6777/*
6577 * Decode EXCHANGE_ID response 6778 * Decode EXCHANGE_ID response
6578 */ 6779 */
6579static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, 6780static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp,
@@ -6622,6 +6823,22 @@ static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp,
6622} 6823}
6623 6824
6624/* 6825/*
6826 * Decode DESTROY_CLIENTID response
6827 */
6828static int nfs4_xdr_dec_destroy_clientid(struct rpc_rqst *rqstp,
6829 struct xdr_stream *xdr,
6830 void *res)
6831{
6832 struct compound_hdr hdr;
6833 int status;
6834
6835 status = decode_compound_hdr(xdr, &hdr);
6836 if (!status)
6837 status = decode_destroy_clientid(xdr, res);
6838 return status;
6839}
6840
6841/*
6625 * Decode SEQUENCE response 6842 * Decode SEQUENCE response
6626 */ 6843 */
6627static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, 6844static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp,
@@ -6816,7 +7033,7 @@ static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp,
6816 status = decode_putrootfh(xdr); 7033 status = decode_putrootfh(xdr);
6817 if (status) 7034 if (status)
6818 goto out; 7035 goto out;
6819 status = decode_secinfo(xdr, res); 7036 status = decode_secinfo_no_name(xdr, res);
6820out: 7037out:
6821 return status; 7038 return status;
6822} 7039}
@@ -7068,6 +7285,9 @@ struct rpc_procinfo nfs4_procedures[] = {
7068 PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid), 7285 PROC(TEST_STATEID, enc_test_stateid, dec_test_stateid),
7069 PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid), 7286 PROC(FREE_STATEID, enc_free_stateid, dec_free_stateid),
7070 PROC(GETDEVICELIST, enc_getdevicelist, dec_getdevicelist), 7287 PROC(GETDEVICELIST, enc_getdevicelist, dec_getdevicelist),
7288 PROC(BIND_CONN_TO_SESSION,
7289 enc_bind_conn_to_session, dec_bind_conn_to_session),
7290 PROC(DESTROY_CLIENTID, enc_destroy_clientid, dec_destroy_clientid),
7071#endif /* CONFIG_NFS_V4_1 */ 7291#endif /* CONFIG_NFS_V4_1 */
7072}; 7292};
7073 7293