Blame view

fs/nfs/nfs4xdr.c 184 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
  /*
   *  fs/nfs/nfs4xdr.c
   *
   *  Client-side XDR for NFSv4.
   *
   *  Copyright (c) 2002 The Regents of the University of Michigan.
   *  All rights reserved.
   *
   *  Kendrick Smith <kmsmith@umich.edu>
   *  Andy Adamson   <andros@umich.edu>
6c0195a46   Andy Adamson   NFS: remove white...
11
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
   *  Redistribution and use in source and binary forms, with or without
   *  modification, are permitted provided that the following conditions
   *  are met:
   *
   *  1. Redistributions of source code must retain the above copyright
   *     notice, this list of conditions and the following disclaimer.
   *  2. Redistributions in binary form must reproduce the above copyright
   *     notice, this list of conditions and the following disclaimer in the
   *     documentation and/or other materials provided with the distribution.
   *  3. Neither the name of the University nor the names of its
   *     contributors may be used to endorse or promote products derived
   *     from this software without specific prior written permission.
   *
   *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
   *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
   *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  #include <linux/param.h>
  #include <linux/time.h>
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
44
45
46
47
  #include <linux/errno.h>
  #include <linux/string.h>
  #include <linux/in.h>
  #include <linux/pagemap.h>
  #include <linux/proc_fs.h>
  #include <linux/kdev_t.h>
  #include <linux/sunrpc/clnt.h>
2449ea2e1   Alexandros Batsakis   nfs41: V2 adjust ...
48
  #include <linux/sunrpc/msg_prot.h>
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
49
  #include <linux/sunrpc/gss_api.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
53
  #include <linux/nfs.h>
  #include <linux/nfs4.h>
  #include <linux/nfs_fs.h>
  #include <linux/nfs_idmap.h>
4ce79717c   Trond Myklebust   [PATCH] NFS: Head...
54
  #include "nfs4_fs.h"
4882ef72c   Alexandros Batsakis   nfs41: add suppor...
55
  #include "internal.h"
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
56
  #include "pnfs.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
  
  #define NFSDBG_FACILITY		NFSDBG_XDR
  
  /* Mapping from NFS error code to "errno" error code. */
  #define errno_NFSERR_IO		EIO
0a8ea4372   David Howells   NFS: Disambiguate...
62
  static int nfs4_stat_to_errno(int);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
66
67
68
69
  
  /* NFSv4 COMPOUND tags are only wanted for debugging purposes */
  #ifdef DEBUG
  #define NFS4_MAXTAGLEN		20
  #else
  #define NFS4_MAXTAGLEN		0
  #endif
6c0195a46   Andy Adamson   NFS: remove white...
70
  /* lock,open owner id:
9f958ab88   Trond Myklebust   NFSv4: Reduce the...
71
   * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT  >> 2)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
   */
d035c36c5   Trond Myklebust   NFSv4: Ensure con...
73
74
  #define open_owner_id_maxsz	(1 + 1 + 4)
  #define lock_owner_id_maxsz	(1 + 1 + 4)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
75
  #define decode_lockowner_maxsz	(1 + XDR_QUADLEN(IDMAP_NAMESZ))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
77
78
79
  #define compound_encode_hdr_maxsz	(3 + (NFS4_MAXTAGLEN >> 2))
  #define compound_decode_hdr_maxsz	(3 + (NFS4_MAXTAGLEN >> 2))
  #define op_encode_hdr_maxsz	(1)
  #define op_decode_hdr_maxsz	(2)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
80
81
82
83
  #define encode_stateid_maxsz	(XDR_QUADLEN(NFS4_STATEID_SIZE))
  #define decode_stateid_maxsz	(XDR_QUADLEN(NFS4_STATEID_SIZE))
  #define encode_verifier_maxsz	(XDR_QUADLEN(NFS4_VERIFIER_SIZE))
  #define decode_verifier_maxsz	(XDR_QUADLEN(NFS4_VERIFIER_SIZE))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
88
89
90
91
  #define encode_putfh_maxsz	(op_encode_hdr_maxsz + 1 + \
  				(NFS4_FHSIZE >> 2))
  #define decode_putfh_maxsz	(op_decode_hdr_maxsz)
  #define encode_putrootfh_maxsz	(op_encode_hdr_maxsz)
  #define decode_putrootfh_maxsz	(op_decode_hdr_maxsz)
  #define encode_getfh_maxsz      (op_encode_hdr_maxsz)
  #define decode_getfh_maxsz      (op_decode_hdr_maxsz + 1 + \
  				((3+NFS4_FHSIZE) >> 2))
e5012d1f3   Andy Adamson   NFSv4.1: update n...
92
  #define nfs4_fattr_bitmap_maxsz 4
969282069   J. Bruce Fields   [PATCH] NFSv4: fi...
93
  #define encode_getattr_maxsz    (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
95
  #define nfs4_name_maxsz		(1 + ((3 + NFS4_MAXNAMLEN) >> 2))
  #define nfs4_path_maxsz		(1 + ((3 + NFS4_MAXPATHLEN) >> 2))
bd625ba80   Trond Myklebust   NFSv4: Fix the NF...
96
97
  #define nfs4_owner_maxsz	(1 + XDR_QUADLEN(IDMAP_NAMESZ))
  #define nfs4_group_maxsz	(1 + XDR_QUADLEN(IDMAP_NAMESZ))
969282069   J. Bruce Fields   [PATCH] NFSv4: fi...
98
99
  /* This is based on getfattr, which uses the most attributes: */
  #define nfs4_fattr_value_maxsz	(1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
bd625ba80   Trond Myklebust   NFSv4: Fix the NF...
100
  				3 + 3 + 3 + nfs4_owner_maxsz + nfs4_group_maxsz))
969282069   J. Bruce Fields   [PATCH] NFSv4: fi...
101
102
103
  #define nfs4_fattr_maxsz	(nfs4_fattr_bitmap_maxsz + \
  				nfs4_fattr_value_maxsz)
  #define decode_getattr_maxsz    (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
104
105
106
107
108
  #define encode_attrs_maxsz	(nfs4_fattr_bitmap_maxsz + \
  				 1 + 2 + 1 + \
  				nfs4_owner_maxsz + \
  				nfs4_group_maxsz + \
  				4 + 4)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
  #define encode_savefh_maxsz     (op_encode_hdr_maxsz)
  #define decode_savefh_maxsz     (op_decode_hdr_maxsz)
56ae19f38   Trond Myklebust   NFSv4: Add direct...
111
112
  #define encode_restorefh_maxsz  (op_encode_hdr_maxsz)
  #define decode_restorefh_maxsz  (op_decode_hdr_maxsz)
2f42b5d04   Fred Isaman   NFS: fix encode_f...
113
  #define encode_fsinfo_maxsz	(encode_getattr_maxsz)
dae100c2b   Fred Isaman   pnfs: ask for lay...
114
115
116
117
118
  /* The 5 accounts for the PNFS attributes, and assumes that at most three
   * layout types will be returned.
   */
  #define decode_fsinfo_maxsz	(op_decode_hdr_maxsz + \
  				 nfs4_fattr_bitmap_maxsz + 4 + 8 + 5)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119
120
121
122
  #define encode_renew_maxsz	(op_encode_hdr_maxsz + 3)
  #define decode_renew_maxsz	(op_decode_hdr_maxsz)
  #define encode_setclientid_maxsz \
  				(op_encode_hdr_maxsz + \
cc38bac3a   Chuck Lever   NFS: Ensure NFSv4...
123
124
125
126
127
128
  				XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
  				XDR_QUADLEN(NFS4_SETCLIENTID_NAMELEN) + \
  				1 /* sc_prog */ + \
  				XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
  				XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \
  				1) /* sc_cb_ident */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
134
135
136
137
  #define decode_setclientid_maxsz \
  				(op_decode_hdr_maxsz + \
  				2 + \
  				1024) /* large value for CLID_INUSE */
  #define encode_setclientid_confirm_maxsz \
  				(op_encode_hdr_maxsz + \
  				3 + (NFS4_VERIFIER_SIZE >> 2))
  #define decode_setclientid_confirm_maxsz \
  				(op_decode_hdr_maxsz)
e6889620e   Trond Myklebust   NFSv4: Fix undere...
138
139
  #define encode_lookup_maxsz	(op_encode_hdr_maxsz + nfs4_name_maxsz)
  #define decode_lookup_maxsz	(op_decode_hdr_maxsz)
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
140
141
  #define encode_share_access_maxsz \
  				(2)
4882ef72c   Alexandros Batsakis   nfs41: add suppor...
142
  #define encode_createmode_maxsz	(1 + encode_attrs_maxsz + encode_verifier_maxsz)
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
143
144
145
146
147
148
149
150
  #define encode_opentype_maxsz	(1 + encode_createmode_maxsz)
  #define encode_claim_null_maxsz	(1 + nfs4_name_maxsz)
  #define encode_open_maxsz	(op_encode_hdr_maxsz + \
  				2 + encode_share_access_maxsz + 2 + \
  				open_owner_id_maxsz + \
  				encode_opentype_maxsz + \
  				encode_claim_null_maxsz)
  #define decode_ace_maxsz	(3 + nfs4_owner_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
151
  #define decode_delegation_maxsz	(1 + decode_stateid_maxsz + 1 + \
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
152
153
154
  				decode_ace_maxsz)
  #define decode_change_info_maxsz	(5)
  #define decode_open_maxsz	(op_decode_hdr_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
155
  				decode_stateid_maxsz + \
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
156
157
158
  				decode_change_info_maxsz + 1 + \
  				nfs4_fattr_bitmap_maxsz + \
  				decode_delegation_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
  #define encode_open_confirm_maxsz \
  				(op_encode_hdr_maxsz + \
  				 encode_stateid_maxsz + 1)
  #define decode_open_confirm_maxsz \
  				(op_decode_hdr_maxsz + \
  				 decode_stateid_maxsz)
  #define encode_open_downgrade_maxsz \
  				(op_encode_hdr_maxsz + \
  				 encode_stateid_maxsz + 1 + \
  				 encode_share_access_maxsz)
  #define decode_open_downgrade_maxsz \
  				(op_decode_hdr_maxsz + \
  				 decode_stateid_maxsz)
  #define encode_close_maxsz	(op_encode_hdr_maxsz + \
  				 1 + encode_stateid_maxsz)
  #define decode_close_maxsz	(op_decode_hdr_maxsz + \
  				 decode_stateid_maxsz)
  #define encode_setattr_maxsz	(op_encode_hdr_maxsz + \
  				 encode_stateid_maxsz + \
  				 encode_attrs_maxsz)
  #define decode_setattr_maxsz	(op_decode_hdr_maxsz + \
  				 nfs4_fattr_bitmap_maxsz)
  #define encode_read_maxsz	(op_encode_hdr_maxsz + \
  				 encode_stateid_maxsz + 3)
  #define decode_read_maxsz	(op_decode_hdr_maxsz + 2)
  #define encode_readdir_maxsz	(op_encode_hdr_maxsz + \
  				 2 + encode_verifier_maxsz + 5)
  #define decode_readdir_maxsz	(op_decode_hdr_maxsz + \
  				 decode_verifier_maxsz)
  #define encode_readlink_maxsz	(op_encode_hdr_maxsz)
  #define decode_readlink_maxsz	(op_decode_hdr_maxsz + 1)
  #define encode_write_maxsz	(op_encode_hdr_maxsz + \
  				 encode_stateid_maxsz + 4)
  #define decode_write_maxsz	(op_decode_hdr_maxsz + \
  				 2 + decode_verifier_maxsz)
  #define encode_commit_maxsz	(op_encode_hdr_maxsz + 3)
  #define decode_commit_maxsz	(op_decode_hdr_maxsz + \
  				 decode_verifier_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
  #define encode_remove_maxsz	(op_encode_hdr_maxsz + \
  				nfs4_name_maxsz)
6ce183919   Benny Halevy   NFS: use decode_c...
199
200
  #define decode_remove_maxsz	(op_decode_hdr_maxsz + \
  				 decode_change_info_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
  #define encode_rename_maxsz	(op_encode_hdr_maxsz + \
  				2 * nfs4_name_maxsz)
6ce183919   Benny Halevy   NFS: use decode_c...
203
204
205
  #define decode_rename_maxsz	(op_decode_hdr_maxsz + \
  				 decode_change_info_maxsz + \
  				 decode_change_info_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
207
  #define encode_link_maxsz	(op_encode_hdr_maxsz + \
  				nfs4_name_maxsz)
6ce183919   Benny Halevy   NFS: use decode_c...
208
  #define decode_link_maxsz	(op_decode_hdr_maxsz + decode_change_info_maxsz)
daccbded7   Trond Myklebust   NFSv4: Clean up f...
209
  #define encode_lockowner_maxsz	(7)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
210
211
  #define encode_lock_maxsz	(op_encode_hdr_maxsz + \
  				 7 + \
daccbded7   Trond Myklebust   NFSv4: Clean up f...
212
213
  				 1 + encode_stateid_maxsz + 1 + \
  				 encode_lockowner_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
214
215
216
217
  #define decode_lock_denied_maxsz \
  				(8 + decode_lockowner_maxsz)
  #define decode_lock_maxsz	(op_decode_hdr_maxsz + \
  				 decode_lock_denied_maxsz)
daccbded7   Trond Myklebust   NFSv4: Clean up f...
218
219
  #define encode_lockt_maxsz	(op_encode_hdr_maxsz + 5 + \
  				encode_lockowner_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
220
221
222
223
224
225
226
  #define decode_lockt_maxsz	(op_decode_hdr_maxsz + \
  				 decode_lock_denied_maxsz)
  #define encode_locku_maxsz	(op_encode_hdr_maxsz + 3 + \
  				 encode_stateid_maxsz + \
  				 4)
  #define decode_locku_maxsz	(op_decode_hdr_maxsz + \
  				 decode_stateid_maxsz)
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
227
228
229
230
231
  #define encode_release_lockowner_maxsz \
  				(op_encode_hdr_maxsz + \
  				 encode_lockowner_maxsz)
  #define decode_release_lockowner_maxsz \
  				(op_decode_hdr_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
232
233
  #define encode_access_maxsz	(op_encode_hdr_maxsz + 1)
  #define decode_access_maxsz	(op_decode_hdr_maxsz + 2)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
  #define encode_symlink_maxsz	(op_encode_hdr_maxsz + \
  				1 + nfs4_name_maxsz + \
94a6d7532   Chuck Lever   NFS: Use cached p...
236
  				1 + \
969282069   J. Bruce Fields   [PATCH] NFSv4: fi...
237
  				nfs4_fattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238
239
  #define decode_symlink_maxsz	(op_decode_hdr_maxsz + 8)
  #define encode_create_maxsz	(op_encode_hdr_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
240
241
  				1 + 2 + nfs4_name_maxsz + \
  				encode_attrs_maxsz)
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
242
243
244
  #define decode_create_maxsz	(op_decode_hdr_maxsz + \
  				decode_change_info_maxsz + \
  				nfs4_fattr_bitmap_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
245
246
  #define encode_statfs_maxsz	(encode_getattr_maxsz)
  #define decode_statfs_maxsz	(decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
  #define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)
  #define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
249
250
251
252
253
254
  #define encode_getacl_maxsz	(encode_getattr_maxsz)
  #define decode_getacl_maxsz	(op_decode_hdr_maxsz + \
  				 nfs4_fattr_bitmap_maxsz + 1)
  #define encode_setacl_maxsz	(op_encode_hdr_maxsz + \
  				 encode_stateid_maxsz + 3)
  #define decode_setacl_maxsz	(decode_setattr_maxsz)
e6889620e   Trond Myklebust   NFSv4: Fix undere...
255
256
257
258
  #define encode_fs_locations_maxsz \
  				(encode_getattr_maxsz)
  #define decode_fs_locations_maxsz \
  				(0)
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
259
  #define encode_secinfo_maxsz	(op_encode_hdr_maxsz + nfs4_name_maxsz)
1650add23   Bryan Schumaker   NFS: Fix decode_s...
260
  #define decode_secinfo_maxsz	(op_decode_hdr_maxsz + 1 + ((NFS_MAX_SECFLAVORS * (16 + GSS_OID_MAX_LEN)) / 4))
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
261
262
  
  #if defined(CONFIG_NFS_V4_1)
fc931582c   Andy Adamson   nfs41: create_ses...
263
  #define NFS4_MAX_MACHINE_NAME_LEN (64)
99fe60d06   Benny Halevy   nfs41: exchange_i...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  #define encode_exchange_id_maxsz (op_encode_hdr_maxsz + \
  				encode_verifier_maxsz + \
  				1 /* co_ownerid.len */ + \
  				XDR_QUADLEN(NFS4_EXCHANGE_ID_LEN) + \
  				1 /* flags */ + \
  				1 /* spa_how */ + \
  				0 /* SP4_NONE (for now) */ + \
  				1 /* zero implemetation id array */)
  #define decode_exchange_id_maxsz (op_decode_hdr_maxsz + \
  				2 /* eir_clientid */ + \
  				1 /* eir_sequenceid */ + \
  				1 /* eir_flags */ + \
  				1 /* spr_how */ + \
  				0 /* SP4_NONE (for now) */ + \
  				2 /* eir_server_owner.so_minor_id */ + \
  				/* eir_server_owner.so_major_id<> */ \
  				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
  				/* eir_server_scope<> */ \
  				XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 + \
  				1 /* eir_server_impl_id array length */ + \
  				0 /* ignored eir_server_impl_id contents */)
fc931582c   Andy Adamson   nfs41: create_ses...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  #define encode_channel_attrs_maxsz  (6 + 1 /* ca_rdma_ird.len (0) */)
  #define decode_channel_attrs_maxsz  (6 + \
  				     1 /* ca_rdma_ird.len */ + \
  				     1 /* ca_rdma_ird */)
  #define encode_create_session_maxsz  (op_encode_hdr_maxsz + \
  				     2 /* csa_clientid */ + \
  				     1 /* csa_sequence */ + \
  				     1 /* csa_flags */ + \
  				     encode_channel_attrs_maxsz + \
  				     encode_channel_attrs_maxsz + \
  				     1 /* csa_cb_program */ + \
  				     1 /* csa_sec_parms.len (1) */ + \
  				     1 /* cb_secflavor (AUTH_SYS) */ + \
  				     1 /* stamp */ + \
  				     1 /* machinename.len */ + \
  				     XDR_QUADLEN(NFS4_MAX_MACHINE_NAME_LEN) + \
  				     1 /* uid */ + \
  				     1 /* gid */ + \
  				     1 /* gids.len (0) */)
  #define decode_create_session_maxsz  (op_decode_hdr_maxsz +	\
  				     XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + \
  				     1 /* csr_sequence */ + \
  				     1 /* csr_flags */ + \
  				     decode_channel_attrs_maxsz + \
  				     decode_channel_attrs_maxsz)
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
310
311
  #define encode_destroy_session_maxsz    (op_encode_hdr_maxsz + 4)
  #define decode_destroy_session_maxsz    (op_decode_hdr_maxsz)
fc01cea96   Andy Adamson   nfs41: sequence o...
312
313
314
315
  #define encode_sequence_maxsz	(op_encode_hdr_maxsz + \
  				XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 4)
  #define decode_sequence_maxsz	(op_decode_hdr_maxsz + \
  				XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN) + 5)
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
316
317
  #define encode_reclaim_complete_maxsz	(op_encode_hdr_maxsz + 4)
  #define decode_reclaim_complete_maxsz	(op_decode_hdr_maxsz + 4)
7f11d8d38   Andy Adamson   pnfs: GETDEVICELIST
318
319
320
321
322
323
324
325
326
327
328
  #define encode_getdevicelist_maxsz (op_encode_hdr_maxsz + 4 + \
  				encode_verifier_maxsz)
  #define decode_getdevicelist_maxsz (op_decode_hdr_maxsz + \
  				2 /* nfs_cookie4 gdlr_cookie */ + \
  				decode_verifier_maxsz \
  				  /* verifier4 gdlr_verifier */ + \
  				1 /* gdlr_deviceid_list count */ + \
  				XDR_QUADLEN(NFS4_PNFS_GETDEVLIST_MAXNUM * \
  					    NFS4_DEVICEID4_SIZE) \
  				  /* gdlr_deviceid_list */ + \
  				1 /* bool gdlr_eof */)
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
329
330
331
332
333
334
335
336
337
338
339
340
341
  #define encode_getdeviceinfo_maxsz (op_encode_hdr_maxsz + 4 + \
  				XDR_QUADLEN(NFS4_DEVICEID4_SIZE))
  #define decode_getdeviceinfo_maxsz (op_decode_hdr_maxsz + \
  				1 /* layout type */ + \
  				1 /* opaque devaddr4 length */ + \
  				  /* devaddr4 payload is read into page */ \
  				1 /* notification bitmap length */ + \
  				1 /* notification bitmap */)
  #define encode_layoutget_maxsz	(op_encode_hdr_maxsz + 10 + \
  				encode_stateid_maxsz)
  #define decode_layoutget_maxsz	(op_decode_hdr_maxsz + 8 + \
  				decode_stateid_maxsz + \
  				XDR_QUADLEN(PNFS_LAYOUT_MAXSIZE))
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
342
343
344
345
346
347
348
349
350
351
352
  #define encode_layoutcommit_maxsz (op_encode_hdr_maxsz +          \
  				2 /* offset */ + \
  				2 /* length */ + \
  				1 /* reclaim */ + \
  				encode_stateid_maxsz + \
  				1 /* new offset (true) */ + \
  				2 /* last byte written */ + \
  				1 /* nt_timechanged (false) */ + \
  				1 /* layoutupdate4 layout type */ + \
  				1 /* NULL filelayout layoutupdate4 payload */)
  #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3)
cbe826036   Benny Halevy   pnfs: layoutreturn
353
354
355
356
357
  #define encode_layoutreturn_maxsz (8 + op_encode_hdr_maxsz + \
  				encode_stateid_maxsz + \
  				1 /* FIXME: opaque lrf_body always empty at the moment */)
  #define decode_layoutreturn_maxsz (op_decode_hdr_maxsz + \
  				1 + decode_stateid_maxsz)
fca78d6d2   Bryan Schumaker   NFS: Add SECINFO_...
358
359
  #define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 1)
  #define decode_secinfo_no_name_maxsz decode_secinfo_maxsz
7d9747947   Bryan Schumaker   NFS: Added TEST_S...
360
361
362
  #define encode_test_stateid_maxsz	(op_encode_hdr_maxsz + 2 + \
  					 XDR_QUADLEN(NFS4_STATEID_SIZE))
  #define decode_test_stateid_maxsz	(op_decode_hdr_maxsz + 2 + 1)
9aeda35fd   Bryan Schumaker   NFS: added FREE_S...
363
364
365
  #define encode_free_stateid_maxsz	(op_encode_hdr_maxsz + 1 + \
  					 XDR_QUADLEN(NFS4_STATEID_SIZE))
  #define decode_free_stateid_maxsz	(op_decode_hdr_maxsz + 1)
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
366
367
368
369
  #else /* CONFIG_NFS_V4_1 */
  #define encode_sequence_maxsz	0
  #define decode_sequence_maxsz	0
  #endif /* CONFIG_NFS_V4_1 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
372
  #define NFS4_enc_compound_sz	(1024)  /* XXX: large enough? */
  #define NFS4_dec_compound_sz	(1024)  /* XXX: large enough? */
  #define NFS4_enc_read_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
373
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
375
  				encode_read_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  #define NFS4_dec_read_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
377
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
379
  				decode_read_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  #define NFS4_enc_readlink_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
381
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
383
  				encode_readlink_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384
  #define NFS4_dec_readlink_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
385
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
387
  				decode_readlink_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
  #define NFS4_enc_readdir_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
389
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
391
  				encode_readdir_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392
  #define NFS4_dec_readdir_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
393
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
394
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
395
  				decode_readdir_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
  #define NFS4_enc_write_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
397
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
399
  				encode_write_maxsz + \
4f9838c7e   Trond Myklebust   NFSv4: Add post-o...
400
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  #define NFS4_dec_write_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
402
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
404
  				decode_write_maxsz + \
4f9838c7e   Trond Myklebust   NFSv4: Add post-o...
405
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406
  #define NFS4_enc_commit_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
407
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
409
  				encode_commit_maxsz + \
4f9838c7e   Trond Myklebust   NFSv4: Add post-o...
410
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
  #define NFS4_dec_commit_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
412
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
414
  				decode_commit_maxsz + \
4f9838c7e   Trond Myklebust   NFSv4: Add post-o...
415
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
  #define NFS4_enc_open_sz        (compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
417
  				encode_sequence_maxsz + \
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
418
419
420
421
422
423
424
  				encode_putfh_maxsz + \
  				encode_savefh_maxsz + \
  				encode_open_maxsz + \
  				encode_getfh_maxsz + \
  				encode_getattr_maxsz + \
  				encode_restorefh_maxsz + \
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
  #define NFS4_dec_open_sz        (compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
426
  				decode_sequence_maxsz + \
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
427
428
429
430
431
432
433
  				decode_putfh_maxsz + \
  				decode_savefh_maxsz + \
  				decode_open_maxsz + \
  				decode_getfh_maxsz + \
  				decode_getattr_maxsz + \
  				decode_restorefh_maxsz + \
  				decode_getattr_maxsz)
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
434
435
436
437
438
439
440
441
  #define NFS4_enc_open_confirm_sz \
  				(compound_encode_hdr_maxsz + \
  				 encode_putfh_maxsz + \
  				 encode_open_confirm_maxsz)
  #define NFS4_dec_open_confirm_sz \
  				(compound_decode_hdr_maxsz + \
  				 decode_putfh_maxsz + \
  				 decode_open_confirm_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
  #define NFS4_enc_open_noattr_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
443
  					encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444
  					encode_putfh_maxsz + \
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
445
446
  					encode_open_maxsz + \
  					encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
  #define NFS4_dec_open_noattr_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
448
  					decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
449
  					decode_putfh_maxsz + \
2cebf8288   Trond Myklebust   NFSv4: Fix the un...
450
451
  					decode_open_maxsz + \
  					decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
  #define NFS4_enc_open_downgrade_sz \
  				(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
454
  				 encode_sequence_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
455
456
457
  				 encode_putfh_maxsz + \
  				 encode_open_downgrade_maxsz + \
  				 encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458
459
  #define NFS4_dec_open_downgrade_sz \
  				(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
460
  				 decode_sequence_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
461
462
463
464
  				 decode_putfh_maxsz + \
  				 decode_open_downgrade_maxsz + \
  				 decode_getattr_maxsz)
  #define NFS4_enc_close_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
465
  				 encode_sequence_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
466
467
468
469
  				 encode_putfh_maxsz + \
  				 encode_close_maxsz + \
  				 encode_getattr_maxsz)
  #define NFS4_dec_close_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
470
  				 decode_sequence_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
471
472
473
474
  				 decode_putfh_maxsz + \
  				 decode_close_maxsz + \
  				 decode_getattr_maxsz)
  #define NFS4_enc_setattr_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
475
  				 encode_sequence_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
476
477
478
479
  				 encode_putfh_maxsz + \
  				 encode_setattr_maxsz + \
  				 encode_getattr_maxsz)
  #define NFS4_dec_setattr_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
480
  				 decode_sequence_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
481
482
483
  				 decode_putfh_maxsz + \
  				 decode_setattr_maxsz + \
  				 decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  #define NFS4_enc_fsinfo_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
485
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
487
488
  				encode_putfh_maxsz + \
  				encode_fsinfo_maxsz)
  #define NFS4_dec_fsinfo_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
489
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
  				decode_putfh_maxsz + \
  				decode_fsinfo_maxsz)
  #define NFS4_enc_renew_sz	(compound_encode_hdr_maxsz + \
  				encode_renew_maxsz)
  #define NFS4_dec_renew_sz	(compound_decode_hdr_maxsz + \
  				decode_renew_maxsz)
  #define NFS4_enc_setclientid_sz	(compound_encode_hdr_maxsz + \
  				encode_setclientid_maxsz)
  #define NFS4_dec_setclientid_sz	(compound_decode_hdr_maxsz + \
  				decode_setclientid_maxsz)
  #define NFS4_enc_setclientid_confirm_sz \
  				(compound_encode_hdr_maxsz + \
  				encode_setclientid_confirm_maxsz + \
  				encode_putrootfh_maxsz + \
  				encode_fsinfo_maxsz)
  #define NFS4_dec_setclientid_confirm_sz \
  				(compound_decode_hdr_maxsz + \
  				decode_setclientid_confirm_maxsz + \
  				decode_putrootfh_maxsz + \
  				decode_fsinfo_maxsz)
  #define NFS4_enc_lock_sz        (compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
511
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
513
  				encode_lock_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
  #define NFS4_dec_lock_sz        (compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
515
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
517
  				decode_lock_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
  #define NFS4_enc_lockt_sz       (compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
519
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
521
522
  				encode_lockt_maxsz)
  #define NFS4_dec_lockt_sz       (compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
523
  				 decode_sequence_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
524
525
  				 decode_putfh_maxsz + \
  				 decode_lockt_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526
  #define NFS4_enc_locku_sz       (compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
527
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
529
  				encode_locku_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
  #define NFS4_dec_locku_sz       (compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
531
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
533
  				decode_locku_maxsz)
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
534
535
536
537
538
539
  #define NFS4_enc_release_lockowner_sz \
  				(compound_encode_hdr_maxsz + \
  				 encode_lockowner_maxsz)
  #define NFS4_dec_release_lockowner_sz \
  				(compound_decode_hdr_maxsz + \
  				 decode_lockowner_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
540
  #define NFS4_enc_access_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
541
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
  				encode_putfh_maxsz + \
76b32999d   Trond Myklebust   NFSv4: Make NFSv4...
543
544
  				encode_access_maxsz + \
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
  #define NFS4_dec_access_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
546
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
  				decode_putfh_maxsz + \
76b32999d   Trond Myklebust   NFSv4: Make NFSv4...
548
549
  				decode_access_maxsz + \
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
  #define NFS4_enc_getattr_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
551
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
552
553
554
  				encode_putfh_maxsz + \
  				encode_getattr_maxsz)
  #define NFS4_dec_getattr_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
555
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
557
558
  				decode_putfh_maxsz + \
  				decode_getattr_maxsz)
  #define NFS4_enc_lookup_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
559
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560
561
562
563
564
  				encode_putfh_maxsz + \
  				encode_lookup_maxsz + \
  				encode_getattr_maxsz + \
  				encode_getfh_maxsz)
  #define NFS4_dec_lookup_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
565
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
  				decode_putfh_maxsz + \
e6889620e   Trond Myklebust   NFSv4: Fix undere...
567
  				decode_lookup_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
570
  				decode_getattr_maxsz + \
  				decode_getfh_maxsz)
  #define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
571
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
572
573
574
575
  				encode_putrootfh_maxsz + \
  				encode_getattr_maxsz + \
  				encode_getfh_maxsz)
  #define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
576
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
579
580
  				decode_putrootfh_maxsz + \
  				decode_getattr_maxsz + \
  				decode_getfh_maxsz)
  #define NFS4_enc_remove_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
581
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
  				encode_putfh_maxsz + \
16e429596   Trond Myklebust   NFSv4: Add post-o...
583
584
  				encode_remove_maxsz + \
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
  #define NFS4_dec_remove_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
586
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
  				decode_putfh_maxsz + \
6ce183919   Benny Halevy   NFS: use decode_c...
588
  				decode_remove_maxsz + \
16e429596   Trond Myklebust   NFSv4: Add post-o...
589
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
  #define NFS4_enc_rename_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
591
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592
593
594
  				encode_putfh_maxsz + \
  				encode_savefh_maxsz + \
  				encode_putfh_maxsz + \
6caf2c827   Trond Myklebust   NFSv4: Add post-o...
595
596
597
598
  				encode_rename_maxsz + \
  				encode_getattr_maxsz + \
  				encode_restorefh_maxsz + \
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
  #define NFS4_dec_rename_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
600
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
602
603
  				decode_putfh_maxsz + \
  				decode_savefh_maxsz + \
  				decode_putfh_maxsz + \
6caf2c827   Trond Myklebust   NFSv4: Add post-o...
604
605
606
607
  				decode_rename_maxsz + \
  				decode_getattr_maxsz + \
  				decode_restorefh_maxsz + \
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
  #define NFS4_enc_link_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
609
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
611
612
  				encode_putfh_maxsz + \
  				encode_savefh_maxsz + \
  				encode_putfh_maxsz + \
91ba2eeec   Trond Myklebust   NFSv4: Add post-o...
613
614
615
616
  				encode_link_maxsz + \
  				decode_getattr_maxsz + \
  				encode_restorefh_maxsz + \
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
  #define NFS4_dec_link_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
618
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
620
621
  				decode_putfh_maxsz + \
  				decode_savefh_maxsz + \
  				decode_putfh_maxsz + \
91ba2eeec   Trond Myklebust   NFSv4: Add post-o...
622
623
624
625
  				decode_link_maxsz + \
  				decode_getattr_maxsz + \
  				decode_restorefh_maxsz + \
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
  #define NFS4_enc_symlink_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
627
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
629
630
631
632
  				encode_putfh_maxsz + \
  				encode_symlink_maxsz + \
  				encode_getattr_maxsz + \
  				encode_getfh_maxsz)
  #define NFS4_dec_symlink_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
633
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
635
636
637
638
  				decode_putfh_maxsz + \
  				decode_symlink_maxsz + \
  				decode_getattr_maxsz + \
  				decode_getfh_maxsz)
  #define NFS4_enc_create_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
639
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
  				encode_putfh_maxsz + \
56ae19f38   Trond Myklebust   NFSv4: Add direct...
641
  				encode_savefh_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
  				encode_create_maxsz + \
56ae19f38   Trond Myklebust   NFSv4: Add direct...
643
  				encode_getfh_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
  				encode_getattr_maxsz + \
56ae19f38   Trond Myklebust   NFSv4: Add direct...
645
646
  				encode_restorefh_maxsz + \
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
647
  #define NFS4_dec_create_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
648
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
649
  				decode_putfh_maxsz + \
56ae19f38   Trond Myklebust   NFSv4: Add direct...
650
  				decode_savefh_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
  				decode_create_maxsz + \
56ae19f38   Trond Myklebust   NFSv4: Add direct...
652
  				decode_getfh_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
  				decode_getattr_maxsz + \
56ae19f38   Trond Myklebust   NFSv4: Add direct...
654
655
  				decode_restorefh_maxsz + \
  				decode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
  #define NFS4_enc_pathconf_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
657
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
658
659
660
  				encode_putfh_maxsz + \
  				encode_getattr_maxsz)
  #define NFS4_dec_pathconf_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
661
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
664
  				decode_putfh_maxsz + \
  				decode_getattr_maxsz)
  #define NFS4_enc_statfs_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
665
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
667
  				encode_statfs_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
  #define NFS4_dec_statfs_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
669
  				decode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
671
  				decode_statfs_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
672
  #define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
673
  				encode_sequence_maxsz + \
ab91f264c   Trond Myklebust   NFSv4: Fix NFS4_e...
674
  				encode_putfh_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
675
676
  				encode_getattr_maxsz)
  #define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
677
  				decode_sequence_maxsz + \
ab91f264c   Trond Myklebust   NFSv4: Fix NFS4_e...
678
  				decode_putfh_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
680
  				decode_getattr_maxsz)
  #define NFS4_enc_delegreturn_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
681
  				encode_sequence_maxsz + \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
  				encode_putfh_maxsz + \
fa178f29c   Trond Myklebust   NFSv4: Ensure DEL...
683
684
  				encode_delegreturn_maxsz + \
  				encode_getattr_maxsz)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
685
  #define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
686
  				decode_sequence_maxsz + \
fa178f29c   Trond Myklebust   NFSv4: Ensure DEL...
687
688
  				decode_delegreturn_maxsz + \
  				decode_getattr_maxsz)
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
689
  #define NFS4_enc_getacl_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
690
  				encode_sequence_maxsz + \
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
691
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
692
  				encode_getacl_maxsz)
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
693
  #define NFS4_dec_getacl_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
694
  				decode_sequence_maxsz + \
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
695
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
696
  				decode_getacl_maxsz)
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
697
  #define NFS4_enc_setacl_sz	(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
698
  				encode_sequence_maxsz + \
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
699
  				encode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
700
  				encode_setacl_maxsz)
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
701
  #define NFS4_dec_setacl_sz	(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
702
  				decode_sequence_maxsz + \
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
703
  				decode_putfh_maxsz + \
9104a55dc   Trond Myklebust   NFSv4: More NFSv4...
704
  				decode_setacl_maxsz)
683b57b43   Trond Myklebust   NFSv4: Implement ...
705
706
  #define NFS4_enc_fs_locations_sz \
  				(compound_encode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
707
  				 encode_sequence_maxsz + \
683b57b43   Trond Myklebust   NFSv4: Implement ...
708
  				 encode_putfh_maxsz + \
e6889620e   Trond Myklebust   NFSv4: Fix undere...
709
710
  				 encode_lookup_maxsz + \
  				 encode_fs_locations_maxsz)
683b57b43   Trond Myklebust   NFSv4: Implement ...
711
712
  #define NFS4_dec_fs_locations_sz \
  				(compound_decode_hdr_maxsz + \
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
713
  				 decode_sequence_maxsz + \
683b57b43   Trond Myklebust   NFSv4: Implement ...
714
  				 decode_putfh_maxsz + \
e6889620e   Trond Myklebust   NFSv4: Fix undere...
715
716
  				 decode_lookup_maxsz + \
  				 decode_fs_locations_maxsz)
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
717
718
719
720
721
722
723
724
  #define NFS4_enc_secinfo_sz 	(compound_encode_hdr_maxsz + \
  				encode_sequence_maxsz + \
  				encode_putfh_maxsz + \
  				encode_secinfo_maxsz)
  #define NFS4_dec_secinfo_sz	(compound_decode_hdr_maxsz + \
  				decode_sequence_maxsz + \
  				decode_putfh_maxsz + \
  				decode_secinfo_maxsz)
99fe60d06   Benny Halevy   nfs41: exchange_i...
725
726
727
728
729
730
731
  #if defined(CONFIG_NFS_V4_1)
  #define NFS4_enc_exchange_id_sz \
  				(compound_encode_hdr_maxsz + \
  				 encode_exchange_id_maxsz)
  #define NFS4_dec_exchange_id_sz \
  				(compound_decode_hdr_maxsz + \
  				 decode_exchange_id_maxsz)
fc931582c   Andy Adamson   nfs41: create_ses...
732
733
734
735
736
737
  #define NFS4_enc_create_session_sz \
  				(compound_encode_hdr_maxsz + \
  				 encode_create_session_maxsz)
  #define NFS4_dec_create_session_sz \
  				(compound_decode_hdr_maxsz + \
  				 decode_create_session_maxsz)
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
738
739
740
741
  #define NFS4_enc_destroy_session_sz	(compound_encode_hdr_maxsz + \
  					 encode_destroy_session_maxsz)
  #define NFS4_dec_destroy_session_sz	(compound_decode_hdr_maxsz + \
  					 decode_destroy_session_maxsz)
fc01cea96   Andy Adamson   nfs41: sequence o...
742
743
744
745
746
747
  #define NFS4_enc_sequence_sz \
  				(compound_decode_hdr_maxsz + \
  				 encode_sequence_maxsz)
  #define NFS4_dec_sequence_sz \
  				(compound_decode_hdr_maxsz + \
  				 decode_sequence_maxsz)
2050f0cc0   Andy Adamson   nfs41: get_lease_...
748
749
750
751
752
753
754
755
  #define NFS4_enc_get_lease_time_sz	(compound_encode_hdr_maxsz + \
  					 encode_sequence_maxsz + \
  					 encode_putrootfh_maxsz + \
  					 encode_fsinfo_maxsz)
  #define NFS4_dec_get_lease_time_sz	(compound_decode_hdr_maxsz + \
  					 decode_sequence_maxsz + \
  					 decode_putrootfh_maxsz + \
  					 decode_fsinfo_maxsz)
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
756
757
758
759
760
761
  #define NFS4_enc_reclaim_complete_sz	(compound_encode_hdr_maxsz + \
  					 encode_sequence_maxsz + \
  					 encode_reclaim_complete_maxsz)
  #define NFS4_dec_reclaim_complete_sz	(compound_decode_hdr_maxsz + \
  					 decode_sequence_maxsz + \
  					 decode_reclaim_complete_maxsz)
7f11d8d38   Andy Adamson   pnfs: GETDEVICELIST
762
763
764
765
766
767
768
769
  #define NFS4_enc_getdevicelist_sz (compound_encode_hdr_maxsz + \
  				encode_sequence_maxsz + \
  				encode_putfh_maxsz + \
  				encode_getdevicelist_maxsz)
  #define NFS4_dec_getdevicelist_sz (compound_decode_hdr_maxsz + \
  				decode_sequence_maxsz + \
  				decode_putfh_maxsz + \
  				decode_getdevicelist_maxsz)
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
770
771
772
773
774
775
776
777
778
779
780
781
782
783
  #define NFS4_enc_getdeviceinfo_sz (compound_encode_hdr_maxsz +    \
  				encode_sequence_maxsz +\
  				encode_getdeviceinfo_maxsz)
  #define NFS4_dec_getdeviceinfo_sz (compound_decode_hdr_maxsz +    \
  				decode_sequence_maxsz + \
  				decode_getdeviceinfo_maxsz)
  #define NFS4_enc_layoutget_sz	(compound_encode_hdr_maxsz + \
  				encode_sequence_maxsz + \
  				encode_putfh_maxsz +        \
  				encode_layoutget_maxsz)
  #define NFS4_dec_layoutget_sz	(compound_decode_hdr_maxsz + \
  				decode_sequence_maxsz + \
  				decode_putfh_maxsz +        \
  				decode_layoutget_maxsz)
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
784
785
786
787
788
789
790
791
792
793
  #define NFS4_enc_layoutcommit_sz (compound_encode_hdr_maxsz + \
  				encode_sequence_maxsz +\
  				encode_putfh_maxsz + \
  				encode_layoutcommit_maxsz + \
  				encode_getattr_maxsz)
  #define NFS4_dec_layoutcommit_sz (compound_decode_hdr_maxsz + \
  				decode_sequence_maxsz + \
  				decode_putfh_maxsz + \
  				decode_layoutcommit_maxsz + \
  				decode_getattr_maxsz)
cbe826036   Benny Halevy   pnfs: layoutreturn
794
795
796
797
798
799
800
801
  #define NFS4_enc_layoutreturn_sz (compound_encode_hdr_maxsz + \
  				encode_sequence_maxsz + \
  				encode_putfh_maxsz + \
  				encode_layoutreturn_maxsz)
  #define NFS4_dec_layoutreturn_sz (compound_decode_hdr_maxsz + \
  				decode_sequence_maxsz + \
  				decode_putfh_maxsz + \
  				decode_layoutreturn_maxsz)
fca78d6d2   Bryan Schumaker   NFS: Add SECINFO_...
802
803
804
805
806
807
808
809
  #define NFS4_enc_secinfo_no_name_sz	(compound_encode_hdr_maxsz + \
  					encode_sequence_maxsz + \
  					encode_putrootfh_maxsz +\
  					encode_secinfo_no_name_maxsz)
  #define NFS4_dec_secinfo_no_name_sz	(compound_decode_hdr_maxsz + \
  					decode_sequence_maxsz + \
  					decode_putrootfh_maxsz + \
  					decode_secinfo_no_name_maxsz)
7d9747947   Bryan Schumaker   NFS: Added TEST_S...
810
811
812
813
814
815
  #define NFS4_enc_test_stateid_sz	(compound_encode_hdr_maxsz + \
  					 encode_sequence_maxsz + \
  					 encode_test_stateid_maxsz)
  #define NFS4_dec_test_stateid_sz	(compound_decode_hdr_maxsz + \
  					 decode_sequence_maxsz + \
  					 decode_test_stateid_maxsz)
9aeda35fd   Bryan Schumaker   NFS: added FREE_S...
816
817
818
819
820
821
  #define NFS4_enc_free_stateid_sz	(compound_encode_hdr_maxsz + \
  					 encode_sequence_maxsz + \
  					 encode_free_stateid_maxsz)
  #define NFS4_dec_free_stateid_sz	(compound_decode_hdr_maxsz + \
  					 decode_sequence_maxsz + \
  					 decode_free_stateid_maxsz)
2449ea2e1   Alexandros Batsakis   nfs41: V2 adjust ...
822
823
824
825
826
827
828
829
830
831
832
833
834
  
  const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
  				      compound_encode_hdr_maxsz +
  				      encode_sequence_maxsz +
  				      encode_putfh_maxsz +
  				      encode_getattr_maxsz) *
  				     XDR_UNIT);
  
  const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
  				     compound_decode_hdr_maxsz +
  				     decode_sequence_maxsz +
  				     decode_putfh_maxsz) *
  				    XDR_UNIT);
99fe60d06   Benny Halevy   nfs41: exchange_i...
835
  #endif /* CONFIG_NFS_V4_1 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
836

bca794785   Trond Myklebust   NFS: Fix the type...
837
838
839
840
841
842
843
844
845
846
847
  static const umode_t nfs_type2fmt[] = {
  	[NF4BAD] = 0,
  	[NF4REG] = S_IFREG,
  	[NF4DIR] = S_IFDIR,
  	[NF4BLK] = S_IFBLK,
  	[NF4CHR] = S_IFCHR,
  	[NF4LNK] = S_IFLNK,
  	[NF4SOCK] = S_IFSOCK,
  	[NF4FIFO] = S_IFIFO,
  	[NF4ATTRDIR] = 0,
  	[NF4NAMEDATTR] = 0,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
849
850
851
852
  };
  
  struct compound_hdr {
  	int32_t		status;
  	uint32_t	nops;
d017931cf   Andy Adamson   NFS: increment nu...
853
  	__be32 *	nops_p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
855
  	uint32_t	taglen;
  	char *		tag;
0c4e8c187   Benny Halevy   NFS: define and i...
856
  	uint32_t	replen;		/* expected reply words */
66cc04297   Benny Halevy   nfs41: encode min...
857
  	u32		minorversion;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858
  };
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
859
860
861
862
863
864
  static __be32 *reserve_space(struct xdr_stream *xdr, size_t nbytes)
  {
  	__be32 *p = xdr_reserve_space(xdr, nbytes);
  	BUG_ON(!p);
  	return p;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
866
867
  
  static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
868
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
869
870
871
872
873
  
  	p = xdr_reserve_space(xdr, 4 + len);
  	BUG_ON(p == NULL);
  	xdr_encode_opaque(p, str, len);
  }
0c4e8c187   Benny Halevy   NFS: define and i...
874
875
876
  static void encode_compound_hdr(struct xdr_stream *xdr,
  				struct rpc_rqst *req,
  				struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
  {
8687b63af   Al Viro   [PATCH] xdr annot...
878
  	__be32 *p;
a17c2153d   Trond Myklebust   SUNRPC: Move the ...
879
  	struct rpc_auth *auth = req->rq_cred->cr_auth;
0c4e8c187   Benny Halevy   NFS: define and i...
880
881
882
883
884
  
  	/* initialize running count of expected bytes in reply.
  	 * NOTE: the replied tag SHOULD be the same is the one sent,
  	 * but this is not required as a MUST for the server to do so. */
  	hdr->replen = RPC_REPHDRSIZE + auth->au_rslack + 3 + hdr->taglen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
886
887
888
  
  	dprintk("encode_compound: tag=%.*s
  ", (int)hdr->taglen, hdr->tag);
  	BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
889
890
  	p = reserve_space(xdr, 4 + hdr->taglen + 8);
  	p = xdr_encode_opaque(p, hdr->tag, hdr->taglen);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
891
  	*p++ = cpu_to_be32(hdr->minorversion);
d017931cf   Andy Adamson   NFS: increment nu...
892
  	hdr->nops_p = p;
345585132   Benny Halevy   nfs: nfs4xdr: opt...
893
  	*p = cpu_to_be32(hdr->nops);
d017931cf   Andy Adamson   NFS: increment nu...
894
895
896
897
  }
  
  static void encode_nops(struct compound_hdr *hdr)
  {
fc931582c   Andy Adamson   nfs41: create_ses...
898
  	BUG_ON(hdr->nops > NFS4_MAX_OPS);
d017931cf   Andy Adamson   NFS: increment nu...
899
  	*hdr->nops_p = htonl(hdr->nops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900
901
902
903
  }
  
  static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
904
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905
906
907
908
909
  
  	p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
  	BUG_ON(p == NULL);
  	xdr_encode_opaque_fixed(p, verf->data, NFS4_VERIFIER_SIZE);
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
910
  static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
911
912
913
914
915
  {
  	char owner_name[IDMAP_NAMESZ];
  	char owner_group[IDMAP_NAMESZ];
  	int owner_namelen = 0;
  	int owner_grouplen = 0;
8687b63af   Al Viro   [PATCH] xdr annot...
916
917
  	__be32 *p;
  	__be32 *q;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
918
919
920
  	int len;
  	uint32_t bmval0 = 0;
  	uint32_t bmval1 = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921
922
923
924
925
926
  
  	/*
  	 * We reserve enough space to write the entire attribute buffer at once.
  	 * In the worst-case, this would be
  	 *   12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
  	 *          = 36 bytes, plus any contribution from variable-length fields
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
927
  	 *            such as owner/group.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
928
929
930
931
932
933
934
935
936
  	 */
  	len = 16;
  
  	/* Sigh */
  	if (iap->ia_valid & ATTR_SIZE)
  		len += 8;
  	if (iap->ia_valid & ATTR_MODE)
  		len += 4;
  	if (iap->ia_valid & ATTR_UID) {
e4fd72a17   Trond Myklebust   NFSv4: cleanup id...
937
  		owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
  		if (owner_namelen < 0) {
fe82a183c   Chuck Lever   NFS: Convert prin...
939
940
941
  			dprintk("nfs: couldn't resolve uid %d to string
  ",
  					iap->ia_uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
942
943
944
945
946
947
948
949
  			/* XXX */
  			strcpy(owner_name, "nobody");
  			owner_namelen = sizeof("nobody") - 1;
  			/* goto out; */
  		}
  		len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
  	}
  	if (iap->ia_valid & ATTR_GID) {
e4fd72a17   Trond Myklebust   NFSv4: cleanup id...
950
  		owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
  		if (owner_grouplen < 0) {
fe82a183c   Chuck Lever   NFS: Convert prin...
952
953
954
  			dprintk("nfs: couldn't resolve gid %d to string
  ",
  					iap->ia_gid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
956
957
958
959
960
961
962
963
964
965
966
967
968
  			strcpy(owner_group, "nobody");
  			owner_grouplen = sizeof("nobody") - 1;
  			/* goto out; */
  		}
  		len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);
  	}
  	if (iap->ia_valid & ATTR_ATIME_SET)
  		len += 16;
  	else if (iap->ia_valid & ATTR_ATIME)
  		len += 4;
  	if (iap->ia_valid & ATTR_MTIME_SET)
  		len += 16;
  	else if (iap->ia_valid & ATTR_MTIME)
  		len += 4;
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
969
  	p = reserve_space(xdr, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
970
971
972
973
974
  
  	/*
  	 * We write the bitmap length now, but leave the bitmap and the attribute
  	 * buffer length to be backfilled at the end of this routine.
  	 */
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
975
  	*p++ = cpu_to_be32(2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
976
977
978
979
980
  	q = p;
  	p += 3;
  
  	if (iap->ia_valid & ATTR_SIZE) {
  		bmval0 |= FATTR4_WORD0_SIZE;
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
981
  		p = xdr_encode_hyper(p, iap->ia_size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
982
983
984
  	}
  	if (iap->ia_valid & ATTR_MODE) {
  		bmval1 |= FATTR4_WORD1_MODE;
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
985
  		*p++ = cpu_to_be32(iap->ia_mode & S_IALLUGO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
986
987
988
  	}
  	if (iap->ia_valid & ATTR_UID) {
  		bmval1 |= FATTR4_WORD1_OWNER;
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
989
  		p = xdr_encode_opaque(p, owner_name, owner_namelen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
991
992
  	}
  	if (iap->ia_valid & ATTR_GID) {
  		bmval1 |= FATTR4_WORD1_OWNER_GROUP;
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
993
  		p = xdr_encode_opaque(p, owner_group, owner_grouplen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
994
995
996
  	}
  	if (iap->ia_valid & ATTR_ATIME_SET) {
  		bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
997
998
  		*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
  		*p++ = cpu_to_be32(0);
d3f6baaa3   Trond Myklebust   NFSv4: Fix an emb...
999
1000
  		*p++ = cpu_to_be32(iap->ia_atime.tv_sec);
  		*p++ = cpu_to_be32(iap->ia_atime.tv_nsec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1001
1002
1003
  	}
  	else if (iap->ia_valid & ATTR_ATIME) {
  		bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1004
  		*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
1006
1007
  	}
  	if (iap->ia_valid & ATTR_MTIME_SET) {
  		bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1008
1009
1010
1011
  		*p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME);
  		*p++ = cpu_to_be32(0);
  		*p++ = cpu_to_be32(iap->ia_mtime.tv_sec);
  		*p++ = cpu_to_be32(iap->ia_mtime.tv_nsec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
1013
1014
  	}
  	else if (iap->ia_valid & ATTR_MTIME) {
  		bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1015
  		*p++ = cpu_to_be32(NFS4_SET_TO_SERVER_TIME);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1016
  	}
6c0195a46   Andy Adamson   NFS: remove white...
1017

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1018
1019
1020
1021
  	/*
  	 * Now we backfill the bitmap and the attribute buffer length.
  	 */
  	if (len != ((char *)p - (char *)q) + 4) {
fe82a183c   Chuck Lever   NFS: Convert prin...
1022
1023
  		printk(KERN_ERR "nfs: Attr length error, %u != %Zu
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1024
1025
1026
1027
1028
1029
  				len, ((char *)p - (char *)q) + 4);
  		BUG();
  	}
  	len = (char *)p - (char *)q - 12;
  	*q++ = htonl(bmval0);
  	*q++ = htonl(bmval1);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1030
  	*q = htonl(len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1032
  /* out: */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1034
  static void encode_access(struct xdr_stream *xdr, u32 access, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1036
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1038
  	p = reserve_space(xdr, 8);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1039
  	*p++ = cpu_to_be32(OP_ACCESS);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1040
  	*p = cpu_to_be32(access);
d017931cf   Andy Adamson   NFS: increment nu...
1041
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1042
  	hdr->replen += decode_access_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1043
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1044
  static void encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1046
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1047

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1048
  	p = reserve_space(xdr, 8+NFS4_STATEID_SIZE);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1049
1050
  	*p++ = cpu_to_be32(OP_CLOSE);
  	*p++ = cpu_to_be32(arg->seqid->sequence->counter);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1051
  	xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE);
d017931cf   Andy Adamson   NFS: increment nu...
1052
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1053
  	hdr->replen += decode_close_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1055
  static void encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1057
  	__be32 *p;
6c0195a46   Andy Adamson   NFS: remove white...
1058

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1059
  	p = reserve_space(xdr, 16);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1060
  	*p++ = cpu_to_be32(OP_COMMIT);
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1061
  	p = xdr_encode_hyper(p, args->offset);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1062
  	*p = cpu_to_be32(args->count);
d017931cf   Andy Adamson   NFS: increment nu...
1063
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1064
  	hdr->replen += decode_commit_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1065
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1066
  static void encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1067
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1068
  	__be32 *p;
6c0195a46   Andy Adamson   NFS: remove white...
1069

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1070
  	p = reserve_space(xdr, 8);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1071
  	*p++ = cpu_to_be32(OP_CREATE);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1072
  	*p = cpu_to_be32(create->ftype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1073
1074
1075
  
  	switch (create->ftype) {
  	case NF4LNK:
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1076
  		p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1077
  		*p = cpu_to_be32(create->u.symlink.len);
94a6d7532   Chuck Lever   NFS: Use cached p...
1078
  		xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1079
1080
1081
  		break;
  
  	case NF4BLK: case NF4CHR:
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1082
  		p = reserve_space(xdr, 8);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1083
  		*p++ = cpu_to_be32(create->u.device.specdata1);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1084
  		*p = cpu_to_be32(create->u.device.specdata2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1085
1086
1087
1088
1089
  		break;
  
  	default:
  		break;
  	}
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
1090
  	encode_string(xdr, create->name->len, create->name->name);
d017931cf   Andy Adamson   NFS: increment nu...
1091
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1092
  	hdr->replen += decode_create_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093

cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1094
  	encode_attrs(xdr, create->attrs, create->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1096
  static void encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1097
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1098
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1099

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1100
  	p = reserve_space(xdr, 12);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1101
1102
  	*p++ = cpu_to_be32(OP_GETATTR);
  	*p++ = cpu_to_be32(1);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1103
  	*p = cpu_to_be32(bitmap);
d017931cf   Andy Adamson   NFS: increment nu...
1104
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1105
  	hdr->replen += decode_getattr_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1106
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1107
  static void encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1108
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1109
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1110

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1111
  	p = reserve_space(xdr, 16);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1112
1113
1114
  	*p++ = cpu_to_be32(OP_GETATTR);
  	*p++ = cpu_to_be32(2);
  	*p++ = cpu_to_be32(bm0);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1115
  	*p = cpu_to_be32(bm1);
d017931cf   Andy Adamson   NFS: increment nu...
1116
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1117
  	hdr->replen += decode_getattr_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1118
  }
dae100c2b   Fred Isaman   pnfs: ask for lay...
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
  static void
  encode_getattr_three(struct xdr_stream *xdr,
  		     uint32_t bm0, uint32_t bm1, uint32_t bm2,
  		     struct compound_hdr *hdr)
  {
  	__be32 *p;
  
  	p = reserve_space(xdr, 4);
  	*p = cpu_to_be32(OP_GETATTR);
  	if (bm2) {
  		p = reserve_space(xdr, 16);
  		*p++ = cpu_to_be32(3);
  		*p++ = cpu_to_be32(bm0);
  		*p++ = cpu_to_be32(bm1);
  		*p = cpu_to_be32(bm2);
  	} else if (bm1) {
  		p = reserve_space(xdr, 12);
  		*p++ = cpu_to_be32(2);
  		*p++ = cpu_to_be32(bm0);
  		*p = cpu_to_be32(bm1);
  	} else {
  		p = reserve_space(xdr, 8);
  		*p++ = cpu_to_be32(1);
  		*p = cpu_to_be32(bm0);
  	}
  	hdr->nops++;
  	hdr->replen += decode_getattr_maxsz;
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1147
  static void encode_getfattr(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1148
  {
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1149
1150
  	encode_getattr_two(xdr, bitmask[0] & nfs4_fattr_bitmap[0],
  			   bitmask[1] & nfs4_fattr_bitmap[1], hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1152
  static void encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153
  {
dae100c2b   Fred Isaman   pnfs: ask for lay...
1154
1155
1156
1157
1158
  	encode_getattr_three(xdr,
  			     bitmask[0] & nfs4_fsinfo_bitmap[0],
  			     bitmask[1] & nfs4_fsinfo_bitmap[1],
  			     bitmask[2] & nfs4_fsinfo_bitmap[2],
  			     hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1159
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1160
  static void encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask, struct compound_hdr *hdr)
830b8e33f   Manoj Naik   NFSv4: Define an ...
1161
  {
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1162
1163
  	encode_getattr_two(xdr, bitmask[0] & nfs4_fs_locations_bitmap[0],
  			   bitmask[1] & nfs4_fs_locations_bitmap[1], hdr);
830b8e33f   Manoj Naik   NFSv4: Define an ...
1164
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1165
  static void encode_getfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1166
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1167
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1168

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1169
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1170
  	*p = cpu_to_be32(OP_GETFH);
d017931cf   Andy Adamson   NFS: increment nu...
1171
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1172
  	hdr->replen += decode_getfh_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1173
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1174
  static void encode_link(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1175
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1176
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1177

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1178
  	p = reserve_space(xdr, 8 + name->len);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1179
  	*p++ = cpu_to_be32(OP_LINK);
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
1180
  	xdr_encode_opaque(p, name->name, name->len);
d017931cf   Andy Adamson   NFS: increment nu...
1181
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1182
  	hdr->replen += decode_link_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1183
  }
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
  static inline int nfs4_lock_type(struct file_lock *fl, int block)
  {
  	if ((fl->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) == F_RDLCK)
  		return block ? NFS4_READW_LT : NFS4_READ_LT;
  	return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
  }
  
  static inline uint64_t nfs4_lock_length(struct file_lock *fl)
  {
  	if (fl->fl_end == OFFSET_MAX)
  		return ~(uint64_t)0;
  	return fl->fl_end - fl->fl_start + 1;
  }
daccbded7   Trond Myklebust   NFSv4: Clean up f...
1197
1198
1199
  static void encode_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner)
  {
  	__be32 *p;
d035c36c5   Trond Myklebust   NFSv4: Ensure con...
1200
  	p = reserve_space(xdr, 32);
daccbded7   Trond Myklebust   NFSv4: Clean up f...
1201
  	p = xdr_encode_hyper(p, lowner->clientid);
d035c36c5   Trond Myklebust   NFSv4: Ensure con...
1202
  	*p++ = cpu_to_be32(20);
daccbded7   Trond Myklebust   NFSv4: Clean up f...
1203
  	p = xdr_encode_opaque_fixed(p, "lock id:", 8);
d035c36c5   Trond Myklebust   NFSv4: Ensure con...
1204
  	*p++ = cpu_to_be32(lowner->s_dev);
daccbded7   Trond Myklebust   NFSv4: Clean up f...
1205
1206
  	xdr_encode_hyper(p, lowner->id);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1207
1208
1209
1210
  /*
   * opcode,type,reclaim,offset,length,new_lock_owner = 32
   * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
   */
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1211
  static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1212
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1213
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1214

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1215
  	p = reserve_space(xdr, 32);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1216
1217
1218
  	*p++ = cpu_to_be32(OP_LOCK);
  	*p++ = cpu_to_be32(nfs4_lock_type(args->fl, args->block));
  	*p++ = cpu_to_be32(args->reclaim);
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1219
1220
  	p = xdr_encode_hyper(p, args->fl->fl_start);
  	p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1221
  	*p = cpu_to_be32(args->new_lock_owner);
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
1222
  	if (args->new_lock_owner){
daccbded7   Trond Myklebust   NFSv4: Clean up f...
1223
  		p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1224
  		*p++ = cpu_to_be32(args->open_seqid->sequence->counter);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1225
  		p = xdr_encode_opaque_fixed(p, args->open_stateid->data, NFS4_STATEID_SIZE);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1226
  		*p++ = cpu_to_be32(args->lock_seqid->sequence->counter);
daccbded7   Trond Myklebust   NFSv4: Clean up f...
1227
  		encode_lockowner(xdr, &args->lock_owner);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1228
1229
  	}
  	else {
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1230
  		p = reserve_space(xdr, NFS4_STATEID_SIZE+4);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1231
  		p = xdr_encode_opaque_fixed(p, args->lock_stateid->data, NFS4_STATEID_SIZE);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1232
  		*p = cpu_to_be32(args->lock_seqid->sequence->counter);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1233
  	}
d017931cf   Andy Adamson   NFS: increment nu...
1234
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1235
  	hdr->replen += decode_lock_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1236
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1237
  static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1238
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1239
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1240

daccbded7   Trond Myklebust   NFSv4: Clean up f...
1241
  	p = reserve_space(xdr, 24);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1242
1243
  	*p++ = cpu_to_be32(OP_LOCKT);
  	*p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0));
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1244
1245
  	p = xdr_encode_hyper(p, args->fl->fl_start);
  	p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
daccbded7   Trond Myklebust   NFSv4: Clean up f...
1246
  	encode_lockowner(xdr, &args->lock_owner);
d017931cf   Andy Adamson   NFS: increment nu...
1247
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1248
  	hdr->replen += decode_lockt_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1250
  static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1251
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1252
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1253

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1254
  	p = reserve_space(xdr, 12+NFS4_STATEID_SIZE+16);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1255
1256
1257
  	*p++ = cpu_to_be32(OP_LOCKU);
  	*p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0));
  	*p++ = cpu_to_be32(args->seqid->sequence->counter);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1258
  	p = xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE);
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1259
  	p = xdr_encode_hyper(p, args->fl->fl_start);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1260
  	xdr_encode_hyper(p, nfs4_lock_length(args->fl));
d017931cf   Andy Adamson   NFS: increment nu...
1261
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1262
  	hdr->replen += decode_locku_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1263
  }
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
  static void encode_release_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner, struct compound_hdr *hdr)
  {
  	__be32 *p;
  
  	p = reserve_space(xdr, 4);
  	*p = cpu_to_be32(OP_RELEASE_LOCKOWNER);
  	encode_lockowner(xdr, lowner);
  	hdr->nops++;
  	hdr->replen += decode_release_lockowner_maxsz;
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1274
  static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1275
1276
  {
  	int len = name->len;
8687b63af   Al Viro   [PATCH] xdr annot...
1277
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1278

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1279
  	p = reserve_space(xdr, 8 + len);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1280
  	*p++ = cpu_to_be32(OP_LOOKUP);
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
1281
  	xdr_encode_opaque(p, name->name, len);
d017931cf   Andy Adamson   NFS: increment nu...
1282
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1283
  	hdr->replen += decode_lookup_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1284
  }
dc0b027df   Trond Myklebust   NFSv4: Convert th...
1285
  static void encode_share_access(struct xdr_stream *xdr, fmode_t fmode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1287
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1288

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1289
  	p = reserve_space(xdr, 8);
dc0b027df   Trond Myklebust   NFSv4: Convert th...
1290
  	switch (fmode & (FMODE_READ|FMODE_WRITE)) {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1291
  	case FMODE_READ:
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1292
  		*p++ = cpu_to_be32(NFS4_SHARE_ACCESS_READ);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1293
1294
  		break;
  	case FMODE_WRITE:
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1295
  		*p++ = cpu_to_be32(NFS4_SHARE_ACCESS_WRITE);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1296
1297
  		break;
  	case FMODE_READ|FMODE_WRITE:
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1298
  		*p++ = cpu_to_be32(NFS4_SHARE_ACCESS_BOTH);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1299
1300
  		break;
  	default:
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1301
  		*p++ = cpu_to_be32(0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1302
  	}
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1303
  	*p = cpu_to_be32(0);		/* for linux, share_deny = 0 always */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1304
1305
1306
1307
  }
  
  static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1308
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1309
1310
1311
1312
   /*
   * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
   * owner 4 = 32
   */
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1313
  	p = reserve_space(xdr, 8);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1314
  	*p++ = cpu_to_be32(OP_OPEN);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1315
  	*p = cpu_to_be32(arg->seqid->sequence->counter);
dc0b027df   Trond Myklebust   NFSv4: Convert th...
1316
  	encode_share_access(xdr, arg->fmode);
d035c36c5   Trond Myklebust   NFSv4: Ensure con...
1317
  	p = reserve_space(xdr, 32);
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1318
  	p = xdr_encode_hyper(p, arg->clientid);
d035c36c5   Trond Myklebust   NFSv4: Ensure con...
1319
  	*p++ = cpu_to_be32(20);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1320
  	p = xdr_encode_opaque_fixed(p, "open id:", 8);
d035c36c5   Trond Myklebust   NFSv4: Ensure con...
1321
  	*p++ = cpu_to_be32(arg->server->s_dev);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1322
  	xdr_encode_hyper(p, arg->id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1323
1324
1325
1326
  }
  
  static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1327
  	__be32 *p;
4882ef72c   Alexandros Batsakis   nfs41: add suppor...
1328
  	struct nfs_client *clp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1329

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1330
  	p = reserve_space(xdr, 4);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1331
  	switch(arg->open_flags & O_EXCL) {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1332
  	case 0:
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1333
  		*p = cpu_to_be32(NFS4_CREATE_UNCHECKED);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1334
1335
1336
  		encode_attrs(xdr, arg->u.attrs, arg->server);
  		break;
  	default:
4882ef72c   Alexandros Batsakis   nfs41: add suppor...
1337
  		clp = arg->server->nfs_client;
a44323453   Trond Myklebust   NFSv41: Deprecate...
1338
  		if (clp->cl_mvops->minor_version > 0) {
4882ef72c   Alexandros Batsakis   nfs41: add suppor...
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
  			if (nfs4_has_persistent_session(clp)) {
  				*p = cpu_to_be32(NFS4_CREATE_GUARDED);
  				encode_attrs(xdr, arg->u.attrs, arg->server);
  			} else {
  				struct iattr dummy;
  
  				*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE4_1);
  				encode_nfs4_verifier(xdr, &arg->u.verifier);
  				dummy.ia_valid = 0;
  				encode_attrs(xdr, &dummy, arg->server);
  			}
  		} else {
  			*p = cpu_to_be32(NFS4_CREATE_EXCLUSIVE);
  			encode_nfs4_verifier(xdr, &arg->u.verifier);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1354
1355
1356
1357
1358
  	}
  }
  
  static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1359
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1360

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1361
  	p = reserve_space(xdr, 4);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1362
  	switch (arg->open_flags & O_CREAT) {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1363
  	case 0:
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1364
  		*p = cpu_to_be32(NFS4_OPEN_NOCREATE);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1365
1366
1367
  		break;
  	default:
  		BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1368
  		*p = cpu_to_be32(NFS4_OPEN_CREATE);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1369
  		encode_createmode(xdr, arg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1370
1371
  	}
  }
bd7bf9d54   Trond Myklebust   NFSv4: Convert de...
1372
  static inline void encode_delegation_type(struct xdr_stream *xdr, fmode_t delegation_type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1373
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1374
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1375

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1376
  	p = reserve_space(xdr, 4);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1377
  	switch (delegation_type) {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1378
  	case 0:
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1379
  		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_NONE);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1380
1381
  		break;
  	case FMODE_READ:
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1382
  		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_READ);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1383
1384
  		break;
  	case FMODE_WRITE|FMODE_READ:
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1385
  		*p = cpu_to_be32(NFS4_OPEN_DELEGATE_WRITE);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1386
1387
1388
  		break;
  	default:
  		BUG();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1389
1390
1391
1392
1393
  	}
  }
  
  static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1394
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1395

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1396
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1397
  	*p = cpu_to_be32(NFS4_OPEN_CLAIM_NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1398
1399
  	encode_string(xdr, name->len, name->name);
  }
bd7bf9d54   Trond Myklebust   NFSv4: Convert de...
1400
  static inline void encode_claim_previous(struct xdr_stream *xdr, fmode_t type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1401
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1402
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1403

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1404
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1405
  	*p = cpu_to_be32(NFS4_OPEN_CLAIM_PREVIOUS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1406
1407
1408
1409
1410
  	encode_delegation_type(xdr, type);
  }
  
  static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1411
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1412

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1413
  	p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1414
  	*p++ = cpu_to_be32(NFS4_OPEN_CLAIM_DELEGATE_CUR);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1415
  	xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1416
1417
  	encode_string(xdr, name->len, name->name);
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1418
  static void encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1419
1420
1421
1422
  {
  	encode_openhdr(xdr, arg);
  	encode_opentype(xdr, arg);
  	switch (arg->claim) {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
  	case NFS4_OPEN_CLAIM_NULL:
  		encode_claim_null(xdr, arg->name);
  		break;
  	case NFS4_OPEN_CLAIM_PREVIOUS:
  		encode_claim_previous(xdr, arg->u.delegation_type);
  		break;
  	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
  		encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
  		break;
  	default:
  		BUG();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1434
  	}
d017931cf   Andy Adamson   NFS: increment nu...
1435
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1436
  	hdr->replen += decode_open_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1437
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1438
  static void encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1439
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1440
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1442
  	p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1443
  	*p++ = cpu_to_be32(OP_OPEN_CONFIRM);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1444
  	p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1445
  	*p = cpu_to_be32(arg->seqid->sequence->counter);
d017931cf   Andy Adamson   NFS: increment nu...
1446
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1447
  	hdr->replen += decode_open_confirm_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1448
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1449
  static void encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1450
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1451
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1452

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1453
  	p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1454
  	*p++ = cpu_to_be32(OP_OPEN_DOWNGRADE);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1455
  	p = xdr_encode_opaque_fixed(p, arg->stateid->data, NFS4_STATEID_SIZE);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1456
  	*p = cpu_to_be32(arg->seqid->sequence->counter);
dc0b027df   Trond Myklebust   NFSv4: Convert th...
1457
  	encode_share_access(xdr, arg->fmode);
d017931cf   Andy Adamson   NFS: increment nu...
1458
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1459
  	hdr->replen += decode_open_downgrade_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1460
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1461
  static void
d017931cf   Andy Adamson   NFS: increment nu...
1462
  encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1463
1464
  {
  	int len = fh->size;
8687b63af   Al Viro   [PATCH] xdr annot...
1465
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1466

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1467
  	p = reserve_space(xdr, 8 + len);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1468
  	*p++ = cpu_to_be32(OP_PUTFH);
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
1469
  	xdr_encode_opaque(p, fh->data, len);
d017931cf   Andy Adamson   NFS: increment nu...
1470
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1471
  	hdr->replen += decode_putfh_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1472
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1473
  static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1474
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1475
  	__be32 *p;
6c0195a46   Andy Adamson   NFS: remove white...
1476

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1477
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1478
  	*p = cpu_to_be32(OP_PUTROOTFH);
d017931cf   Andy Adamson   NFS: increment nu...
1479
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1480
  	hdr->replen += decode_putrootfh_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1481
  }
89d1ea657   Andy Adamson   NFSv4.1: send zer...
1482
  static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx, int zero_seqid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1483
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1484
  	nfs4_stateid stateid;
8687b63af   Al Viro   [PATCH] xdr annot...
1485
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1486

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1487
  	p = reserve_space(xdr, NFS4_STATEID_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1488
  	if (ctx->state != NULL) {
77041ed9b   Trond Myklebust   NFSv4: Ensure the...
1489
  		nfs4_copy_stateid(&stateid, ctx->state, l_ctx->lockowner, l_ctx->pid);
89d1ea657   Andy Adamson   NFSv4.1: send zer...
1490
1491
  		if (zero_seqid)
  			stateid.stateid.seqid = 0;
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1492
  		xdr_encode_opaque_fixed(p, stateid.data, NFS4_STATEID_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1493
  	} else
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1494
  		xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1495
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1496
  static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1498
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1500
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1501
  	*p = cpu_to_be32(OP_READ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1502

89d1ea657   Andy Adamson   NFSv4.1: send zer...
1503
1504
  	encode_stateid(xdr, args->context, args->lock_context,
  		       hdr->minorversion);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1505

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1506
  	p = reserve_space(xdr, 12);
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1507
  	p = xdr_encode_hyper(p, args->offset);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1508
  	*p = cpu_to_be32(args->count);
d017931cf   Andy Adamson   NFS: increment nu...
1509
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1510
  	hdr->replen += decode_read_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1511
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1512
  static void encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1513
  {
28331a46d   Trond Myklebust   NFSv4: Ensure we ...
1514
1515
1516
1517
  	uint32_t attrs[2] = {
  		FATTR4_WORD0_RDATTR_ERROR,
  		FATTR4_WORD1_MOUNTED_ON_FILEID,
  	};
6f7a35bd2   Trond Myklebust   NFSv4: Fix up the...
1518
  	uint32_t dircount = readdir->count >> 1;
8687b63af   Al Viro   [PATCH] xdr annot...
1519
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1520

82f2e5472   Bryan Schumaker   NFS: Readdir plus...
1521
1522
  	if (readdir->plus) {
  		attrs[0] |= FATTR4_WORD0_TYPE|FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE|
28331a46d   Trond Myklebust   NFSv4: Ensure we ...
1523
  			FATTR4_WORD0_FSID|FATTR4_WORD0_FILEHANDLE|FATTR4_WORD0_FILEID;
82f2e5472   Bryan Schumaker   NFS: Readdir plus...
1524
1525
1526
1527
  		attrs[1] |= FATTR4_WORD1_MODE|FATTR4_WORD1_NUMLINKS|FATTR4_WORD1_OWNER|
  			FATTR4_WORD1_OWNER_GROUP|FATTR4_WORD1_RAWDEV|
  			FATTR4_WORD1_SPACE_USED|FATTR4_WORD1_TIME_ACCESS|
  			FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY;
6f7a35bd2   Trond Myklebust   NFSv4: Fix up the...
1528
  		dircount >>= 1;
82f2e5472   Bryan Schumaker   NFS: Readdir plus...
1529
  	}
28331a46d   Trond Myklebust   NFSv4: Ensure we ...
1530
1531
1532
  	/* Use mounted_on_fileid only if the server supports it */
  	if (!(readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID))
  		attrs[0] |= FATTR4_WORD0_FILEID;
82f2e5472   Bryan Schumaker   NFS: Readdir plus...
1533

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1534
  	p = reserve_space(xdr, 12+NFS4_VERIFIER_SIZE+20);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1535
  	*p++ = cpu_to_be32(OP_READDIR);
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1536
  	p = xdr_encode_hyper(p, readdir->cookie);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1537
  	p = xdr_encode_opaque_fixed(p, readdir->verifier.data, NFS4_VERIFIER_SIZE);
6f7a35bd2   Trond Myklebust   NFSv4: Fix up the...
1538
  	*p++ = cpu_to_be32(dircount);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1539
1540
  	*p++ = cpu_to_be32(readdir->count);
  	*p++ = cpu_to_be32(2);
82f2e5472   Bryan Schumaker   NFS: Readdir plus...
1541

e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1542
  	*p++ = cpu_to_be32(attrs[0] & readdir->bitmask[0]);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1543
  	*p = cpu_to_be32(attrs[1] & readdir->bitmask[1]);
d017931cf   Andy Adamson   NFS: increment nu...
1544
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1545
  	hdr->replen += decode_readdir_maxsz;
441092415   Fred Isaman   nfs: fix printout...
1546
1547
1548
  	dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x
  ",
  			__func__,
eadf4598e   Trond Myklebust   [PATCH] NFS: Add ...
1549
1550
1551
1552
1553
  			(unsigned long long)readdir->cookie,
  			((u32 *)readdir->verifier.data)[0],
  			((u32 *)readdir->verifier.data)[1],
  			attrs[0] & readdir->bitmask[0],
  			attrs[1] & readdir->bitmask[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1555
  static void encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1557
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1558

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1559
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1560
  	*p = cpu_to_be32(OP_READLINK);
d017931cf   Andy Adamson   NFS: increment nu...
1561
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1562
  	hdr->replen += decode_readlink_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1563
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1564
  static void encode_remove(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1565
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1566
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1567

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1568
  	p = reserve_space(xdr, 8 + name->len);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1569
  	*p++ = cpu_to_be32(OP_REMOVE);
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
1570
  	xdr_encode_opaque(p, name->name, name->len);
d017931cf   Andy Adamson   NFS: increment nu...
1571
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1572
  	hdr->replen += decode_remove_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1573
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1574
  static void encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1575
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1576
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577

811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
1578
1579
1580
1581
  	p = reserve_space(xdr, 4);
  	*p = cpu_to_be32(OP_RENAME);
  	encode_string(xdr, oldname->len, oldname->name);
  	encode_string(xdr, newname->len, newname->name);
d017931cf   Andy Adamson   NFS: increment nu...
1582
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1583
  	hdr->replen += decode_rename_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1584
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1585
  static void encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1586
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1587
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1588

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1589
  	p = reserve_space(xdr, 12);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1590
  	*p++ = cpu_to_be32(OP_RENEW);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1591
  	xdr_encode_hyper(p, client_stateid->cl_clientid);
d017931cf   Andy Adamson   NFS: increment nu...
1592
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1593
  	hdr->replen += decode_renew_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1594
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1595
  static void
d017931cf   Andy Adamson   NFS: increment nu...
1596
  encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
56ae19f38   Trond Myklebust   NFSv4: Add direct...
1597
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1598
  	__be32 *p;
56ae19f38   Trond Myklebust   NFSv4: Add direct...
1599

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1600
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1601
  	*p = cpu_to_be32(OP_RESTOREFH);
d017931cf   Andy Adamson   NFS: increment nu...
1602
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1603
  	hdr->replen += decode_restorefh_maxsz;
56ae19f38   Trond Myklebust   NFSv4: Add direct...
1604
  }
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
1605
  static void
d017931cf   Andy Adamson   NFS: increment nu...
1606
  encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr)
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
1607
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1608
  	__be32 *p;
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
1609

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1610
  	p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1611
  	*p++ = cpu_to_be32(OP_SETATTR);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1612
  	xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE);
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1613
  	p = reserve_space(xdr, 2*4);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1614
  	*p++ = cpu_to_be32(1);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1615
  	*p = cpu_to_be32(FATTR4_WORD0_ACL);
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
1616
  	BUG_ON(arg->acl_len % 4);
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1617
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1618
  	*p = cpu_to_be32(arg->acl_len);
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
1619
  	xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
d017931cf   Andy Adamson   NFS: increment nu...
1620
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1621
  	hdr->replen += decode_setacl_maxsz;
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
1622
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1623
  static void
d017931cf   Andy Adamson   NFS: increment nu...
1624
  encode_savefh(struct xdr_stream *xdr, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1625
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1626
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1627

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1628
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1629
  	*p = cpu_to_be32(OP_SAVEFH);
d017931cf   Andy Adamson   NFS: increment nu...
1630
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1631
  	hdr->replen += decode_savefh_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1632
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1633
  static void encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1634
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1635
  	__be32 *p;
6c0195a46   Andy Adamson   NFS: remove white...
1636

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1637
  	p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1638
  	*p++ = cpu_to_be32(OP_SETATTR);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1639
  	xdr_encode_opaque_fixed(p, arg->stateid.data, NFS4_STATEID_SIZE);
d017931cf   Andy Adamson   NFS: increment nu...
1640
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1641
  	hdr->replen += decode_setattr_maxsz;
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1642
  	encode_attrs(xdr, arg->iap, server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1643
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1644
  static void encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1645
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1646
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1648
  	p = reserve_space(xdr, 4 + NFS4_VERIFIER_SIZE);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1649
  	*p++ = cpu_to_be32(OP_SETCLIENTID);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1650
  	xdr_encode_opaque_fixed(p, setclientid->sc_verifier->data, NFS4_VERIFIER_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1651
1652
  
  	encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name);
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1653
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1654
  	*p = cpu_to_be32(setclientid->sc_prog);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1655
1656
  	encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid);
  	encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1657
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1658
  	*p = cpu_to_be32(setclientid->sc_cb_ident);
d017931cf   Andy Adamson   NFS: increment nu...
1659
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1660
  	hdr->replen += decode_setclientid_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1661
  }
bb8b27e50   Trond Myklebust   NFSv4: Clean up t...
1662
  static void encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs4_setclientid_res *arg, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1663
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
1664
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1665

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1666
  	p = reserve_space(xdr, 12 + NFS4_VERIFIER_SIZE);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1667
  	*p++ = cpu_to_be32(OP_SETCLIENTID_CONFIRM);
bb8b27e50   Trond Myklebust   NFSv4: Clean up t...
1668
1669
  	p = xdr_encode_hyper(p, arg->clientid);
  	xdr_encode_opaque_fixed(p, arg->confirm.data, NFS4_VERIFIER_SIZE);
d017931cf   Andy Adamson   NFS: increment nu...
1670
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1671
  	hdr->replen += decode_setclientid_confirm_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1672
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1673
  static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1675
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1676

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1677
  	p = reserve_space(xdr, 4);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1678
  	*p = cpu_to_be32(OP_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1679

89d1ea657   Andy Adamson   NFSv4.1: send zer...
1680
1681
  	encode_stateid(xdr, args->context, args->lock_context,
  		       hdr->minorversion);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1682

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1683
  	p = reserve_space(xdr, 16);
b95be5a97   Benny Halevy   nfs: nfs4xdr: get...
1684
  	p = xdr_encode_hyper(p, args->offset);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1685
  	*p++ = cpu_to_be32(args->stable);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1686
  	*p = cpu_to_be32(args->count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
1688
  
  	xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
d017931cf   Andy Adamson   NFS: increment nu...
1689
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1690
  	hdr->replen += decode_write_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1691
  }
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
1692
  static void encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid, struct compound_hdr *hdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1693
  {
8687b63af   Al Viro   [PATCH] xdr annot...
1694
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1695

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1696
  	p = reserve_space(xdr, 4+NFS4_STATEID_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1697

e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1698
  	*p++ = cpu_to_be32(OP_DELEGRETURN);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1699
  	xdr_encode_opaque_fixed(p, stateid->data, NFS4_STATEID_SIZE);
d017931cf   Andy Adamson   NFS: increment nu...
1700
  	hdr->nops++;
dadf0c276   Benny Halevy   NFS: update hdr->...
1701
  	hdr->replen += decode_delegreturn_maxsz;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1702
  }
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
1703

5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
  static void encode_secinfo(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
  {
  	int len = name->len;
  	__be32 *p;
  
  	p = reserve_space(xdr, 8 + len);
  	*p++ = cpu_to_be32(OP_SECINFO);
  	xdr_encode_opaque(p, name->name, len);
  	hdr->nops++;
  	hdr->replen += decode_secinfo_maxsz;
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
1715
  #if defined(CONFIG_NFS_V4_1)
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
1716
  /* NFSv4.1 operations */
99fe60d06   Benny Halevy   nfs41: exchange_i...
1717
1718
1719
1720
1721
  static void encode_exchange_id(struct xdr_stream *xdr,
  			       struct nfs41_exchange_id_args *args,
  			       struct compound_hdr *hdr)
  {
  	__be32 *p;
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1722
  	p = reserve_space(xdr, 4 + sizeof(args->verifier->data));
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1723
  	*p++ = cpu_to_be32(OP_EXCHANGE_ID);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1724
  	xdr_encode_opaque_fixed(p, args->verifier->data, sizeof(args->verifier->data));
99fe60d06   Benny Halevy   nfs41: exchange_i...
1725
1726
  
  	encode_string(xdr, args->id_len, args->id);
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1727
  	p = reserve_space(xdr, 12);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1728
1729
  	*p++ = cpu_to_be32(args->flags);
  	*p++ = cpu_to_be32(0);	/* zero length state_protect4_a */
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1730
  	*p = cpu_to_be32(0);	/* zero length implementation id array */
99fe60d06   Benny Halevy   nfs41: exchange_i...
1731
1732
1733
  	hdr->nops++;
  	hdr->replen += decode_exchange_id_maxsz;
  }
fc931582c   Andy Adamson   nfs41: create_ses...
1734
1735
1736
1737
1738
1739
1740
1741
1742
  
  static void encode_create_session(struct xdr_stream *xdr,
  				  struct nfs41_create_session_args *args,
  				  struct compound_hdr *hdr)
  {
  	__be32 *p;
  	char machine_name[NFS4_MAX_MACHINE_NAME_LEN];
  	uint32_t len;
  	struct nfs_client *clp = args->client;
8e0d46e13   Mike Sager   nfs41: Adjust max...
1743
1744
1745
1746
1747
1748
1749
1750
  	u32 max_resp_sz_cached;
  
  	/*
  	 * Assumes OPEN is the biggest non-idempotent compound.
  	 * 2 is the verifier.
  	 */
  	max_resp_sz_cached = (NFS4_dec_open_sz + RPC_REPHDRSIZE +
  			      RPC_MAX_AUTH_SIZE + 2) * XDR_UNIT;
fc931582c   Andy Adamson   nfs41: create_ses...
1751

42edd6981   Benny Halevy   nfs: nfs4xdr: opt...
1752
1753
  	len = scnprintf(machine_name, sizeof(machine_name), "%s",
  			clp->cl_ipaddr);
fc931582c   Andy Adamson   nfs41: create_ses...
1754

13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1755
  	p = reserve_space(xdr, 20 + 2*28 + 20 + len + 12);
42edd6981   Benny Halevy   nfs: nfs4xdr: opt...
1756
  	*p++ = cpu_to_be32(OP_CREATE_SESSION);
114f64b5f   Andy Adamson   NFSv4: remove dup...
1757
  	p = xdr_encode_hyper(p, clp->cl_clientid);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1758
1759
  	*p++ = cpu_to_be32(clp->cl_seqid);			/*Sequence id */
  	*p++ = cpu_to_be32(args->flags);			/*flags */
fc931582c   Andy Adamson   nfs41: create_ses...
1760

fc931582c   Andy Adamson   nfs41: create_ses...
1761
  	/* Fore Channel */
c9c30dd5f   Benny Halevy   NFSv4.1: deprecat...
1762
  	*p++ = cpu_to_be32(0);				/* header padding size */
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1763
1764
  	*p++ = cpu_to_be32(args->fc_attrs.max_rqst_sz);	/* max req size */
  	*p++ = cpu_to_be32(args->fc_attrs.max_resp_sz);	/* max resp size */
8e0d46e13   Mike Sager   nfs41: Adjust max...
1765
  	*p++ = cpu_to_be32(max_resp_sz_cached);		/* Max resp sz cached */
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1766
1767
1768
  	*p++ = cpu_to_be32(args->fc_attrs.max_ops);	/* max operations */
  	*p++ = cpu_to_be32(args->fc_attrs.max_reqs);	/* max requests */
  	*p++ = cpu_to_be32(0);				/* rdmachannel_attrs */
fc931582c   Andy Adamson   nfs41: create_ses...
1769
1770
  
  	/* Back Channel */
c9c30dd5f   Benny Halevy   NFSv4.1: deprecat...
1771
  	*p++ = cpu_to_be32(0);				/* header padding size */
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1772
1773
1774
1775
1776
1777
  	*p++ = cpu_to_be32(args->bc_attrs.max_rqst_sz);	/* max req size */
  	*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz);	/* max resp size */
  	*p++ = cpu_to_be32(args->bc_attrs.max_resp_sz_cached);	/* Max resp sz cached */
  	*p++ = cpu_to_be32(args->bc_attrs.max_ops);	/* max operations */
  	*p++ = cpu_to_be32(args->bc_attrs.max_reqs);	/* max requests */
  	*p++ = cpu_to_be32(0);				/* rdmachannel_attrs */
fc931582c   Andy Adamson   nfs41: create_ses...
1778

e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1779
  	*p++ = cpu_to_be32(args->cb_program);		/* cb_program */
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1780
  	*p++ = cpu_to_be32(1);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1781
  	*p++ = cpu_to_be32(RPC_AUTH_UNIX);			/* auth_sys */
fc931582c   Andy Adamson   nfs41: create_ses...
1782
1783
  
  	/* authsys_parms rfc1831 */
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1784
  	*p++ = cpu_to_be32((u32)clp->cl_boot_time.tv_nsec);	/* stamp */
811652bd6   Benny Halevy   nfs: nfs4xdr: mer...
1785
  	p = xdr_encode_opaque(p, machine_name, len);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1786
1787
  	*p++ = cpu_to_be32(0);				/* UID */
  	*p++ = cpu_to_be32(0);				/* GID */
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1788
  	*p = cpu_to_be32(0);				/* No more gids */
fc931582c   Andy Adamson   nfs41: create_ses...
1789
1790
1791
  	hdr->nops++;
  	hdr->replen += decode_create_session_maxsz;
  }
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
1792
1793
1794
1795
1796
1797
  
  static void encode_destroy_session(struct xdr_stream *xdr,
  				   struct nfs4_session *session,
  				   struct compound_hdr *hdr)
  {
  	__be32 *p;
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1798
  	p = reserve_space(xdr, 4 + NFS4_MAX_SESSIONID_LEN);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1799
  	*p++ = cpu_to_be32(OP_DESTROY_SESSION);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1800
  	xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
1801
1802
1803
  	hdr->nops++;
  	hdr->replen += decode_destroy_session_maxsz;
  }
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
  
  static void encode_reclaim_complete(struct xdr_stream *xdr,
  				    struct nfs41_reclaim_complete_args *args,
  				    struct compound_hdr *hdr)
  {
  	__be32 *p;
  
  	p = reserve_space(xdr, 8);
  	*p++ = cpu_to_be32(OP_RECLAIM_COMPLETE);
  	*p++ = cpu_to_be32(args->one_fs);
  	hdr->nops++;
  	hdr->replen += decode_reclaim_complete_maxsz;
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
1817
  #endif /* CONFIG_NFS_V4_1 */
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
1818
1819
1820
1821
1822
1823
  static void encode_sequence(struct xdr_stream *xdr,
  			    const struct nfs4_sequence_args *args,
  			    struct compound_hdr *hdr)
  {
  #if defined(CONFIG_NFS_V4_1)
  	struct nfs4_session *session = args->sa_session;
fc01cea96   Andy Adamson   nfs41: sequence o...
1824
1825
1826
  	struct nfs4_slot_table *tp;
  	struct nfs4_slot *slot;
  	__be32 *p;
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
1827
1828
1829
  
  	if (!session)
  		return;
fc01cea96   Andy Adamson   nfs41: sequence o...
1830
1831
1832
1833
  	tp = &session->fc_slot_table;
  
  	WARN_ON(args->sa_slotid == NFS4_MAX_SLOT_TABLE);
  	slot = tp->slots + args->sa_slotid;
13c65ce90   Benny Halevy   nfs: nfs4xdr: cha...
1834
  	p = reserve_space(xdr, 4 + NFS4_MAX_SESSIONID_LEN + 16);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1835
  	*p++ = cpu_to_be32(OP_SEQUENCE);
fc01cea96   Andy Adamson   nfs41: sequence o...
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
  
  	/*
  	 * Sessionid + seqid + slotid + max slotid + cache_this
  	 */
  	dprintk("%s: sessionid=%u:%u:%u:%u seqid=%d slotid=%d "
  		"max_slotid=%d cache_this=%d
  ",
  		__func__,
  		((u32 *)session->sess_id.data)[0],
  		((u32 *)session->sess_id.data)[1],
  		((u32 *)session->sess_id.data)[2],
  		((u32 *)session->sess_id.data)[3],
  		slot->seq_nr, args->sa_slotid,
  		tp->highest_used_slotid, args->sa_cache_this);
93f0cf259   Benny Halevy   nfs: nfs4xdr: get...
1850
  	p = xdr_encode_opaque_fixed(p, session->sess_id.data, NFS4_MAX_SESSIONID_LEN);
e75bc1c89   Benny Halevy   nfs: nfs4xdr: get...
1851
1852
1853
  	*p++ = cpu_to_be32(slot->seq_nr);
  	*p++ = cpu_to_be32(args->sa_slotid);
  	*p++ = cpu_to_be32(tp->highest_used_slotid);
345585132   Benny Halevy   nfs: nfs4xdr: opt...
1854
  	*p = cpu_to_be32(args->sa_cache_this);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
1855
1856
1857
1858
  	hdr->nops++;
  	hdr->replen += decode_sequence_maxsz;
  #endif /* CONFIG_NFS_V4_1 */
  }
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
1859
1860
  #ifdef CONFIG_NFS_V4_1
  static void
7f11d8d38   Andy Adamson   pnfs: GETDEVICELIST
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
  encode_getdevicelist(struct xdr_stream *xdr,
  		     const struct nfs4_getdevicelist_args *args,
  		     struct compound_hdr *hdr)
  {
  	__be32 *p;
  	nfs4_verifier dummy = {
  		.data = "dummmmmy",
  	};
  
  	p = reserve_space(xdr, 20);
  	*p++ = cpu_to_be32(OP_GETDEVICELIST);
  	*p++ = cpu_to_be32(args->layoutclass);
  	*p++ = cpu_to_be32(NFS4_PNFS_GETDEVLIST_MAXNUM);
  	xdr_encode_hyper(p, 0ULL);                          /* cookie */
  	encode_nfs4_verifier(xdr, &dummy);
  	hdr->nops++;
  	hdr->replen += decode_getdevicelist_maxsz;
  }
  
  static void
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
  encode_getdeviceinfo(struct xdr_stream *xdr,
  		     const struct nfs4_getdeviceinfo_args *args,
  		     struct compound_hdr *hdr)
  {
  	__be32 *p;
  
  	p = reserve_space(xdr, 16 + NFS4_DEVICEID4_SIZE);
  	*p++ = cpu_to_be32(OP_GETDEVICEINFO);
  	p = xdr_encode_opaque_fixed(p, args->pdev->dev_id.data,
  				    NFS4_DEVICEID4_SIZE);
  	*p++ = cpu_to_be32(args->pdev->layout_type);
  	*p++ = cpu_to_be32(args->pdev->pglen);		/* gdia_maxcount */
  	*p++ = cpu_to_be32(0);				/* bitmap length 0 */
  	hdr->nops++;
  	hdr->replen += decode_getdeviceinfo_maxsz;
  }
  
  static void
  encode_layoutget(struct xdr_stream *xdr,
  		      const struct nfs4_layoutget_args *args,
  		      struct compound_hdr *hdr)
  {
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
  	__be32 *p;
  
  	p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE);
  	*p++ = cpu_to_be32(OP_LAYOUTGET);
  	*p++ = cpu_to_be32(0);     /* Signal layout available */
  	*p++ = cpu_to_be32(args->type);
  	*p++ = cpu_to_be32(args->range.iomode);
  	p = xdr_encode_hyper(p, args->range.offset);
  	p = xdr_encode_hyper(p, args->range.length);
  	p = xdr_encode_hyper(p, args->minlength);
cf7d63f1f   Fred Isaman   pnfs: serialize L...
1913
  	p = xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
  	*p = cpu_to_be32(args->maxcount);
  
  	dprintk("%s: 1st type:0x%x iomode:%d off:%lu len:%lu mc:%d
  ",
  		__func__,
  		args->type,
  		args->range.iomode,
  		(unsigned long)args->range.offset,
  		(unsigned long)args->range.length,
  		args->maxcount);
  	hdr->nops++;
  	hdr->replen += decode_layoutget_maxsz;
  }
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
1927
1928
1929
  
  static int
  encode_layoutcommit(struct xdr_stream *xdr,
ac7db7264   Benny Halevy   pnfs: encode_layo...
1930
  		    struct inode *inode,
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
1931
1932
1933
1934
1935
1936
1937
1938
  		    const struct nfs4_layoutcommit_args *args,
  		    struct compound_hdr *hdr)
  {
  	__be32 *p;
  
  	dprintk("%s: lbw: %llu type: %d
  ", __func__, args->lastbytewritten,
  		NFS_SERVER(args->inode)->pnfs_curr_ld->id);
ac7db7264   Benny Halevy   pnfs: encode_layo...
1939
  	p = reserve_space(xdr, 44 + NFS4_STATEID_SIZE);
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
1940
1941
1942
  	*p++ = cpu_to_be32(OP_LAYOUTCOMMIT);
  	/* Only whole file layouts */
  	p = xdr_encode_hyper(p, 0); /* offset */
3557c6c3b   Peng Tao   pnfs: use lwb as ...
1943
  	p = xdr_encode_hyper(p, args->lastbytewritten + 1);	/* length */
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
1944
1945
1946
1947
1948
1949
  	*p++ = cpu_to_be32(0); /* reclaim */
  	p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE);
  	*p++ = cpu_to_be32(1); /* newoffset = TRUE */
  	p = xdr_encode_hyper(p, args->lastbytewritten);
  	*p++ = cpu_to_be32(0); /* Never send time_modify_changed */
  	*p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
ac7db7264   Benny Halevy   pnfs: encode_layo...
1950
1951
1952
1953
1954
1955
1956
1957
  
  	if (NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit)
  		NFS_SERVER(inode)->pnfs_curr_ld->encode_layoutcommit(
  			NFS_I(inode)->layout, xdr, args);
  	else {
  		p = reserve_space(xdr, 4);
  		*p = cpu_to_be32(0); /* no layout-type payload */
  	}
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
1958
1959
1960
1961
1962
  
  	hdr->nops++;
  	hdr->replen += decode_layoutcommit_maxsz;
  	return 0;
  }
cbe826036   Benny Halevy   pnfs: layoutreturn
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
  
  static void
  encode_layoutreturn(struct xdr_stream *xdr,
  		    const struct nfs4_layoutreturn_args *args,
  		    struct compound_hdr *hdr)
  {
  	__be32 *p;
  
  	p = reserve_space(xdr, 20);
  	*p++ = cpu_to_be32(OP_LAYOUTRETURN);
  	*p++ = cpu_to_be32(0);		/* reclaim. always 0 for now */
  	*p++ = cpu_to_be32(args->layout_type);
  	*p++ = cpu_to_be32(IOMODE_ANY);
  	*p = cpu_to_be32(RETURN_FILE);
  	p = reserve_space(xdr, 16 + NFS4_STATEID_SIZE);
  	p = xdr_encode_hyper(p, 0);
  	p = xdr_encode_hyper(p, NFS4_MAX_UINT64);
  	spin_lock(&args->inode->i_lock);
  	xdr_encode_opaque_fixed(p, &args->stateid.data, NFS4_STATEID_SIZE);
  	spin_unlock(&args->inode->i_lock);
04a555498   Andy Adamson   pnfs: encode_layo...
1983
1984
1985
1986
1987
1988
1989
  	if (NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn) {
  		NFS_SERVER(args->inode)->pnfs_curr_ld->encode_layoutreturn(
  			NFS_I(args->inode)->layout, xdr, args);
  	} else {
  		p = reserve_space(xdr, 4);
  		*p = cpu_to_be32(0);
  	}
cbe826036   Benny Halevy   pnfs: layoutreturn
1990
1991
1992
  	hdr->nops++;
  	hdr->replen += decode_layoutreturn_maxsz;
  }
fca78d6d2   Bryan Schumaker   NFS: Add SECINFO_...
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
  
  static int
  encode_secinfo_no_name(struct xdr_stream *xdr,
  		       const struct nfs41_secinfo_no_name_args *args,
  		       struct compound_hdr *hdr)
  {
  	__be32 *p;
  	p = reserve_space(xdr, 8);
  	*p++ = cpu_to_be32(OP_SECINFO_NO_NAME);
  	*p++ = cpu_to_be32(args->style);
  	hdr->nops++;
  	hdr->replen += decode_secinfo_no_name_maxsz;
  	return 0;
  }
7d9747947   Bryan Schumaker   NFS: Added TEST_S...
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
  
  static void encode_test_stateid(struct xdr_stream *xdr,
  				struct nfs41_test_stateid_args *args,
  				struct compound_hdr *hdr)
  {
  	__be32 *p;
  
  	p = reserve_space(xdr, 8 + NFS4_STATEID_SIZE);
  	*p++ = cpu_to_be32(OP_TEST_STATEID);
  	*p++ = cpu_to_be32(1);
  	xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE);
  	hdr->nops++;
  	hdr->replen += decode_test_stateid_maxsz;
  }
9aeda35fd   Bryan Schumaker   NFS: added FREE_S...
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
  
  static void encode_free_stateid(struct xdr_stream *xdr,
  				struct nfs41_free_stateid_args *args,
  				struct compound_hdr *hdr)
  {
  	__be32 *p;
  	p = reserve_space(xdr, 4 + NFS4_STATEID_SIZE);
  	*p++ = cpu_to_be32(OP_FREE_STATEID);
  	xdr_encode_opaque_fixed(p, args->stateid->data, NFS4_STATEID_SIZE);
  	hdr->nops++;
  	hdr->replen += decode_free_stateid_maxsz;
  }
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2033
  #endif /* CONFIG_NFS_V4_1 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2034
2035
2036
  /*
   * END OF "GENERIC" ENCODE ROUTINES.
   */
66cc04297   Benny Halevy   nfs41: encode min...
2037
2038
2039
2040
  static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
  {
  #if defined(CONFIG_NFS_V4_1)
  	if (args->sa_session)
a44323453   Trond Myklebust   NFSv41: Deprecate...
2041
  		return args->sa_session->clp->cl_mvops->minor_version;
66cc04297   Benny Halevy   nfs41: encode min...
2042
2043
2044
  #endif /* CONFIG_NFS_V4_1 */
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2045
2046
2047
  /*
   * Encode an ACCESS request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2048
2049
  static void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr,
  				const struct nfs4_accessargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2050
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2051
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2052
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2053
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2054

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2055
2056
2057
2058
2059
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_access(xdr, args->access, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2060
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2061
2062
2063
2064
2065
  }
  
  /*
   * Encode LOOKUP request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2066
2067
  static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
  				const struct nfs4_lookup_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2068
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2069
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2070
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2071
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2072

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2073
2074
2075
2076
2077
2078
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->dir_fh, &hdr);
  	encode_lookup(xdr, args->name, &hdr);
  	encode_getfh(xdr, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2079
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2080
2081
2082
2083
2084
  }
  
  /*
   * Encode LOOKUP_ROOT request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2085
2086
2087
  static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
  				     const struct nfs4_lookup_root_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2088
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2089
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2090
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2091
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2092

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2093
2094
2095
2096
2097
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putrootfh(xdr, &hdr);
  	encode_getfh(xdr, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2098
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2099
2100
2101
2102
2103
  }
  
  /*
   * Encode REMOVE request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2104
2105
  static void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr,
  				const struct nfs_removeargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2106
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2107
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2108
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2109
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2110

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2111
2112
2113
2114
2115
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_remove(xdr, &args->name, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2116
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2117
2118
2119
2120
2121
  }
  
  /*
   * Encode RENAME request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2122
2123
  static void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr,
  				const struct nfs_renameargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2124
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2125
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2126
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2127
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2128

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2129
2130
2131
2132
2133
2134
2135
2136
2137
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->old_dir, &hdr);
  	encode_savefh(xdr, &hdr);
  	encode_putfh(xdr, args->new_dir, &hdr);
  	encode_rename(xdr, args->old_name, args->new_name, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
  	encode_restorefh(xdr, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2138
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2139
2140
2141
2142
2143
  }
  
  /*
   * Encode LINK request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2144
2145
  static void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr,
  			     const struct nfs4_link_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2146
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2147
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2148
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2149
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2150

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2151
2152
2153
2154
2155
2156
2157
2158
2159
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_savefh(xdr, &hdr);
  	encode_putfh(xdr, args->dir_fh, &hdr);
  	encode_link(xdr, args->name, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
  	encode_restorefh(xdr, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2160
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2161
2162
2163
2164
2165
  }
  
  /*
   * Encode CREATE request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2166
2167
  static void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr,
  				const struct nfs4_create_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2168
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2169
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2170
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2171
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2172

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2173
2174
2175
2176
2177
2178
2179
2180
2181
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->dir_fh, &hdr);
  	encode_savefh(xdr, &hdr);
  	encode_create(xdr, args, &hdr);
  	encode_getfh(xdr, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
  	encode_restorefh(xdr, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2182
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2183
2184
2185
2186
2187
  }
  
  /*
   * Encode SYMLINK request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2188
2189
  static void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr,
  				 const struct nfs4_create_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2190
  {
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2191
  	nfs4_xdr_enc_create(req, xdr, args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2192
2193
2194
2195
2196
  }
  
  /*
   * Encode GETATTR request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2197
2198
  static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr,
  				 const struct nfs4_getattr_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2199
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2200
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2201
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2202
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2203

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2204
2205
2206
2207
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2208
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2209
2210
2211
2212
2213
  }
  
  /*
   * Encode a CLOSE request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2214
2215
  static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr,
  			       struct nfs_closeargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2216
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
2217
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2218
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
05d564fe0   Andy Adamson   NFS: fix tabs in ...
2219
  	};
05d564fe0   Andy Adamson   NFS: fix tabs in ...
2220

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2221
2222
2223
2224
2225
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_close(xdr, args, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2226
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2227
2228
2229
2230
2231
  }
  
  /*
   * Encode an OPEN request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2232
2233
  static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr,
  			      struct nfs_openargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2234
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2235
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2236
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2237
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2238

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2239
2240
2241
2242
2243
2244
2245
2246
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_savefh(xdr, &hdr);
  	encode_open(xdr, args, &hdr);
  	encode_getfh(xdr, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
  	encode_restorefh(xdr, &hdr);
6926afd19   Trond Myklebust   NFSv4: Save the o...
2247
  	encode_getfattr(xdr, args->dir_bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2248
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2249
2250
2251
2252
2253
  }
  
  /*
   * Encode an OPEN_CONFIRM request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2254
2255
2256
  static void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req,
  				      struct xdr_stream *xdr,
  				      struct nfs_open_confirmargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2257
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2258
  	struct compound_hdr hdr = {
d017931cf   Andy Adamson   NFS: increment nu...
2259
  		.nops   = 0,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2260
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2261

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2262
2263
2264
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_open_confirm(xdr, args, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2265
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2266
2267
2268
2269
2270
  }
  
  /*
   * Encode an OPEN request with no attributes.
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2271
2272
2273
  static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
  				     struct nfs_openargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2274
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2275
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2276
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2277
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2278

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2279
2280
2281
2282
2283
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_open(xdr, args, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2284
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2285
2286
2287
2288
2289
  }
  
  /*
   * Encode an OPEN_DOWNGRADE request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2290
2291
2292
  static void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req,
  					struct xdr_stream *xdr,
  					struct nfs_closeargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2293
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2294
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2295
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2296
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2297

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2298
2299
2300
2301
2302
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_open_downgrade(xdr, args, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2303
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2304
2305
2306
2307
2308
  }
  
  /*
   * Encode a LOCK request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2309
2310
  static void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr,
  			      struct nfs_lock_args *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2311
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2312
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2313
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2314
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2315

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2316
2317
2318
2319
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_lock(xdr, args, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2320
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2321
2322
2323
2324
2325
  }
  
  /*
   * Encode a LOCKT request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2326
2327
  static void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr,
  			       struct nfs_lockt_args *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2328
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2329
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2330
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2331
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2332

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2333
2334
2335
2336
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_lockt(xdr, args, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2337
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2338
2339
2340
2341
2342
  }
  
  /*
   * Encode a LOCKU request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2343
2344
  static void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr,
  			       struct nfs_locku_args *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2345
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2346
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2347
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2348
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2349

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2350
2351
2352
2353
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_locku(xdr, args, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2354
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2355
  }
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2356
2357
2358
  static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req,
  					   struct xdr_stream *xdr,
  					struct nfs_release_lockowner_args *args)
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
2359
  {
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
2360
2361
2362
  	struct compound_hdr hdr = {
  		.minorversion = 0,
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2363
2364
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_release_lockowner(xdr, &args->lock_owner, &hdr);
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
2365
  	encode_nops(&hdr);
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
2366
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2367
2368
2369
  /*
   * Encode a READLINK request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2370
2371
  static void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr,
  				  const struct nfs4_readlink *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2372
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2373
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2374
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2375
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2376

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2377
2378
2379
2380
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_readlink(xdr, args, req, &hdr);
e3a535e17   Trond Myklebust   NFSv4: Fix the nf...
2381

28f566942   Benny Halevy   NFS: use dynamica...
2382
  	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
e3a535e17   Trond Myklebust   NFSv4: Fix the nf...
2383
  			args->pgbase, args->pglen);
d017931cf   Andy Adamson   NFS: increment nu...
2384
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2385
2386
2387
2388
2389
  }
  
  /*
   * Encode a READDIR request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2390
2391
  static void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr,
  				 const struct nfs4_readdir_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2392
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2393
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2394
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2395
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2396

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2397
2398
2399
2400
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_readdir(xdr, args, req, &hdr);
d6ac02dfa   Trond Myklebust   NFSv4: Fix the re...
2401

28f566942   Benny Halevy   NFS: use dynamica...
2402
  	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages,
d6ac02dfa   Trond Myklebust   NFSv4: Fix the re...
2403
2404
2405
  			 args->pgbase, args->count);
  	dprintk("%s: inlined page args = (%u, %p, %u, %u)
  ",
28f566942   Benny Halevy   NFS: use dynamica...
2406
  			__func__, hdr.replen << 2, args->pages,
d6ac02dfa   Trond Myklebust   NFSv4: Fix the re...
2407
  			args->pgbase, args->count);
d017931cf   Andy Adamson   NFS: increment nu...
2408
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2409
2410
2411
2412
2413
  }
  
  /*
   * Encode a READ request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2414
2415
  static void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr,
  			      struct nfs_readargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2416
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2417
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2418
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2419
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2420

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2421
2422
2423
2424
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_read(xdr, args, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2425

28f566942   Benny Halevy   NFS: use dynamica...
2426
  	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2427
  			 args->pages, args->pgbase, args->count);
4f22ccc34   \"Talpey, Thomas\   SUNRPC: mark bulk...
2428
  	req->rq_rcv_buf.flags |= XDRBUF_READ;
d017931cf   Andy Adamson   NFS: increment nu...
2429
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2430
2431
2432
2433
2434
  }
  
  /*
   * Encode an SETATTR request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2435
2436
  static void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr,
  				 struct nfs_setattrargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2437
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
2438
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2439
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
05d564fe0   Andy Adamson   NFS: fix tabs in ...
2440
  	};
05d564fe0   Andy Adamson   NFS: fix tabs in ...
2441

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2442
2443
2444
2445
2446
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_setattr(xdr, args, args->server, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2447
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2448
2449
2450
  }
  
  /*
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
2451
2452
   * Encode a GETACL request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2453
2454
  static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
  				struct nfs_getaclargs *args)
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
2455
  {
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
2456
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2457
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
2458
  	};
28f566942   Benny Halevy   NFS: use dynamica...
2459
  	uint32_t replen;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
2460

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2461
2462
2463
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
bf118a342   Andy Adamson   NFSv4: include bi...
2464
  	replen = hdr.replen + op_decode_hdr_maxsz + 1;
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2465
  	encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
2466

28f566942   Benny Halevy   NFS: use dynamica...
2467
  	xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
2468
  		args->acl_pages, args->acl_pgbase, args->acl_len);
bf118a342   Andy Adamson   NFSv4: include bi...
2469
  	xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
d017931cf   Andy Adamson   NFS: increment nu...
2470
  	encode_nops(&hdr);
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
2471
2472
2473
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2474
2475
   * Encode a WRITE request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2476
2477
  static void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr,
  			       struct nfs_writeargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2478
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2479
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2480
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2481
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2482

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2483
2484
2485
2486
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_write(xdr, args, &hdr);
4f22ccc34   \"Talpey, Thomas\   SUNRPC: mark bulk...
2487
  	req->rq_snd_buf.flags |= XDRBUF_WRITE;
7ffd10640   Fred Isaman   NFSv4.1: remove G...
2488
2489
  	if (args->bitmask)
  		encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2490
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2491
2492
2493
2494
2495
  }
  
  /*
   *  a COMMIT request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2496
2497
  static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr,
  				struct nfs_writeargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2498
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2499
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2500
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2501
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2502

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2503
2504
2505
2506
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_commit(xdr, args, &hdr);
988b6dceb   Fred Isaman   NFSv4.1: remove G...
2507
2508
  	if (args->bitmask)
  		encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2509
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2510
2511
2512
2513
2514
  }
  
  /*
   * FSINFO request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2515
2516
  static void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr,
  				struct nfs4_fsinfo_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2517
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2518
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2519
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2520
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2521

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2522
2523
2524
2525
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_fsinfo(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2526
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2527
2528
2529
2530
2531
  }
  
  /*
   * a PATHCONF request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2532
2533
  static void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
  				  const struct nfs4_pathconf_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2534
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2535
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2536
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2537
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2538

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2539
2540
2541
2542
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_getattr_one(xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0],
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
2543
  			   &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2544
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2545
2546
2547
2548
2549
  }
  
  /*
   * a STATFS request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2550
2551
  static void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
  				const struct nfs4_statfs_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2552
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2553
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2554
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2555
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2556

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2557
2558
2559
2560
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_getattr_two(xdr, args->bitmask[0] & nfs4_statfs_bitmap[0],
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
2561
  			   args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2562
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2563
2564
2565
2566
2567
  }
  
  /*
   * GETATTR_BITMAP request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2568
2569
2570
  static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
  				     struct nfs4_server_caps_arg *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2571
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2572
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2573
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2574
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2575

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2576
2577
2578
2579
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fhandle, &hdr);
  	encode_getattr_one(xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
2580
2581
2582
  			   FATTR4_WORD0_LINK_SUPPORT|
  			   FATTR4_WORD0_SYMLINK_SUPPORT|
  			   FATTR4_WORD0_ACLSUPPORT, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2583
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2584
2585
2586
2587
2588
  }
  
  /*
   * a RENEW request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2589
2590
  static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr,
  			       struct nfs_client *clp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2591
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2592
  	struct compound_hdr hdr = {
d017931cf   Andy Adamson   NFS: increment nu...
2593
  		.nops	= 0,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2594
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2595
2596
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_renew(xdr, clp, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2597
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2598
2599
2600
2601
2602
  }
  
  /*
   * a SETCLIENTID request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2603
2604
2605
  static void nfs4_xdr_enc_setclientid(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
  				     struct nfs4_setclientid *sc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2606
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2607
  	struct compound_hdr hdr = {
d017931cf   Andy Adamson   NFS: increment nu...
2608
  		.nops	= 0,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2609
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2610
2611
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_setclientid(xdr, sc, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2612
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2613
2614
2615
2616
2617
  }
  
  /*
   * a SETCLIENTID_CONFIRM request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2618
2619
2620
  static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req,
  					     struct xdr_stream *xdr,
  					     struct nfs4_setclientid_res *arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2621
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2622
  	struct compound_hdr hdr = {
d017931cf   Andy Adamson   NFS: increment nu...
2623
  		.nops	= 0,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2624
  	};
dae100c2b   Fred Isaman   pnfs: ask for lay...
2625
  	const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2626

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2627
2628
2629
2630
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_setclientid_confirm(xdr, arg, &hdr);
  	encode_putrootfh(xdr, &hdr);
  	encode_fsinfo(xdr, lease_bitmap, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2631
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2632
2633
2634
2635
2636
  }
  
  /*
   * DELEGRETURN request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2637
2638
2639
  static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
  				     const struct nfs4_delegreturnargs *args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2640
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2641
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2642
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2643
  	};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2644

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2645
2646
2647
2648
2649
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fhandle, &hdr);
  	encode_delegreturn(xdr, args->stateid, &hdr);
  	encode_getfattr(xdr, args->bitmask, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
2650
  	encode_nops(&hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2651
2652
2653
  }
  
  /*
683b57b43   Trond Myklebust   NFSv4: Implement ...
2654
2655
   * Encode FS_LOCATIONS request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2656
2657
2658
  static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req,
  				      struct xdr_stream *xdr,
  				      struct nfs4_fs_locations_arg *args)
683b57b43   Trond Myklebust   NFSv4: Implement ...
2659
  {
683b57b43   Trond Myklebust   NFSv4: Implement ...
2660
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
2661
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
683b57b43   Trond Myklebust   NFSv4: Implement ...
2662
  	};
28f566942   Benny Halevy   NFS: use dynamica...
2663
  	uint32_t replen;
683b57b43   Trond Myklebust   NFSv4: Implement ...
2664

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2665
2666
2667
2668
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->dir_fh, &hdr);
  	encode_lookup(xdr, args->name, &hdr);
28f566942   Benny Halevy   NFS: use dynamica...
2669
  	replen = hdr.replen;	/* get the attribute into args->page */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2670
  	encode_fs_locations(xdr, args->bitmask, &hdr);
cf8cdbe5b   Andy Adamson   NFS: remove unuse...
2671

28f566942   Benny Halevy   NFS: use dynamica...
2672
  	xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page,
683b57b43   Trond Myklebust   NFSv4: Implement ...
2673
  			0, PAGE_SIZE);
d017931cf   Andy Adamson   NFS: increment nu...
2674
  	encode_nops(&hdr);
683b57b43   Trond Myklebust   NFSv4: Implement ...
2675
  }
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
  /*
   * Encode SECINFO request
   */
  static void nfs4_xdr_enc_secinfo(struct rpc_rqst *req,
  				struct xdr_stream *xdr,
  				struct nfs4_secinfo_arg *args)
  {
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
  
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->dir_fh, &hdr);
  	encode_secinfo(xdr, args->name, &hdr);
  	encode_nops(&hdr);
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
2693
2694
2695
2696
  #if defined(CONFIG_NFS_V4_1)
  /*
   * EXCHANGE_ID request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2697
2698
2699
  static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
  				     struct nfs41_exchange_id_args *args)
99fe60d06   Benny Halevy   nfs41: exchange_i...
2700
  {
99fe60d06   Benny Halevy   nfs41: exchange_i...
2701
  	struct compound_hdr hdr = {
a44323453   Trond Myklebust   NFSv41: Deprecate...
2702
  		.minorversion = args->client->cl_mvops->minor_version,
99fe60d06   Benny Halevy   nfs41: exchange_i...
2703
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2704
2705
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_exchange_id(xdr, args, &hdr);
99fe60d06   Benny Halevy   nfs41: exchange_i...
2706
  	encode_nops(&hdr);
99fe60d06   Benny Halevy   nfs41: exchange_i...
2707
  }
2050f0cc0   Andy Adamson   nfs41: get_lease_...
2708
2709
  
  /*
fc931582c   Andy Adamson   nfs41: create_ses...
2710
2711
   * a CREATE_SESSION request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2712
2713
2714
  static void nfs4_xdr_enc_create_session(struct rpc_rqst *req,
  					struct xdr_stream *xdr,
  					struct nfs41_create_session_args *args)
fc931582c   Andy Adamson   nfs41: create_ses...
2715
  {
fc931582c   Andy Adamson   nfs41: create_ses...
2716
  	struct compound_hdr hdr = {
a44323453   Trond Myklebust   NFSv41: Deprecate...
2717
  		.minorversion = args->client->cl_mvops->minor_version,
fc931582c   Andy Adamson   nfs41: create_ses...
2718
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2719
2720
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_create_session(xdr, args, &hdr);
fc931582c   Andy Adamson   nfs41: create_ses...
2721
  	encode_nops(&hdr);
fc931582c   Andy Adamson   nfs41: create_ses...
2722
2723
2724
  }
  
  /*
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
2725
2726
   * a DESTROY_SESSION request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2727
2728
2729
  static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req,
  					 struct xdr_stream *xdr,
  					 struct nfs4_session *session)
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
2730
  {
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
2731
  	struct compound_hdr hdr = {
a44323453   Trond Myklebust   NFSv41: Deprecate...
2732
  		.minorversion = session->clp->cl_mvops->minor_version,
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
2733
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2734
2735
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_destroy_session(xdr, session, &hdr);
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
2736
  	encode_nops(&hdr);
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
2737
2738
2739
  }
  
  /*
fc01cea96   Andy Adamson   nfs41: sequence o...
2740
2741
   * a SEQUENCE request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2742
2743
  static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr,
  				  struct nfs4_sequence_args *args)
fc01cea96   Andy Adamson   nfs41: sequence o...
2744
  {
fc01cea96   Andy Adamson   nfs41: sequence o...
2745
2746
2747
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(args),
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2748
2749
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, args, &hdr);
fc01cea96   Andy Adamson   nfs41: sequence o...
2750
  	encode_nops(&hdr);
fc01cea96   Andy Adamson   nfs41: sequence o...
2751
2752
2753
  }
  
  /*
2050f0cc0   Andy Adamson   nfs41: get_lease_...
2754
2755
   * a GET_LEASE_TIME request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2756
2757
2758
  static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req,
  					struct xdr_stream *xdr,
  					struct nfs4_get_lease_time_args *args)
2050f0cc0   Andy Adamson   nfs41: get_lease_...
2759
  {
2050f0cc0   Andy Adamson   nfs41: get_lease_...
2760
2761
2762
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->la_seq_args),
  	};
dae100c2b   Fred Isaman   pnfs: ask for lay...
2763
  	const u32 lease_bitmap[3] = { FATTR4_WORD0_LEASE_TIME };
2050f0cc0   Andy Adamson   nfs41: get_lease_...
2764

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2765
2766
2767
2768
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->la_seq_args, &hdr);
  	encode_putrootfh(xdr, &hdr);
  	encode_fsinfo(xdr, lease_bitmap, &hdr);
2050f0cc0   Andy Adamson   nfs41: get_lease_...
2769
  	encode_nops(&hdr);
2050f0cc0   Andy Adamson   nfs41: get_lease_...
2770
  }
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
2771
2772
2773
2774
  
  /*
   * a RECLAIM_COMPLETE request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2775
2776
2777
  static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req,
  					  struct xdr_stream *xdr,
  				struct nfs41_reclaim_complete_args *args)
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
2778
  {
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
2779
2780
2781
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args)
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2782
2783
2784
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_reclaim_complete(xdr, args, &hdr);
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
2785
  	encode_nops(&hdr);
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
2786
  }
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2787
  /*
7f11d8d38   Andy Adamson   pnfs: GETDEVICELIST
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
   * Encode GETDEVICELIST request
   */
  static void nfs4_xdr_enc_getdevicelist(struct rpc_rqst *req,
  				       struct xdr_stream *xdr,
  				       struct nfs4_getdevicelist_args *args)
  {
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
  
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_getdevicelist(xdr, args, &hdr);
  	encode_nops(&hdr);
  }
  
  /*
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2806
2807
   * Encode GETDEVICEINFO request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2808
2809
2810
  static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req,
  				       struct xdr_stream *xdr,
  				       struct nfs4_getdeviceinfo_args *args)
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2811
  {
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2812
2813
2814
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2815
2816
2817
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_getdeviceinfo(xdr, args, &hdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2818
2819
2820
2821
2822
2823
2824
2825
  
  	/* set up reply kvec. Subtract notification bitmap max size (2)
  	 * so that notification bitmap is put in xdr_buf tail */
  	xdr_inline_pages(&req->rq_rcv_buf, (hdr.replen - 2) << 2,
  			 args->pdev->pages, args->pdev->pgbase,
  			 args->pdev->pglen);
  
  	encode_nops(&hdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2826
2827
2828
2829
2830
  }
  
  /*
   *  Encode LAYOUTGET request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2831
2832
2833
  static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req,
  				   struct xdr_stream *xdr,
  				   struct nfs4_layoutget_args *args)
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2834
  {
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2835
2836
2837
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
2838
2839
2840
2841
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
  	encode_layoutget(xdr, args, &hdr);
35124a099   Weston Andros Adamson   Cleanup XDR parsi...
2842
2843
2844
  
  	xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2,
  	    args->layout.pages, 0, args->layout.pglen);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2845
  	encode_nops(&hdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2846
  }
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
2847
2848
2849
2850
  
  /*
   *  Encode LAYOUTCOMMIT request
   */
cbe826036   Benny Halevy   pnfs: layoutreturn
2851
2852
2853
  static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
  				      struct xdr_stream *xdr,
  				      struct nfs4_layoutcommit_args *args)
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
2854
  {
ac7db7264   Benny Halevy   pnfs: encode_layo...
2855
2856
  	struct nfs4_layoutcommit_data *data =
  		container_of(args, struct nfs4_layoutcommit_data, args);
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
2857
2858
2859
2860
2861
2862
2863
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
  
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
ac7db7264   Benny Halevy   pnfs: encode_layo...
2864
  	encode_layoutcommit(xdr, data->args.inode, args, &hdr);
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
2865
  	encode_getfattr(xdr, args->bitmask, &hdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2866
  	encode_nops(&hdr);
cbe826036   Benny Halevy   pnfs: layoutreturn
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
  }
  
  /*
   * Encode LAYOUTRETURN request
   */
  static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req,
  				      struct xdr_stream *xdr,
  				      struct nfs4_layoutreturn_args *args)
  {
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
  
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, NFS_FH(args->inode), &hdr);
  	encode_layoutreturn(xdr, args, &hdr);
  	encode_nops(&hdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
2885
  }
fca78d6d2   Bryan Schumaker   NFS: Add SECINFO_...
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
  
  /*
   * Encode SECINFO_NO_NAME request
   */
  static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req,
  					struct xdr_stream *xdr,
  					struct nfs41_secinfo_no_name_args *args)
  {
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
  
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putrootfh(xdr, &hdr);
  	encode_secinfo_no_name(xdr, args, &hdr);
  	encode_nops(&hdr);
  	return 0;
  }
7d9747947   Bryan Schumaker   NFS: Added TEST_S...
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
  
  /*
   *  Encode TEST_STATEID request
   */
  static void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req,
  				      struct xdr_stream *xdr,
  				      struct nfs41_test_stateid_args *args)
  {
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
  
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_test_stateid(xdr, args, &hdr);
  	encode_nops(&hdr);
  }
9aeda35fd   Bryan Schumaker   NFS: added FREE_S...
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
  
  /*
   *  Encode FREE_STATEID request
   */
  static void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
  				     struct nfs41_free_stateid_args *args)
  {
  	struct compound_hdr hdr = {
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
  	};
  
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_free_stateid(xdr, args, &hdr);
  	encode_nops(&hdr);
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
2939
  #endif /* CONFIG_NFS_V4_1 */
686841b3c   Benny Halevy   nfs: nfs4xdr: int...
2940
2941
2942
2943
2944
2945
2946
  static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
  {
  	dprintk("nfs: %s: prematurely hit end of receive buffer. "
  		"Remaining buffer length is %tu words.
  ",
  		func, xdr->end - xdr->p);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2947

683b57b43   Trond Myklebust   NFSv4: Implement ...
2948
  static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2949
  {
8687b63af   Al Viro   [PATCH] xdr annot...
2950
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2951

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
2952
2953
2954
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
2955
  	*len = be32_to_cpup(p);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
2956
2957
2958
  	p = xdr_inline_decode(xdr, *len);
  	if (unlikely(!p))
  		goto out_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2959
2960
  	*string = (char *)p;
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
2961
2962
2963
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2964
2965
2966
2967
  }
  
  static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
2968
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2969

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
2970
2971
2972
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
2973
  	hdr->status = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
2974
  	hdr->taglen = be32_to_cpup(p);
6c0195a46   Andy Adamson   NFS: remove white...
2975

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
2976
2977
2978
  	p = xdr_inline_decode(xdr, hdr->taglen + 4);
  	if (unlikely(!p))
  		goto out_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2979
2980
  	hdr->tag = (char *)p;
  	p += XDR_QUADLEN(hdr->taglen);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
2981
  	hdr->nops = be32_to_cpup(p);
aadf61521   Benny Halevy   nfs: return compo...
2982
2983
  	if (unlikely(hdr->nops < 1))
  		return nfs4_stat_to_errno(hdr->status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2984
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
2985
2986
2987
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2988
2989
2990
2991
  }
  
  static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
2992
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2993
2994
  	uint32_t opnum;
  	int32_t nfserr;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
2995
2996
2997
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
2998
  	opnum = be32_to_cpup(p++);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2999
  	if (opnum != expected) {
fe82a183c   Chuck Lever   NFS: Convert prin...
3000
3001
3002
  		dprintk("nfs: Server returned operation"
  			" %d but we issued a request for %d
  ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3003
3004
3005
  				opnum, expected);
  		return -EIO;
  	}
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3006
  	nfserr = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3007
  	if (nfserr != NFS_OK)
856dff3d3   Benny Halevy   nfs: return negat...
3008
  		return nfs4_stat_to_errno(nfserr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3009
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3010
3011
3012
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3013
3014
3015
  }
  
  /* Dummy routine */
adfa6f980   David Howells   NFS: Rename struc...
3016
  static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3017
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3018
  	__be32 *p;
683b57b43   Trond Myklebust   NFSv4: Implement ...
3019
  	unsigned int strlen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3020
  	char *str;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3021
3022
3023
3024
3025
  	p = xdr_inline_decode(xdr, 12);
  	if (likely(p))
  		return decode_opaque_inline(xdr, &strlen, &str);
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3026
3027
3028
3029
  }
  
  static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3030
3031
  	uint32_t bmlen;
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3032

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3033
3034
3035
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3036
  	bmlen = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3037

dae100c2b   Fred Isaman   pnfs: ask for lay...
3038
  	bitmap[0] = bitmap[1] = bitmap[2] = 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3039
3040
3041
  	p = xdr_inline_decode(xdr, (bmlen << 2));
  	if (unlikely(!p))
  		goto out_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3042
  	if (bmlen > 0) {
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
3043
  		bitmap[0] = be32_to_cpup(p++);
dae100c2b   Fred Isaman   pnfs: ask for lay...
3044
3045
3046
3047
3048
  		if (bmlen > 1) {
  			bitmap[1] = be32_to_cpup(p++);
  			if (bmlen > 2)
  				bitmap[2] = be32_to_cpup(p);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3049
3050
  	}
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3051
3052
3053
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3054
  }
8687b63af   Al Viro   [PATCH] xdr annot...
3055
  static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3056
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3057
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3058

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3059
3060
3061
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3062
  	*attrlen = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3063
3064
  	*savep = xdr->p;
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3065
3066
3067
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3068
3069
3070
3071
3072
  }
  
  static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask)
  {
  	if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) {
3388bff5c   Roman Borisov   nfs: fix unchecke...
3073
3074
3075
3076
  		int ret;
  		ret = decode_attr_bitmap(xdr, bitmask);
  		if (unlikely(ret < 0))
  			return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3077
3078
  		bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS;
  	} else
dae100c2b   Fred Isaman   pnfs: ask for lay...
3079
3080
3081
3082
  		bitmask[0] = bitmask[1] = bitmask[2] = 0;
  	dprintk("%s: bitmask=%08x:%08x:%08x
  ", __func__,
  		bitmask[0], bitmask[1], bitmask[2]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3083
3084
3085
3086
3087
  	return 0;
  }
  
  static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3088
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3089
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3090
3091
3092
3093
3094
  
  	*type = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3095
3096
3097
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3098
  		*type = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3099
  		if (*type < NF4REG || *type > NF4NAMEDATTR) {
3110ff804   Harvey Harrison   nfs: replace rema...
3100
3101
  			dprintk("%s: bad type %d
  ", __func__, *type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3102
3103
3104
  			return -EIO;
  		}
  		bitmap[0] &= ~FATTR4_WORD0_TYPE;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3105
  		ret = NFS_ATTR_FATTR_TYPE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3106
  	}
bca794785   Trond Myklebust   NFS: Fix the type...
3107
3108
  	dprintk("%s: type=0%o
  ", __func__, nfs_type2fmt[*type]);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3109
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3110
3111
3112
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3113
3114
3115
3116
  }
  
  static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3117
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3118
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3119
3120
3121
3122
3123
  
  	*change = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3124
3125
3126
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3127
  		xdr_decode_hyper(p, change);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3128
  		bitmap[0] &= ~FATTR4_WORD0_CHANGE;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3129
  		ret = NFS_ATTR_FATTR_CHANGE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3130
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3131
3132
  	dprintk("%s: change attribute=%Lu
  ", __func__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3133
  			(unsigned long long)*change);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3134
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3135
3136
3137
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3138
3139
3140
3141
  }
  
  static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3142
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3143
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3144
3145
3146
3147
3148
  
  	*size = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3149
3150
3151
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3152
  		xdr_decode_hyper(p, size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3153
  		bitmap[0] &= ~FATTR4_WORD0_SIZE;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3154
  		ret = NFS_ATTR_FATTR_SIZE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3155
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3156
3157
  	dprintk("%s: file size=%Lu
  ", __func__, (unsigned long long)*size);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3158
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3159
3160
3161
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3162
3163
3164
3165
  }
  
  static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3166
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3167
3168
3169
3170
3171
  
  	*res = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3172
3173
3174
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3175
  		*res = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3176
3177
  		bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3178
3179
  	dprintk("%s: link support=%s
  ", __func__, *res == 0 ? "false" : "true");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3180
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3181
3182
3183
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3184
3185
3186
3187
  }
  
  static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3188
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3189
3190
3191
3192
3193
  
  	*res = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3194
3195
3196
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3197
  		*res = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3198
3199
  		bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3200
3201
  	dprintk("%s: symlink support=%s
  ", __func__, *res == 0 ? "false" : "true");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3202
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3203
3204
3205
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3206
  }
8b4bdcf89   Trond Myklebust   NFS: Store the fi...
3207
  static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3208
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3209
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3210
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3211
3212
3213
3214
3215
3216
  
  	fsid->major = 0;
  	fsid->minor = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_FSID)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3217
3218
3219
  		p = xdr_inline_decode(xdr, 16);
  		if (unlikely(!p))
  			goto out_overflow;
3ceb4dbb9   Benny Halevy   nfs: nfs4xdr: get...
3220
  		p = xdr_decode_hyper(p, &fsid->major);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3221
  		xdr_decode_hyper(p, &fsid->minor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3222
  		bitmap[0] &= ~FATTR4_WORD0_FSID;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3223
  		ret = NFS_ATTR_FATTR_FSID;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3224
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3225
3226
  	dprintk("%s: fsid=(0x%Lx/0x%Lx)
  ", __func__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3227
3228
  			(unsigned long long)fsid->major,
  			(unsigned long long)fsid->minor);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3229
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3230
3231
3232
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3233
3234
3235
3236
  }
  
  static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3237
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3238
3239
3240
3241
3242
  
  	*res = 60;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3243
3244
3245
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3246
  		*res = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3247
3248
  		bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3249
3250
  	dprintk("%s: file size=%u
  ", __func__, (unsigned int)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3251
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3252
3253
3254
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3255
  }
ee7b75fc4   Trond Myklebust   NFSv4: Fix a read...
3256
  static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res)
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
  {
  	__be32 *p;
  
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_RDATTR_ERROR - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) {
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
  		bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
ee7b75fc4   Trond Myklebust   NFSv4: Fix a read...
3267
  		*res = -be32_to_cpup(p);
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
  	}
  	return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
  
  static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fh *fh)
  {
  	__be32 *p;
  	int len;
7ad073530   Trond Myklebust   NFSv4: Fix up dec...
3279
3280
  	if (fh != NULL)
  		memset(fh, 0, sizeof(*fh));
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
  
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEHANDLE - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) {
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
  		len = be32_to_cpup(p);
  		if (len > NFS4_FHSIZE)
  			return -EIO;
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
3291
3292
3293
  		p = xdr_inline_decode(xdr, len);
  		if (unlikely(!p))
  			goto out_overflow;
7ad073530   Trond Myklebust   NFSv4: Fix up dec...
3294
3295
3296
3297
  		if (fh != NULL) {
  			memcpy(fh->data, p, len);
  			fh->size = len;
  		}
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
3298
3299
3300
3301
3302
3303
3304
  		bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE;
  	}
  	return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3305
3306
  static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3307
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3308
3309
3310
3311
3312
  
  	*res = ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3313
3314
3315
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3316
  		*res = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3317
3318
  		bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3319
3320
  	dprintk("%s: ACLs supported=%u
  ", __func__, (unsigned int)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3321
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3322
3323
3324
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3325
3326
3327
3328
  }
  
  static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3329
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3330
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3331
3332
3333
3334
3335
  
  	*fileid = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3336
3337
3338
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3339
  		xdr_decode_hyper(p, fileid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3340
  		bitmap[0] &= ~FATTR4_WORD0_FILEID;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3341
  		ret = NFS_ATTR_FATTR_FILEID;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3342
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3343
3344
  	dprintk("%s: fileid=%Lu
  ", __func__, (unsigned long long)*fileid);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3345
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3346
3347
3348
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3349
  }
99baf625d   Manoj Naik   NFSv4: Decode mou...
3350
3351
  static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3352
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3353
  	int ret = 0;
99baf625d   Manoj Naik   NFSv4: Decode mou...
3354
3355
3356
3357
3358
  
  	*fileid = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3359
3360
3361
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3362
  		xdr_decode_hyper(p, fileid);
99baf625d   Manoj Naik   NFSv4: Decode mou...
3363
  		bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
28331a46d   Trond Myklebust   NFSv4: Ensure we ...
3364
  		ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID;
99baf625d   Manoj Naik   NFSv4: Decode mou...
3365
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3366
3367
  	dprintk("%s: fileid=%Lu
  ", __func__, (unsigned long long)*fileid);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3368
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3369
3370
3371
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
99baf625d   Manoj Naik   NFSv4: Decode mou...
3372
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3373
3374
  static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3375
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3376
3377
3378
3379
3380
3381
  	int status = 0;
  
  	*res = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3382
3383
3384
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3385
  		xdr_decode_hyper(p, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3386
3387
  		bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3388
3389
  	dprintk("%s: files avail=%Lu
  ", __func__, (unsigned long long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3390
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3391
3392
3393
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3394
3395
3396
3397
  }
  
  static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3398
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3399
3400
3401
3402
3403
3404
  	int status = 0;
  
  	*res = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3405
3406
3407
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3408
  		xdr_decode_hyper(p, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3409
3410
  		bitmap[0] &= ~FATTR4_WORD0_FILES_FREE;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3411
3412
  	dprintk("%s: files free=%Lu
  ", __func__, (unsigned long long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3413
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3414
3415
3416
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3417
3418
3419
3420
  }
  
  static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3421
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3422
3423
3424
3425
3426
3427
  	int status = 0;
  
  	*res = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3428
3429
3430
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3431
  		xdr_decode_hyper(p, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3432
3433
  		bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3434
3435
  	dprintk("%s: files total=%Lu
  ", __func__, (unsigned long long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3436
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3437
3438
3439
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3440
  }
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3441
3442
  static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
  {
464ad6b1a   Chuck Lever   NFS: Change sign ...
3443
  	u32 n;
8687b63af   Al Viro   [PATCH] xdr annot...
3444
  	__be32 *p;
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3445
  	int status = 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3446
3447
3448
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3449
  	n = be32_to_cpup(p);
33a43f280   Andy Adamson   NFSv4: A root pat...
3450
3451
  	if (n == 0)
  		goto root_path;
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
  	dprintk("path ");
  	path->ncomponents = 0;
  	while (path->ncomponents < n) {
  		struct nfs4_string *component = &path->components[path->ncomponents];
  		status = decode_opaque_inline(xdr, &component->len, &component->data);
  		if (unlikely(status != 0))
  			goto out_eio;
  		if (path->ncomponents != n)
  			dprintk("/");
  		dprintk("%s", component->data);
  		if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS)
  			path->ncomponents++;
  		else {
  			dprintk("cannot parse %d components in path
  ", n);
  			goto out_eio;
  		}
  	}
  out:
  	dprintk("
  ");
  	return status;
33a43f280   Andy Adamson   NFSv4: A root pat...
3474
3475
3476
3477
3478
3479
3480
3481
  root_path:
  /* a root pathname is sent as a zero component4 */
  	path->ncomponents = 1;
  	path->components[0].len=0;
  	path->components[0].data=NULL;
  	dprintk("path /
  ");
  	goto out;
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3482
3483
3484
3485
  out_eio:
  	dprintk(" status %d", status);
  	status = -EIO;
  	goto out;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3486
3487
3488
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3489
3490
3491
  }
  
  static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res)
683b57b43   Trond Myklebust   NFSv4: Implement ...
3492
3493
  {
  	int n;
8687b63af   Al Viro   [PATCH] xdr annot...
3494
  	__be32 *p;
683b57b43   Trond Myklebust   NFSv4: Implement ...
3495
3496
3497
3498
3499
3500
3501
  	int status = -EIO;
  
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U)))
  		goto out;
  	status = 0;
  	if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
  		goto out;
3110ff804   Harvey Harrison   nfs: replace rema...
3502
  	dprintk("%s: fsroot ", __func__);
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3503
  	status = decode_pathname(xdr, &res->fs_path);
683b57b43   Trond Myklebust   NFSv4: Implement ...
3504
3505
  	if (unlikely(status != 0))
  		goto out;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3506
3507
3508
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3509
  	n = be32_to_cpup(p);
683b57b43   Trond Myklebust   NFSv4: Implement ...
3510
3511
3512
3513
  	if (n <= 0)
  		goto out_eio;
  	res->nlocations = 0;
  	while (res->nlocations < n) {
464ad6b1a   Chuck Lever   NFS: Change sign ...
3514
  		u32 m;
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3515
  		struct nfs4_fs_location *loc = &res->locations[res->nlocations];
683b57b43   Trond Myklebust   NFSv4: Implement ...
3516

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3517
3518
3519
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3520
  		m = be32_to_cpup(p);
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3521
3522
  
  		loc->nservers = 0;
3110ff804   Harvey Harrison   nfs: replace rema...
3523
  		dprintk("%s: servers ", __func__);
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3524
3525
3526
3527
3528
3529
3530
3531
3532
  		while (loc->nservers < m) {
  			struct nfs4_string *server = &loc->servers[loc->nservers];
  			status = decode_opaque_inline(xdr, &server->len, &server->data);
  			if (unlikely(status != 0))
  				goto out_eio;
  			dprintk("%s ", server->data);
  			if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS)
  				loc->nservers++;
  			else {
464ad6b1a   Chuck Lever   NFS: Change sign ...
3533
3534
3535
3536
  				unsigned int i;
  				dprintk("%s: using first %u of %u servers "
  					"returned for location %u
  ",
3110ff804   Harvey Harrison   nfs: replace rema...
3537
  						__func__,
464ad6b1a   Chuck Lever   NFS: Change sign ...
3538
3539
  						NFS4_FS_LOCATION_MAXSERVERS,
  						m, res->nlocations);
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3540
  				for (i = loc->nservers; i < m; i++) {
2e42c3e2a   Trond Myklebust   NFS: Fix more spa...
3541
  					unsigned int len;
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3542
3543
3544
3545
3546
3547
3548
3549
  					char *data;
  					status = decode_opaque_inline(xdr, &len, &data);
  					if (unlikely(status != 0))
  						goto out_eio;
  				}
  			}
  		}
  		status = decode_pathname(xdr, &loc->rootpath);
683b57b43   Trond Myklebust   NFSv4: Implement ...
3550
3551
  		if (unlikely(status != 0))
  			goto out_eio;
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
3552
  		if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES)
683b57b43   Trond Myklebust   NFSv4: Implement ...
3553
3554
  			res->nlocations++;
  	}
409924e4c   Trond Myklebust   NFSv4: Make decod...
3555
3556
  	if (res->nlocations != 0)
  		status = NFS_ATTR_FATTR_V4_REFERRAL;
683b57b43   Trond Myklebust   NFSv4: Implement ...
3557
  out:
3110ff804   Harvey Harrison   nfs: replace rema...
3558
3559
  	dprintk("%s: fs_locations done, error = %d
  ", __func__, status);
683b57b43   Trond Myklebust   NFSv4: Implement ...
3560
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3561
3562
  out_overflow:
  	print_overflow_msg(__func__, xdr);
683b57b43   Trond Myklebust   NFSv4: Implement ...
3563
3564
3565
3566
  out_eio:
  	status = -EIO;
  	goto out;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3567
3568
  static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3569
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3570
3571
3572
3573
3574
3575
  	int status = 0;
  
  	*res = 0;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3576
3577
3578
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3579
  		xdr_decode_hyper(p, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3580
3581
  		bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3582
3583
  	dprintk("%s: maxfilesize=%Lu
  ", __func__, (unsigned long long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3584
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3585
3586
3587
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3588
3589
3590
3591
  }
  
  static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3592
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3593
3594
3595
3596
3597
3598
  	int status = 0;
  
  	*maxlink = 1;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3599
3600
3601
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3602
  		*maxlink = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3603
3604
  		bitmap[0] &= ~FATTR4_WORD0_MAXLINK;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3605
3606
  	dprintk("%s: maxlink=%u
  ", __func__, *maxlink);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3607
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3608
3609
3610
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3611
3612
3613
3614
  }
  
  static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3615
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3616
3617
3618
3619
3620
3621
  	int status = 0;
  
  	*maxname = 1024;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3622
3623
3624
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3625
  		*maxname = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3626
3627
  		bitmap[0] &= ~FATTR4_WORD0_MAXNAME;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3628
3629
  	dprintk("%s: maxname=%u
  ", __func__, *maxname);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3630
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3631
3632
3633
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3634
3635
3636
3637
  }
  
  static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3638
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3639
3640
3641
3642
3643
3644
3645
  	int status = 0;
  
  	*res = 1024;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXREAD - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) {
  		uint64_t maxread;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3646
3647
3648
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3649
  		xdr_decode_hyper(p, &maxread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3650
3651
3652
3653
3654
  		if (maxread > 0x7FFFFFFF)
  			maxread = 0x7FFFFFFF;
  		*res = (uint32_t)maxread;
  		bitmap[0] &= ~FATTR4_WORD0_MAXREAD;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3655
3656
  	dprintk("%s: maxread=%lu
  ", __func__, (unsigned long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3657
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3658
3659
3660
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3661
3662
3663
3664
  }
  
  static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3665
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3666
3667
3668
3669
3670
3671
3672
  	int status = 0;
  
  	*res = 1024;
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXWRITE - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) {
  		uint64_t maxwrite;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3673
3674
3675
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3676
  		xdr_decode_hyper(p, &maxwrite);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3677
3678
3679
3680
3681
  		if (maxwrite > 0x7FFFFFFF)
  			maxwrite = 0x7FFFFFFF;
  		*res = (uint32_t)maxwrite;
  		bitmap[0] &= ~FATTR4_WORD0_MAXWRITE;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3682
3683
  	dprintk("%s: maxwrite=%lu
  ", __func__, (unsigned long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3684
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3685
3686
3687
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3688
  }
bca794785   Trond Myklebust   NFS: Fix the type...
3689
  static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3690
  {
bca794785   Trond Myklebust   NFS: Fix the type...
3691
  	uint32_t tmp;
8687b63af   Al Viro   [PATCH] xdr annot...
3692
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3693
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3694
3695
3696
3697
3698
  
  	*mode = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_MODE)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3699
3700
3701
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3702
  		tmp = be32_to_cpup(p);
bca794785   Trond Myklebust   NFS: Fix the type...
3703
  		*mode = tmp & ~S_IFMT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3704
  		bitmap[1] &= ~FATTR4_WORD1_MODE;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3705
  		ret = NFS_ATTR_FATTR_MODE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3706
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3707
3708
  	dprintk("%s: file mode=0%o
  ", __func__, (unsigned int)*mode);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3709
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3710
3711
3712
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3713
3714
3715
3716
  }
  
  static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3717
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3718
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3719
3720
3721
3722
3723
  
  	*nlink = 1;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3724
3725
3726
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3727
  		*nlink = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3728
  		bitmap[1] &= ~FATTR4_WORD1_NUMLINKS;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3729
  		ret = NFS_ATTR_FATTR_NLINK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3730
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3731
3732
  	dprintk("%s: nlink=%u
  ", __func__, (unsigned int)*nlink);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3733
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3734
3735
3736
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3737
  }
80e52aced   Trond Myklebust   NFSv4: Don't do i...
3738
  static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap,
6926afd19   Trond Myklebust   NFSv4: Save the o...
3739
3740
  		const struct nfs_server *server, uint32_t *uid,
  		struct nfs4_string *owner_name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3741
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3742
3743
  	uint32_t len;
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3744
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3745
3746
3747
3748
3749
  
  	*uid = -2;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3750
3751
3752
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3753
  		len = be32_to_cpup(p);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3754
3755
3756
  		p = xdr_inline_decode(xdr, len);
  		if (unlikely(!p))
  			goto out_overflow;
6926afd19   Trond Myklebust   NFSv4: Save the o...
3757
3758
3759
3760
3761
3762
  		if (owner_name != NULL) {
  			owner_name->data = kmemdup(p, len, GFP_NOWAIT);
  			if (owner_name->data != NULL) {
  				owner_name->len = len;
  				ret = NFS_ATTR_FATTR_OWNER_NAME;
  			}
80e52aced   Trond Myklebust   NFSv4: Don't do i...
3763
  		} else if (len < XDR_MAX_NETOBJ) {
e4fd72a17   Trond Myklebust   NFSv4: cleanup id...
3764
  			if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0)
409924e4c   Trond Myklebust   NFSv4: Make decod...
3765
3766
  				ret = NFS_ATTR_FATTR_OWNER;
  			else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3767
3768
  				dprintk("%s: nfs_map_name_to_uid failed!
  ",
3110ff804   Harvey Harrison   nfs: replace rema...
3769
  						__func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3770
  		} else
fe82a183c   Chuck Lever   NFS: Convert prin...
3771
3772
  			dprintk("%s: name too long (%u)!
  ",
3110ff804   Harvey Harrison   nfs: replace rema...
3773
  					__func__, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3774
3775
  		bitmap[1] &= ~FATTR4_WORD1_OWNER;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3776
3777
  	dprintk("%s: uid=%d
  ", __func__, (int)*uid);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3778
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3779
3780
3781
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3782
  }
80e52aced   Trond Myklebust   NFSv4: Don't do i...
3783
  static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap,
6926afd19   Trond Myklebust   NFSv4: Save the o...
3784
3785
  		const struct nfs_server *server, uint32_t *gid,
  		struct nfs4_string *group_name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3786
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3787
3788
  	uint32_t len;
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3789
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3790
3791
3792
3793
3794
  
  	*gid = -2;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3795
3796
3797
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3798
  		len = be32_to_cpup(p);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3799
3800
3801
  		p = xdr_inline_decode(xdr, len);
  		if (unlikely(!p))
  			goto out_overflow;
6926afd19   Trond Myklebust   NFSv4: Save the o...
3802
3803
3804
3805
3806
3807
  		if (group_name != NULL) {
  			group_name->data = kmemdup(p, len, GFP_NOWAIT);
  			if (group_name->data != NULL) {
  				group_name->len = len;
  				ret = NFS_ATTR_FATTR_GROUP_NAME;
  			}
80e52aced   Trond Myklebust   NFSv4: Don't do i...
3808
  		} else if (len < XDR_MAX_NETOBJ) {
e4fd72a17   Trond Myklebust   NFSv4: cleanup id...
3809
  			if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0)
409924e4c   Trond Myklebust   NFSv4: Make decod...
3810
3811
  				ret = NFS_ATTR_FATTR_GROUP;
  			else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3812
3813
  				dprintk("%s: nfs_map_group_to_gid failed!
  ",
3110ff804   Harvey Harrison   nfs: replace rema...
3814
  						__func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3815
  		} else
fe82a183c   Chuck Lever   NFS: Convert prin...
3816
3817
  			dprintk("%s: name too long (%u)!
  ",
3110ff804   Harvey Harrison   nfs: replace rema...
3818
  					__func__, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3819
3820
  		bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3821
3822
  	dprintk("%s: gid=%d
  ", __func__, (int)*gid);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3823
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3824
3825
3826
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3827
3828
3829
3830
  }
  
  static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3831
3832
  	uint32_t major = 0, minor = 0;
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3833
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3834
3835
3836
3837
3838
3839
  
  	*rdev = MKDEV(0,0);
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) {
  		dev_t tmp;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3840
3841
3842
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
3843
  		major = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3844
  		minor = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3845
3846
3847
3848
  		tmp = MKDEV(major, minor);
  		if (MAJOR(tmp) == major && MINOR(tmp) == minor)
  			*rdev = tmp;
  		bitmap[1] &= ~ FATTR4_WORD1_RAWDEV;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3849
  		ret = NFS_ATTR_FATTR_RDEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3850
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3851
3852
  	dprintk("%s: rdev=(0x%x:0x%x)
  ", __func__, major, minor);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3853
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3854
3855
3856
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3857
3858
3859
3860
  }
  
  static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3861
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3862
3863
3864
3865
3866
3867
  	int status = 0;
  
  	*res = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3868
3869
3870
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3871
  		xdr_decode_hyper(p, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3872
3873
  		bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3874
3875
  	dprintk("%s: space avail=%Lu
  ", __func__, (unsigned long long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3876
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3877
3878
3879
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3880
3881
3882
3883
  }
  
  static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3884
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3885
3886
3887
3888
3889
3890
  	int status = 0;
  
  	*res = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3891
3892
3893
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3894
  		xdr_decode_hyper(p, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3895
3896
  		bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3897
3898
  	dprintk("%s: space free=%Lu
  ", __func__, (unsigned long long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3899
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3900
3901
3902
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3903
3904
3905
3906
  }
  
  static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3907
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3908
3909
3910
3911
3912
3913
  	int status = 0;
  
  	*res = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3914
3915
3916
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3917
  		xdr_decode_hyper(p, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3918
3919
  		bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3920
3921
  	dprintk("%s: space total=%Lu
  ", __func__, (unsigned long long)*res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3922
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3923
3924
3925
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3926
3927
3928
3929
  }
  
  static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3930
  	__be32 *p;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3931
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3932
3933
3934
3935
3936
  
  	*used = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3937
3938
3939
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3940
  		xdr_decode_hyper(p, used);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3941
  		bitmap[1] &= ~FATTR4_WORD1_SPACE_USED;
409924e4c   Trond Myklebust   NFSv4: Make decod...
3942
  		ret = NFS_ATTR_FATTR_SPACE_USED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3943
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3944
3945
  	dprintk("%s: space used=%Lu
  ", __func__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3946
  			(unsigned long long)*used);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3947
  	return ret;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3948
3949
3950
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3951
3952
3953
3954
  }
  
  static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
3955
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3956
3957
  	uint64_t sec;
  	uint32_t nsec;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3958
3959
3960
  	p = xdr_inline_decode(xdr, 12);
  	if (unlikely(!p))
  		goto out_overflow;
3ceb4dbb9   Benny Halevy   nfs: nfs4xdr: get...
3961
  	p = xdr_decode_hyper(p, &sec);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
3962
  	nsec = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3963
3964
3965
  	time->tv_sec = (time_t)sec;
  	time->tv_nsec = (long)nsec;
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
3966
3967
3968
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
  }
  
  static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
  {
  	int status = 0;
  
  	time->tv_sec = 0;
  	time->tv_nsec = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_ACCESS - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_TIME_ACCESS)) {
  		status = decode_attr_time(xdr, time);
409924e4c   Trond Myklebust   NFSv4: Make decod...
3981
3982
  		if (status == 0)
  			status = NFS_ATTR_FATTR_ATIME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3983
3984
  		bitmap[1] &= ~FATTR4_WORD1_TIME_ACCESS;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
3985
3986
  	dprintk("%s: atime=%ld
  ", __func__, (long)time->tv_sec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
  	return status;
  }
  
  static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
  {
  	int status = 0;
  
  	time->tv_sec = 0;
  	time->tv_nsec = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_METADATA - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) {
  		status = decode_attr_time(xdr, time);
409924e4c   Trond Myklebust   NFSv4: Make decod...
4000
4001
  		if (status == 0)
  			status = NFS_ATTR_FATTR_CTIME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4002
4003
  		bitmap[1] &= ~FATTR4_WORD1_TIME_METADATA;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
4004
4005
  	dprintk("%s: ctime=%ld
  ", __func__, (long)time->tv_sec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4006
4007
  	return status;
  }
55b6e7742   Ricardo Labiaga   Ask for time_delt...
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
  static int decode_attr_time_delta(struct xdr_stream *xdr, uint32_t *bitmap,
  				  struct timespec *time)
  {
  	int status = 0;
  
  	time->tv_sec = 0;
  	time->tv_nsec = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_DELTA - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_TIME_DELTA)) {
  		status = decode_attr_time(xdr, time);
  		bitmap[1] &= ~FATTR4_WORD1_TIME_DELTA;
  	}
  	dprintk("%s: time_delta=%ld %ld
  ", __func__, (long)time->tv_sec,
  		(long)time->tv_nsec);
  	return status;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
  static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
  {
  	int status = 0;
  
  	time->tv_sec = 0;
  	time->tv_nsec = 0;
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_MODIFY - 1U)))
  		return -EIO;
  	if (likely(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) {
  		status = decode_attr_time(xdr, time);
409924e4c   Trond Myklebust   NFSv4: Make decod...
4036
4037
  		if (status == 0)
  			status = NFS_ATTR_FATTR_MTIME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4038
4039
  		bitmap[1] &= ~FATTR4_WORD1_TIME_MODIFY;
  	}
3110ff804   Harvey Harrison   nfs: replace rema...
4040
4041
  	dprintk("%s: mtime=%ld
  ", __func__, (long)time->tv_sec);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4042
4043
  	return status;
  }
8687b63af   Al Viro   [PATCH] xdr annot...
4044
  static int verify_attr_len(struct xdr_stream *xdr, __be32 *savep, uint32_t attrlen)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4045
4046
4047
4048
4049
  {
  	unsigned int attrwords = XDR_QUADLEN(attrlen);
  	unsigned int nwords = xdr->p - savep;
  
  	if (unlikely(attrwords != nwords)) {
fe82a183c   Chuck Lever   NFS: Convert prin...
4050
4051
4052
  		dprintk("%s: server returned incorrect attribute length: "
  			"%u %c %u
  ",
3110ff804   Harvey Harrison   nfs: replace rema...
4053
  				__func__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
  				attrwords << 2,
  				(attrwords < nwords) ? '<' : '>',
  				nwords << 2);
  		return -EIO;
  	}
  	return 0;
  }
  
  static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4064
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4065

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4066
4067
4068
  	p = xdr_inline_decode(xdr, 20);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
4069
  	cinfo->atomic = be32_to_cpup(p++);
3ceb4dbb9   Benny Halevy   nfs: nfs4xdr: get...
4070
  	p = xdr_decode_hyper(p, &cinfo->before);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4071
  	xdr_decode_hyper(p, &cinfo->after);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4072
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4073
4074
4075
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4076
4077
4078
4079
  }
  
  static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4080
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4081
4082
4083
4084
4085
4086
  	uint32_t supp, acc;
  	int status;
  
  	status = decode_op_hdr(xdr, OP_ACCESS);
  	if (status)
  		return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4087
4088
4089
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
4090
  	supp = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4091
  	acc = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4092
4093
4094
  	access->supported = supp;
  	access->access = acc;
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4095
4096
4097
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4098
  }
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4099
  static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4100
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4101
  	__be32 *p;
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
  
  	p = xdr_inline_decode(xdr, len);
  	if (likely(p)) {
  		memcpy(buf, p, len);
  		return 0;
  	}
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
  
  static int decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
  {
  	return decode_opaque_fixed(xdr, stateid->data, NFS4_STATEID_SIZE);
  }
  
  static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4119
4120
4121
  	int status;
  
  	status = decode_op_hdr(xdr, OP_CLOSE);
c1d519312   Trond Myklebust   NFSv4: Only incre...
4122
4123
  	if (status != -EIO)
  		nfs_increment_open_seqid(status, res->seqid);
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4124
4125
4126
  	if (!status)
  		status = decode_stateid(xdr, &res->stateid);
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4127
  }
db942bbd0   Benny Halevy   nfs: nfs4xdr: int...
4128
4129
4130
  static int decode_verifier(struct xdr_stream *xdr, void *verifier)
  {
  	return decode_opaque_fixed(xdr, verifier, 8);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4131
4132
4133
4134
  }
  
  static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4135
4136
4137
  	int status;
  
  	status = decode_op_hdr(xdr, OP_COMMIT);
db942bbd0   Benny Halevy   nfs: nfs4xdr: int...
4138
4139
4140
  	if (!status)
  		status = decode_verifier(xdr, res->verf->verifier);
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4141
4142
4143
4144
  }
  
  static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4145
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4146
4147
4148
4149
4150
4151
4152
4153
  	uint32_t bmlen;
  	int status;
  
  	status = decode_op_hdr(xdr, OP_CREATE);
  	if (status)
  		return status;
  	if ((status = decode_change_info(xdr, cinfo)))
  		return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4154
4155
4156
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4157
  	bmlen = be32_to_cpup(p);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4158
4159
4160
4161
4162
4163
  	p = xdr_inline_decode(xdr, bmlen << 2);
  	if (likely(p))
  		return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4164
4165
4166
4167
  }
  
  static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4168
  	__be32 *savep;
dae100c2b   Fred Isaman   pnfs: ask for lay...
4169
  	uint32_t attrlen, bitmap[3] = {0};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
  	int status;
  
  	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_supported(xdr, bitmap, res->attr_bitmask)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_link_support(xdr, bitmap, &res->has_links)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_symlink_support(xdr, bitmap, &res->has_symlinks)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0)
  		goto xdr_error;
  	status = verify_attr_len(xdr, savep, attrlen);
  xdr_error:
3110ff804   Harvey Harrison   nfs: replace rema...
4188
4189
  	dprintk("%s: xdr returned %d!
  ", __func__, -status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4190
4191
  	return status;
  }
6c0195a46   Andy Adamson   NFS: remove white...
4192

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4193
4194
  static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4195
  	__be32 *savep;
dae100c2b   Fred Isaman   pnfs: ask for lay...
4196
  	uint32_t attrlen, bitmap[3] = {0};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4197
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
4198

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
  	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
  		goto xdr_error;
  
  	if ((status = decode_attr_files_avail(xdr, bitmap, &fsstat->afiles)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_files_free(xdr, bitmap, &fsstat->ffiles)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_space_total(xdr, bitmap, &fsstat->tbytes)) != 0)
  		goto xdr_error;
  
  	status = verify_attr_len(xdr, savep, attrlen);
  xdr_error:
3110ff804   Harvey Harrison   nfs: replace rema...
4221
4222
  	dprintk("%s: xdr returned %d!
  ", __func__, -status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4223
4224
4225
4226
4227
  	return status;
  }
  
  static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4228
  	__be32 *savep;
dae100c2b   Fred Isaman   pnfs: ask for lay...
4229
  	uint32_t attrlen, bitmap[3] = {0};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4230
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
4231

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
  	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
  		goto xdr_error;
  
  	if ((status = decode_attr_maxlink(xdr, bitmap, &pathconf->max_link)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_maxname(xdr, bitmap, &pathconf->max_namelen)) != 0)
  		goto xdr_error;
  
  	status = verify_attr_len(xdr, savep, attrlen);
  xdr_error:
3110ff804   Harvey Harrison   nfs: replace rema...
4246
4247
  	dprintk("%s: xdr returned %d!
  ", __func__, -status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4248
4249
  	return status;
  }
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4250
4251
  static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap,
  		struct nfs_fattr *fattr, struct nfs_fh *fh,
6926afd19   Trond Myklebust   NFSv4: Save the o...
4252
  		const struct nfs_server *server)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4253
  {
bca794785   Trond Myklebust   NFS: Fix the type...
4254
4255
  	int status;
  	umode_t fmode = 0;
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4256
  	uint32_t type;
ee7b75fc4   Trond Myklebust   NFSv4: Fix a read...
4257
  	int32_t err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4258

f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4259
4260
  	status = decode_attr_type(xdr, bitmap, &type);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4261
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4262
4263
4264
4265
4266
  	fattr->mode = 0;
  	if (status != 0) {
  		fattr->mode |= nfs_type2fmt[type];
  		fattr->valid |= status;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4267

f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4268
4269
  	status = decode_attr_change(xdr, bitmap, &fattr->change_attr);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4270
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4271
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4272
4273
4274
  
  	status = decode_attr_size(xdr, bitmap, &fattr->size);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4275
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4276
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4277
4278
4279
  
  	status = decode_attr_fsid(xdr, bitmap, &fattr->fsid);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4280
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4281
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4282

ee7b75fc4   Trond Myklebust   NFSv4: Fix a read...
4283
4284
  	err = 0;
  	status = decode_attr_error(xdr, bitmap, &err);
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4285
4286
  	if (status < 0)
  		goto xdr_error;
ee7b75fc4   Trond Myklebust   NFSv4: Fix a read...
4287
4288
  	if (err == -NFS4ERR_WRONGSEC)
  		nfs_fixup_secinfo_attributes(fattr, fh);
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4289
4290
4291
4292
  
  	status = decode_attr_filehandle(xdr, bitmap, fh);
  	if (status < 0)
  		goto xdr_error;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4293
4294
  	status = decode_attr_fileid(xdr, bitmap, &fattr->fileid);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4295
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4296
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4297
4298
  
  	status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
7aaa0b3bd   Manoj Naik   NFSv4: convert fs...
4299
  						struct nfs4_fs_locations,
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4300
4301
  						fattr));
  	if (status < 0)
683b57b43   Trond Myklebust   NFSv4: Implement ...
4302
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4303
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4304
4305
4306
  
  	status = decode_attr_mode(xdr, bitmap, &fmode);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4307
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4308
4309
4310
4311
  	if (status != 0) {
  		fattr->mode |= fmode;
  		fattr->valid |= status;
  	}
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4312
4313
4314
  
  	status = decode_attr_nlink(xdr, bitmap, &fattr->nlink);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4315
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4316
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4317

6926afd19   Trond Myklebust   NFSv4: Save the o...
4318
  	status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, fattr->owner_name);
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4319
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4320
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4321
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4322

6926afd19   Trond Myklebust   NFSv4: Save the o...
4323
  	status = decode_attr_group(xdr, bitmap, server, &fattr->gid, fattr->group_name);
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4324
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4325
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4326
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4327
4328
4329
  
  	status = decode_attr_rdev(xdr, bitmap, &fattr->rdev);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4330
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4331
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4332
4333
4334
  
  	status = decode_attr_space_used(xdr, bitmap, &fattr->du.nfs3.used);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4335
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4336
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4337
4338
4339
  
  	status = decode_attr_time_access(xdr, bitmap, &fattr->atime);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4340
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4341
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4342
4343
4344
  
  	status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4345
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4346
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4347
4348
4349
  
  	status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime);
  	if (status < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4350
  		goto xdr_error;
409924e4c   Trond Myklebust   NFSv4: Make decod...
4351
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4352

28331a46d   Trond Myklebust   NFSv4: Ensure we ...
4353
  	status = decode_attr_mounted_on_fileid(xdr, bitmap, &fattr->mounted_on_fileid);
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4354
  	if (status < 0)
99baf625d   Manoj Naik   NFSv4: Decode mou...
4355
  		goto xdr_error;
28331a46d   Trond Myklebust   NFSv4: Ensure we ...
4356
  	fattr->valid |= status;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4357

ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4358
4359
4360
4361
4362
4363
4364
  xdr_error:
  	dprintk("%s: xdr returned %d
  ", __func__, -status);
  	return status;
  }
  
  static int decode_getfattr_generic(struct xdr_stream *xdr, struct nfs_fattr *fattr,
6926afd19   Trond Myklebust   NFSv4: Save the o...
4365
  		struct nfs_fh *fh, const struct nfs_server *server)
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4366
4367
4368
  {
  	__be32 *savep;
  	uint32_t attrlen,
dae100c2b   Fred Isaman   pnfs: ask for lay...
4369
  		 bitmap[3] = {0};
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
  	int status;
  
  	status = decode_op_hdr(xdr, OP_GETATTR);
  	if (status < 0)
  		goto xdr_error;
  
  	status = decode_attr_bitmap(xdr, bitmap);
  	if (status < 0)
  		goto xdr_error;
  
  	status = decode_attr_length(xdr, &attrlen, &savep);
  	if (status < 0)
  		goto xdr_error;
6926afd19   Trond Myklebust   NFSv4: Save the o...
4383
  	status = decode_getfattr_attrs(xdr, bitmap, fattr, fh, server);
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4384
4385
  	if (status < 0)
  		goto xdr_error;
f26c7a788   Trond Myklebust   NFSv4: Clean up d...
4386
  	status = verify_attr_len(xdr, savep, attrlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4387
  xdr_error:
3110ff804   Harvey Harrison   nfs: replace rema...
4388
4389
  	dprintk("%s: xdr returned %d
  ", __func__, -status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4390
4391
  	return status;
  }
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4392
  static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr,
6926afd19   Trond Myklebust   NFSv4: Save the o...
4393
  		const struct nfs_server *server)
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4394
  {
6926afd19   Trond Myklebust   NFSv4: Save the o...
4395
  	return decode_getfattr_generic(xdr, fattr, NULL, server);
ae42c70a6   Bryan Schumaker   NFS: introduce ge...
4396
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4397

504913fbc   Andy Adamson   NFS: ask for layo...
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
  /*
   * Decode potentially multiple layout types. Currently we only support
   * one layout driver per file system.
   */
  static int decode_first_pnfs_layout_type(struct xdr_stream *xdr,
  					 uint32_t *layouttype)
  {
  	uint32_t *p;
  	int num;
  
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	num = be32_to_cpup(p);
  
  	/* pNFS is not supported by the underlying file system */
  	if (num == 0) {
  		*layouttype = 0;
  		return 0;
  	}
  	if (num > 1)
  		printk(KERN_INFO "%s: Warning: Multiple pNFS layout drivers "
  			"per filesystem not supported
  ", __func__);
  
  	/* Decode and set first layout type, move xdr->p past unused types */
  	p = xdr_inline_decode(xdr, num * 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	*layouttype = be32_to_cpup(p);
  	return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
  
  /*
   * The type of file system exported.
   * Note we must ensure that layouttype is set in any non-error case.
   */
  static int decode_attr_pnfstype(struct xdr_stream *xdr, uint32_t *bitmap,
  				uint32_t *layouttype)
  {
  	int status = 0;
  
  	dprintk("%s: bitmap is %x
  ", __func__, bitmap[1]);
  	if (unlikely(bitmap[1] & (FATTR4_WORD1_FS_LAYOUT_TYPES - 1U)))
  		return -EIO;
  	if (bitmap[1] & FATTR4_WORD1_FS_LAYOUT_TYPES) {
  		status = decode_first_pnfs_layout_type(xdr, layouttype);
  		bitmap[1] &= ~FATTR4_WORD1_FS_LAYOUT_TYPES;
  	} else
  		*layouttype = 0;
  	return status;
  }
dae100c2b   Fred Isaman   pnfs: ask for lay...
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
  /*
   * The prefered block size for layout directed io
   */
  static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap,
  				      uint32_t *res)
  {
  	__be32 *p;
  
  	dprintk("%s: bitmap is %x
  ", __func__, bitmap[2]);
  	*res = 0;
  	if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) {
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p)) {
  			print_overflow_msg(__func__, xdr);
  			return -EIO;
  		}
  		*res = be32_to_cpup(p);
  		bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE;
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4476
4477
  static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4478
  	__be32 *savep;
dae100c2b   Fred Isaman   pnfs: ask for lay...
4479
  	uint32_t attrlen, bitmap[3];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
  	int status;
  
  	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
  		goto xdr_error;
  
  	fsinfo->rtmult = fsinfo->wtmult = 512;	/* ??? */
  
  	if ((status = decode_attr_lease_time(xdr, bitmap, &fsinfo->lease_time)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_maxfilesize(xdr, bitmap, &fsinfo->maxfilesize)) != 0)
  		goto xdr_error;
  	if ((status = decode_attr_maxread(xdr, bitmap, &fsinfo->rtmax)) != 0)
  		goto xdr_error;
  	fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax;
  	if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0)
  		goto xdr_error;
  	fsinfo->wtpref = fsinfo->wtmax;
55b6e7742   Ricardo Labiaga   Ask for time_delt...
4501
4502
4503
  	status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta);
  	if (status != 0)
  		goto xdr_error;
504913fbc   Andy Adamson   NFS: ask for layo...
4504
4505
4506
  	status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype);
  	if (status != 0)
  		goto xdr_error;
dae100c2b   Fred Isaman   pnfs: ask for lay...
4507
4508
4509
  	status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize);
  	if (status)
  		goto xdr_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4510
4511
4512
  
  	status = verify_attr_len(xdr, savep, attrlen);
  xdr_error:
3110ff804   Harvey Harrison   nfs: replace rema...
4513
4514
  	dprintk("%s: xdr returned %d!
  ", __func__, -status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4515
4516
4517
4518
4519
  	return status;
  }
  
  static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4520
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4521
4522
  	uint32_t len;
  	int status;
9936781d0   Trond Myklebust   NFSv4: Try to rec...
4523
4524
  	/* Zero handle first to allow comparisons */
  	memset(fh, 0, sizeof(*fh));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4525
4526
4527
  	status = decode_op_hdr(xdr, OP_GETFH);
  	if (status)
  		return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4528

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4529
4530
4531
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4532
  	len = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4533
4534
4535
  	if (len > NFS4_FHSIZE)
  		return -EIO;
  	fh->size = len;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4536
4537
4538
  	p = xdr_inline_decode(xdr, len);
  	if (unlikely(!p))
  		goto out_overflow;
99398d065   Benny Halevy   nfs: nfs4xdr: get...
4539
  	memcpy(fh->data, p, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4540
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4541
4542
4543
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4544
4545
4546
4547
4548
  }
  
  static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
  {
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
4549

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4550
4551
4552
4553
4554
4555
4556
4557
4558
  	status = decode_op_hdr(xdr, OP_LINK);
  	if (status)
  		return status;
  	return decode_change_info(xdr, cinfo);
  }
  
  /*
   * We create the owner, so we know a proper owner.id length is 4.
   */
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4559
  static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4560
  {
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4561
  	uint64_t offset, length, clientid;
8687b63af   Al Viro   [PATCH] xdr annot...
4562
  	__be32 *p;
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4563
  	uint32_t namelen, type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4564

babddc72a   Bryan Schumaker   NFS: decode_diren...
4565
  	p = xdr_inline_decode(xdr, 32); /* read 32 bytes */
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4566
4567
  	if (unlikely(!p))
  		goto out_overflow;
babddc72a   Bryan Schumaker   NFS: decode_diren...
4568
  	p = xdr_decode_hyper(p, &offset); /* read 2 8-byte long words */
3ceb4dbb9   Benny Halevy   nfs: nfs4xdr: get...
4569
  	p = xdr_decode_hyper(p, &length);
babddc72a   Bryan Schumaker   NFS: decode_diren...
4570
4571
  	type = be32_to_cpup(p++); /* 4 byte read */
  	if (fl != NULL) { /* manipulate file lock */
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4572
4573
4574
4575
4576
4577
4578
4579
4580
  		fl->fl_start = (loff_t)offset;
  		fl->fl_end = fl->fl_start + (loff_t)length - 1;
  		if (length == ~(uint64_t)0)
  			fl->fl_end = OFFSET_MAX;
  		fl->fl_type = F_WRLCK;
  		if (type & 1)
  			fl->fl_type = F_RDLCK;
  		fl->fl_pid = 0;
  	}
babddc72a   Bryan Schumaker   NFS: decode_diren...
4581
4582
4583
  	p = xdr_decode_hyper(p, &clientid); /* read 8 bytes */
  	namelen = be32_to_cpup(p); /* read 4 bytes */  /* have read all 32 bytes now */
  	p = xdr_inline_decode(xdr, namelen); /* variable size field */
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4584
4585
4586
4587
4588
  	if (likely(p))
  		return -NFS4ERR_DENIED;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4589
  }
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4590
  static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4591
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4592
4593
4594
  	int status;
  
  	status = decode_op_hdr(xdr, OP_LOCK);
c1d519312   Trond Myklebust   NFSv4: Only incre...
4595
4596
  	if (status == -EIO)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4597
  	if (status == 0) {
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4598
4599
4600
  		status = decode_stateid(xdr, &res->stateid);
  		if (unlikely(status))
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4601
  	} else if (status == -NFS4ERR_DENIED)
c1d519312   Trond Myklebust   NFSv4: Only incre...
4602
4603
4604
4605
4606
  		status = decode_lock_denied(xdr, NULL);
  	if (res->open_seqid != NULL)
  		nfs_increment_open_seqid(status, res->open_seqid);
  	nfs_increment_lock_seqid(status, res->lock_seqid);
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4607
4608
  	return status;
  }
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4609
  static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4610
4611
4612
4613
  {
  	int status;
  	status = decode_op_hdr(xdr, OP_LOCKT);
  	if (status == -NFS4ERR_DENIED)
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4614
  		return decode_lock_denied(xdr, res->denied);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4615
4616
  	return status;
  }
911d1aaf2   Trond Myklebust   NFSv4: locking XD...
4617
  static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4618
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4619
4620
4621
  	int status;
  
  	status = decode_op_hdr(xdr, OP_LOCKU);
c1d519312   Trond Myklebust   NFSv4: Only incre...
4622
4623
  	if (status != -EIO)
  		nfs_increment_lock_seqid(status, res->seqid);
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4624
4625
  	if (status == 0)
  		status = decode_stateid(xdr, &res->stateid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4626
4627
  	return status;
  }
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
4628
4629
4630
4631
  static int decode_release_lockowner(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_RELEASE_LOCKOWNER);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4632
4633
4634
4635
4636
4637
4638
4639
  static int decode_lookup(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_LOOKUP);
  }
  
  /* This is too sick! */
  static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4640
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4641
  	uint32_t limit_type, nblocks, blocksize;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4642
4643
4644
  	p = xdr_inline_decode(xdr, 12);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
4645
  	limit_type = be32_to_cpup(p++);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4646
  	switch (limit_type) {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4647
  	case 1:
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4648
  		xdr_decode_hyper(p, maxsize);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4649
4650
  		break;
  	case 2:
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
4651
  		nblocks = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4652
  		blocksize = be32_to_cpup(p);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4653
  		*maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4654
4655
  	}
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4656
4657
4658
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4659
4660
4661
4662
  }
  
  static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4663
4664
  	__be32 *p;
  	uint32_t delegation_type;
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4665
  	int status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4666

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4667
4668
4669
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4670
  	delegation_type = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4671
4672
4673
4674
  	if (delegation_type == NFS4_OPEN_DELEGATE_NONE) {
  		res->delegation_type = 0;
  		return 0;
  	}
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4675
4676
4677
  	status = decode_stateid(xdr, &res->delegation);
  	if (unlikely(status))
  		return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4678
4679
4680
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4681
  	res->do_recall = be32_to_cpup(p);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4682

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4683
  	switch (delegation_type) {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4684
4685
4686
4687
4688
4689
  	case NFS4_OPEN_DELEGATE_READ:
  		res->delegation_type = FMODE_READ;
  		break;
  	case NFS4_OPEN_DELEGATE_WRITE:
  		res->delegation_type = FMODE_WRITE|FMODE_READ;
  		if (decode_space_limit(xdr, &res->maxsize) < 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4690
4691
  				return -EIO;
  	}
7539bbab8   David Howells   NFS: Rename nfs_s...
4692
  	return decode_ace(xdr, NULL, res->server->nfs_client);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4693
4694
4695
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4696
4697
4698
4699
  }
  
  static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4700
  	__be32 *p;
aa53ed541   Jeff Layton   NFS4: on a O_EXCL...
4701
  	uint32_t savewords, bmlen, i;
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4702
  	int status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4703

05d564fe0   Andy Adamson   NFS: fix tabs in ...
4704
  	status = decode_op_hdr(xdr, OP_OPEN);
c1d519312   Trond Myklebust   NFSv4: Only incre...
4705
4706
  	if (status != -EIO)
  		nfs_increment_open_seqid(status, res->seqid);
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4707
4708
4709
  	if (!status)
  		status = decode_stateid(xdr, &res->stateid);
  	if (unlikely(status))
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4710
  		return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4711

05d564fe0   Andy Adamson   NFS: fix tabs in ...
4712
  	decode_change_info(xdr, &res->cinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4713

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4714
4715
4716
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
4717
  	res->rflags = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4718
  	bmlen = be32_to_cpup(p);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4719
4720
  	if (bmlen > 10)
  		goto xdr_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4721

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4722
4723
4724
  	p = xdr_inline_decode(xdr, bmlen << 2);
  	if (unlikely(!p))
  		goto out_overflow;
aa53ed541   Jeff Layton   NFS4: on a O_EXCL...
4725
4726
  	savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE);
  	for (i = 0; i < savewords; ++i)
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
4727
  		res->attrset[i] = be32_to_cpup(p++);
aa53ed541   Jeff Layton   NFS4: on a O_EXCL...
4728
4729
  	for (; i < NFS4_BITMAP_SIZE; i++)
  		res->attrset[i] = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4730
4731
  	return decode_delegation(xdr, res);
  xdr_error:
3110ff804   Harvey Harrison   nfs: replace rema...
4732
4733
  	dprintk("%s: Bitmap too large! Length = %u
  ", __func__, bmlen);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4734
  	return -EIO;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4735
4736
4737
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4738
4739
4740
4741
  }
  
  static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4742
  	int status;
05d564fe0   Andy Adamson   NFS: fix tabs in ...
4743
  	status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
c1d519312   Trond Myklebust   NFSv4: Only incre...
4744
4745
  	if (status != -EIO)
  		nfs_increment_open_seqid(status, res->seqid);
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4746
4747
4748
  	if (!status)
  		status = decode_stateid(xdr, &res->stateid);
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4749
4750
4751
4752
  }
  
  static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4753
4754
4755
  	int status;
  
  	status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE);
c1d519312   Trond Myklebust   NFSv4: Only incre...
4756
4757
  	if (status != -EIO)
  		nfs_increment_open_seqid(status, res->seqid);
07d30434c   Benny Halevy   nfs: nfs4xdr: int...
4758
4759
4760
  	if (!status)
  		status = decode_stateid(xdr, &res->stateid);
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
  }
  
  static int decode_putfh(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_PUTFH);
  }
  
  static int decode_putrootfh(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_PUTROOTFH);
  }
  
  static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res)
  {
  	struct kvec *iov = req->rq_rcv_buf.head;
8687b63af   Al Viro   [PATCH] xdr annot...
4776
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4777
4778
4779
4780
4781
4782
  	uint32_t count, eof, recvd, hdrlen;
  	int status;
  
  	status = decode_op_hdr(xdr, OP_READ);
  	if (status)
  		return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4783
4784
4785
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
4786
  	eof = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4787
  	count = be32_to_cpup(p);
8111f3736   Chuck Lever   NFS: Fix hdrlen c...
4788
  	hdrlen = (u8 *) xdr->p - (u8 *) iov->iov_base;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4789
4790
  	recvd = req->rq_rcv_buf.len - hdrlen;
  	if (count > recvd) {
fe82a183c   Chuck Lever   NFS: Convert prin...
4791
  		dprintk("NFS: server cheating in read reply: "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4792
4793
4794
4795
4796
4797
4798
4799
4800
  				"count %u > recvd %u
  ", count, recvd);
  		count = recvd;
  		eof = 0;
  	}
  	xdr_read_pages(xdr, count);
  	res->eof = eof;
  	res->count = count;
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4801
4802
4803
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4804
4805
4806
4807
4808
  }
  
  static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir)
  {
  	struct xdr_buf	*rcvbuf = &req->rq_rcv_buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4809
  	struct kvec	*iov = rcvbuf->head;
bcecff77a   Chuck Lever   NFS: Use unsigned...
4810
4811
  	size_t		hdrlen;
  	u32		recvd, pglen = rcvbuf->page_len;
bcecff77a   Chuck Lever   NFS: Use unsigned...
4812
  	int		status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4813
4814
  
  	status = decode_op_hdr(xdr, OP_READDIR);
db942bbd0   Benny Halevy   nfs: nfs4xdr: int...
4815
4816
4817
  	if (!status)
  		status = decode_verifier(xdr, readdir->verifier.data);
  	if (unlikely(status))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4818
  		return status;
441092415   Fred Isaman   nfs: fix printout...
4819
4820
4821
  	dprintk("%s: verifier = %08x:%08x
  ",
  			__func__,
eadf4598e   Trond Myklebust   [PATCH] NFS: Add ...
4822
4823
  			((u32 *)readdir->verifier.data)[0],
  			((u32 *)readdir->verifier.data)[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4824

db942bbd0   Benny Halevy   nfs: nfs4xdr: int...
4825
  	hdrlen = (char *) xdr->p - (char *) iov->iov_base;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4826
4827
4828
4829
  	recvd = rcvbuf->len - hdrlen;
  	if (pglen > recvd)
  		pglen = recvd;
  	xdr_read_pages(xdr, pglen);
afa8ccc97   Bryan Schumaker   NFS: remove page ...
4830

ac3961282   Trond Myklebust   NFS: readdir shou...
4831
  	return pglen;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4832
4833
4834
4835
4836
4837
  }
  
  static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
  {
  	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  	struct kvec *iov = rcvbuf->head;
bcecff77a   Chuck Lever   NFS: Use unsigned...
4838
4839
  	size_t hdrlen;
  	u32 len, recvd;
8687b63af   Al Viro   [PATCH] xdr annot...
4840
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4841
4842
4843
4844
4845
4846
4847
  	int status;
  
  	status = decode_op_hdr(xdr, OP_READLINK);
  	if (status)
  		return status;
  
  	/* Convert length of symlink */
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4848
4849
4850
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4851
  	len = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4852
  	if (len >= rcvbuf->page_len || len <= 0) {
fe82a183c   Chuck Lever   NFS: Convert prin...
4853
4854
  		dprintk("nfs: server returned giant symlink!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4855
4856
4857
4858
4859
  		return -ENAMETOOLONG;
  	}
  	hdrlen = (char *) xdr->p - (char *) iov->iov_base;
  	recvd = req->rq_rcv_buf.len - hdrlen;
  	if (recvd < len) {
fe82a183c   Chuck Lever   NFS: Convert prin...
4860
  		dprintk("NFS: server cheating in readlink reply: "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
  				"count %u > recvd %u
  ", len, recvd);
  		return -EIO;
  	}
  	xdr_read_pages(xdr, len);
  	/*
  	 * The XDR encode routine has set things up so that
  	 * the link text will be copied directly into the
  	 * buffer.  We just have to do overflow-checking,
  	 * and and null-terminate the text (the VFS expects
  	 * null-termination).
  	 */
b4687da7f   Chuck Lever   SUNRPC: Refactor ...
4873
  	xdr_terminate_string(rcvbuf, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4874
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4875
4876
4877
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
  }
  
  static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
  {
  	int status;
  
  	status = decode_op_hdr(xdr, OP_REMOVE);
  	if (status)
  		goto out;
  	status = decode_change_info(xdr, cinfo);
  out:
  	return status;
  }
  
  static int decode_rename(struct xdr_stream *xdr, struct nfs4_change_info *old_cinfo,
  	      struct nfs4_change_info *new_cinfo)
  {
  	int status;
  
  	status = decode_op_hdr(xdr, OP_RENAME);
  	if (status)
  		goto out;
  	if ((status = decode_change_info(xdr, old_cinfo)))
  		goto out;
  	status = decode_change_info(xdr, new_cinfo);
  out:
  	return status;
  }
  
  static int decode_renew(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_RENEW);
  }
56ae19f38   Trond Myklebust   NFSv4: Add direct...
4911
4912
4913
4914
4915
  static int
  decode_restorefh(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_RESTOREFH);
  }
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4916
  static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
bf118a342   Andy Adamson   NFSv4: include bi...
4917
  			 struct nfs_getaclres *res)
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4918
  {
bf118a342   Andy Adamson   NFSv4: include bi...
4919
  	__be32 *savep, *bm_p;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4920
  	uint32_t attrlen,
dae100c2b   Fred Isaman   pnfs: ask for lay...
4921
  		 bitmap[3] = {0};
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4922
4923
  	struct kvec *iov = req->rq_rcv_buf.head;
  	int status;
bf118a342   Andy Adamson   NFSv4: include bi...
4924
  	res->acl_len = 0;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4925
4926
  	if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
  		goto out;
bf118a342   Andy Adamson   NFSv4: include bi...
4927
  	bm_p = xdr->p;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4928
4929
4930
4931
4932
4933
4934
4935
  	if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
  		goto out;
  	if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
  		goto out;
  
  	if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
  		return -EIO;
  	if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
bcecff77a   Chuck Lever   NFS: Use unsigned...
4936
4937
  		size_t hdrlen;
  		u32 recvd;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4938

bf118a342   Andy Adamson   NFSv4: include bi...
4939
4940
4941
4942
4943
4944
  		/* The bitmap (xdr len + bitmaps) and the attr xdr len words
  		 * are stored with the acl data to handle the problem of
  		 * variable length bitmaps.*/
  		xdr->p = bm_p;
  		res->acl_data_offset = be32_to_cpup(bm_p) + 2;
  		res->acl_data_offset <<= 2;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4945
4946
4947
  		/* We ignore &savep and don't do consistency checks on
  		 * the attr length.  Let userspace figure it out.... */
  		hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
bf118a342   Andy Adamson   NFSv4: include bi...
4948
  		attrlen += res->acl_data_offset;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4949
4950
  		recvd = req->rq_rcv_buf.len - hdrlen;
  		if (attrlen > recvd) {
bf118a342   Andy Adamson   NFSv4: include bi...
4951
4952
4953
4954
4955
4956
4957
  			if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
  				/* getxattr interface called with a NULL buf */
  				res->acl_len = attrlen;
  				goto out;
  			}
  			dprintk("NFS: acl reply: attrlen %u > recvd %u
  ",
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4958
4959
4960
  					attrlen, recvd);
  			return -EINVAL;
  		}
c04871e63   J. Bruce Fields   NFSv4: remove obv...
4961
  		xdr_read_pages(xdr, attrlen);
bf118a342   Andy Adamson   NFSv4: include bi...
4962
  		res->acl_len = attrlen;
8c233cf9c   J. Bruce Fields   NFSv4: handle no ...
4963
4964
  	} else
  		status = -EOPNOTSUPP;
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
4965
4966
4967
4968
  
  out:
  	return status;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4969
4970
4971
4972
4973
  static int
  decode_savefh(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_SAVEFH);
  }
9e9ecc03d   Benny Halevy   NFS: get rid of u...
4974
  static int decode_setattr(struct xdr_stream *xdr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4975
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4976
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4977
4978
  	uint32_t bmlen;
  	int status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4979
4980
4981
  	status = decode_op_hdr(xdr, OP_SETATTR);
  	if (status)
  		return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4982
4983
4984
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
4985
  	bmlen = be32_to_cpup(p);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4986
4987
4988
4989
4990
4991
  	p = xdr_inline_decode(xdr, bmlen << 2);
  	if (likely(p))
  		return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4992
  }
bb8b27e50   Trond Myklebust   NFSv4: Clean up t...
4993
  static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4994
  {
8687b63af   Al Viro   [PATCH] xdr annot...
4995
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4996
4997
  	uint32_t opnum;
  	int32_t nfserr;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
4998
4999
5000
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5001
  	opnum = be32_to_cpup(p++);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5002
  	if (opnum != OP_SETCLIENTID) {
fe82a183c   Chuck Lever   NFS: Convert prin...
5003
  		dprintk("nfs: decode_setclientid: Server returned operation"
6c0195a46   Andy Adamson   NFS: remove white...
5004
5005
  			" %d
  ", opnum);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5006
5007
  		return -EIO;
  	}
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
5008
  	nfserr = be32_to_cpup(p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5009
  	if (nfserr == NFS_OK) {
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5010
5011
5012
  		p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE);
  		if (unlikely(!p))
  			goto out_overflow;
bb8b27e50   Trond Myklebust   NFSv4: Clean up t...
5013
5014
  		p = xdr_decode_hyper(p, &res->clientid);
  		memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5015
5016
5017
5018
  	} else if (nfserr == NFSERR_CLID_INUSE) {
  		uint32_t len;
  
  		/* skip netid string */
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5019
5020
5021
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
5022
  		len = be32_to_cpup(p);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5023
5024
5025
  		p = xdr_inline_decode(xdr, len);
  		if (unlikely(!p))
  			goto out_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5026
5027
  
  		/* skip uaddr string */
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5028
5029
5030
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
5031
  		len = be32_to_cpup(p);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5032
5033
5034
  		p = xdr_inline_decode(xdr, len);
  		if (unlikely(!p))
  			goto out_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5035
5036
  		return -NFSERR_CLID_INUSE;
  	} else
856dff3d3   Benny Halevy   nfs: return negat...
5037
  		return nfs4_stat_to_errno(nfserr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5038
5039
  
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5040
5041
5042
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5043
5044
5045
5046
5047
5048
5049
5050
5051
  }
  
  static int decode_setclientid_confirm(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_SETCLIENTID_CONFIRM);
  }
  
  static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res)
  {
8687b63af   Al Viro   [PATCH] xdr annot...
5052
  	__be32 *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5053
5054
5055
5056
5057
  	int status;
  
  	status = decode_op_hdr(xdr, OP_WRITE);
  	if (status)
  		return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5058
5059
5060
  	p = xdr_inline_decode(xdr, 16);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5061
5062
  	res->count = be32_to_cpup(p++);
  	res->verf->committed = be32_to_cpup(p++);
99398d065   Benny Halevy   nfs: nfs4xdr: get...
5063
  	memcpy(res->verf->verifier, p, 8);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5064
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5065
5066
5067
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5068
5069
5070
5071
5072
5073
  }
  
  static int decode_delegreturn(struct xdr_stream *xdr)
  {
  	return decode_op_hdr(xdr, OP_DELEGRETURN);
  }
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
  static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor *flavor)
  {
  	__be32 *p;
  
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	flavor->gss.sec_oid4.len = be32_to_cpup(p);
  	if (flavor->gss.sec_oid4.len > GSS_OID_MAX_LEN)
  		goto out_err;
  
  	p = xdr_inline_decode(xdr, flavor->gss.sec_oid4.len);
  	if (unlikely(!p))
  		goto out_overflow;
  	memcpy(flavor->gss.sec_oid4.data, p, flavor->gss.sec_oid4.len);
  
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
  	flavor->gss.qop4 = be32_to_cpup(p++);
  	flavor->gss.service = be32_to_cpup(p);
  
  	return 0;
  
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  out_err:
  	return -EINVAL;
  }
  
  static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res)
  {
  	struct nfs4_secinfo_flavor *sec_flavor;
  	int status;
  	__be32 *p;
c3dfc2808   Bryan Schumaker   NFS: Use correct ...
5110
  	int i, num_flavors;
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5111
5112
  
  	status = decode_op_hdr(xdr, OP_SECINFO);
613e901e1   Bryan Schumaker   NFS: Return meani...
5113
5114
  	if (status)
  		goto out;
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5115
5116
5117
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5118

c3dfc2808   Bryan Schumaker   NFS: Use correct ...
5119
5120
5121
5122
  	res->flavors->num_flavors = 0;
  	num_flavors = be32_to_cpup(p);
  
  	for (i = 0; i < num_flavors; i++) {
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5123
  		sec_flavor = &res->flavors->flavors[i];
c3dfc2808   Bryan Schumaker   NFS: Use correct ...
5124
  		if ((char *)&sec_flavor[1] - (char *)res->flavors > PAGE_SIZE)
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5125
5126
5127
5128
5129
5130
5131
5132
  			break;
  
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
  		sec_flavor->flavor = be32_to_cpup(p);
  
  		if (sec_flavor->flavor == RPC_AUTH_GSS) {
613e901e1   Bryan Schumaker   NFS: Return meani...
5133
5134
5135
  			status = decode_secinfo_gss(xdr, sec_flavor);
  			if (status)
  				goto out;
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5136
  		}
c3dfc2808   Bryan Schumaker   NFS: Use correct ...
5137
  		res->flavors->num_flavors++;
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5138
  	}
613e901e1   Bryan Schumaker   NFS: Return meani...
5139
5140
  out:
  	return status;
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
5141
5142
5143
5144
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
5145
5146
5147
5148
5149
5150
  #if defined(CONFIG_NFS_V4_1)
  static int decode_exchange_id(struct xdr_stream *xdr,
  			      struct nfs41_exchange_id_res *res)
  {
  	__be32 *p;
  	uint32_t dummy;
2460ba57c   Benny Halevy   nfs: nfs4xdr: sim...
5151
  	char *dummy_str;
99fe60d06   Benny Halevy   nfs41: exchange_i...
5152
5153
5154
5155
5156
5157
  	int status;
  	struct nfs_client *clp = res->client;
  
  	status = decode_op_hdr(xdr, OP_EXCHANGE_ID);
  	if (status)
  		return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5158
5159
5160
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
114f64b5f   Andy Adamson   NFSv4: remove dup...
5161
  	xdr_decode_hyper(p, &clp->cl_clientid);
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5162
5163
5164
  	p = xdr_inline_decode(xdr, 12);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5165
5166
  	clp->cl_seqid = be32_to_cpup(p++);
  	clp->cl_exchange_flags = be32_to_cpup(p++);
99fe60d06   Benny Halevy   nfs41: exchange_i...
5167
5168
  
  	/* We ask for SP4_NONE */
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
5169
  	dummy = be32_to_cpup(p);
99fe60d06   Benny Halevy   nfs41: exchange_i...
5170
5171
5172
5173
  	if (dummy != SP4_NONE)
  		return -EIO;
  
  	/* Throw away minor_id */
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5174
5175
5176
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
99fe60d06   Benny Halevy   nfs41: exchange_i...
5177
5178
  
  	/* Throw away Major id */
2460ba57c   Benny Halevy   nfs: nfs4xdr: sim...
5179
5180
5181
  	status = decode_opaque_inline(xdr, &dummy, &dummy_str);
  	if (unlikely(status))
  		return status;
99fe60d06   Benny Halevy   nfs41: exchange_i...
5182

78fe0f41d   Weston Andros Adamson   NFS: use scope fr...
5183
  	/* Save server_scope */
2460ba57c   Benny Halevy   nfs: nfs4xdr: sim...
5184
5185
5186
  	status = decode_opaque_inline(xdr, &dummy, &dummy_str);
  	if (unlikely(status))
  		return status;
99fe60d06   Benny Halevy   nfs41: exchange_i...
5187

78fe0f41d   Weston Andros Adamson   NFS: use scope fr...
5188
5189
5190
5191
5192
  	if (unlikely(dummy > NFS4_OPAQUE_LIMIT))
  		return -EIO;
  
  	memcpy(res->server_scope->server_scope, dummy_str, dummy);
  	res->server_scope->server_scope_sz = dummy;
99fe60d06   Benny Halevy   nfs41: exchange_i...
5193
  	/* Throw away Implementation id array */
2460ba57c   Benny Halevy   nfs: nfs4xdr: sim...
5194
5195
5196
  	status = decode_opaque_inline(xdr, &dummy, &dummy_str);
  	if (unlikely(status))
  		return status;
99fe60d06   Benny Halevy   nfs41: exchange_i...
5197
5198
  
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5199
5200
5201
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
99fe60d06   Benny Halevy   nfs41: exchange_i...
5202
  }
fc931582c   Andy Adamson   nfs41: create_ses...
5203
5204
5205
5206
5207
  
  static int decode_chan_attrs(struct xdr_stream *xdr,
  			     struct nfs4_channel_attrs *attrs)
  {
  	__be32 *p;
c9c30dd5f   Benny Halevy   NFSv4.1: deprecat...
5208
  	u32 nr_attrs, val;
fc931582c   Andy Adamson   nfs41: create_ses...
5209

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5210
5211
5212
  	p = xdr_inline_decode(xdr, 28);
  	if (unlikely(!p))
  		goto out_overflow;
c9c30dd5f   Benny Halevy   NFSv4.1: deprecat...
5213
5214
5215
  	val = be32_to_cpup(p++);	/* headerpadsz */
  	if (val)
  		return -EINVAL;		/* no support for header padding yet */
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5216
5217
5218
5219
5220
  	attrs->max_rqst_sz = be32_to_cpup(p++);
  	attrs->max_resp_sz = be32_to_cpup(p++);
  	attrs->max_resp_sz_cached = be32_to_cpup(p++);
  	attrs->max_ops = be32_to_cpup(p++);
  	attrs->max_reqs = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
5221
  	nr_attrs = be32_to_cpup(p);
fc931582c   Andy Adamson   nfs41: create_ses...
5222
5223
5224
5225
5226
5227
  	if (unlikely(nr_attrs > 1)) {
  		printk(KERN_WARNING "%s: Invalid rdma channel attrs count %u
  ",
  			__func__, nr_attrs);
  		return -EINVAL;
  	}
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5228
5229
5230
5231
5232
  	if (nr_attrs == 1) {
  		p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */
  		if (unlikely(!p))
  			goto out_overflow;
  	}
fc931582c   Andy Adamson   nfs41: create_ses...
5233
  	return 0;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5234
5235
5236
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
fc931582c   Andy Adamson   nfs41: create_ses...
5237
  }
e78291e4e   Benny Halevy   nfs: nfs4xdr: int...
5238
5239
5240
  static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid)
  {
  	return decode_opaque_fixed(xdr, sid->data, NFS4_MAX_SESSIONID_LEN);
fc931582c   Andy Adamson   nfs41: create_ses...
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
  }
  
  static int decode_create_session(struct xdr_stream *xdr,
  				 struct nfs41_create_session_res *res)
  {
  	__be32 *p;
  	int status;
  	struct nfs_client *clp = res->client;
  	struct nfs4_session *session = clp->cl_session;
  
  	status = decode_op_hdr(xdr, OP_CREATE_SESSION);
e78291e4e   Benny Halevy   nfs: nfs4xdr: int...
5252
5253
5254
  	if (!status)
  		status = decode_sessionid(xdr, &session->sess_id);
  	if (unlikely(status))
fc931582c   Andy Adamson   nfs41: create_ses...
5255
  		return status;
fc931582c   Andy Adamson   nfs41: create_ses...
5256
  	/* seqid, flags */
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5257
5258
5259
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5260
  	clp->cl_seqid = be32_to_cpup(p++);
cccddf4f5   Benny Halevy   nfs: nfs4xdr: opt...
5261
  	session->flags = be32_to_cpup(p);
fc931582c   Andy Adamson   nfs41: create_ses...
5262
5263
5264
5265
5266
5267
  
  	/* Channel attributes */
  	status = decode_chan_attrs(xdr, &session->fc_attrs);
  	if (!status)
  		status = decode_chan_attrs(xdr, &session->bc_attrs);
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5268
5269
5270
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
fc931582c   Andy Adamson   nfs41: create_ses...
5271
  }
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
5272
5273
5274
5275
5276
  
  static int decode_destroy_session(struct xdr_stream *xdr, void *dummy)
  {
  	return decode_op_hdr(xdr, OP_DESTROY_SESSION);
  }
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
5277
5278
5279
5280
5281
  
  static int decode_reclaim_complete(struct xdr_stream *xdr, void *dummy)
  {
  	return decode_op_hdr(xdr, OP_RECLAIM_COMPLETE);
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
5282
  #endif /* CONFIG_NFS_V4_1 */
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5283
5284
5285
5286
5287
  static int decode_sequence(struct xdr_stream *xdr,
  			   struct nfs4_sequence_res *res,
  			   struct rpc_rqst *rqstp)
  {
  #if defined(CONFIG_NFS_V4_1)
fc01cea96   Andy Adamson   nfs41: sequence o...
5288
5289
5290
5291
  	struct nfs4_sessionid id;
  	u32 dummy;
  	int status;
  	__be32 *p;
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5292
5293
  	if (!res->sr_session)
  		return 0;
fc01cea96   Andy Adamson   nfs41: sequence o...
5294
  	status = decode_op_hdr(xdr, OP_SEQUENCE);
e78291e4e   Benny Halevy   nfs: nfs4xdr: int...
5295
5296
5297
  	if (!status)
  		status = decode_sessionid(xdr, &id);
  	if (unlikely(status))
fc01cea96   Andy Adamson   nfs41: sequence o...
5298
  		goto out_err;
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5299

fc01cea96   Andy Adamson   nfs41: sequence o...
5300
5301
5302
5303
  	/*
  	 * If the server returns different values for sessionID, slotID or
  	 * sequence number, the server is looney tunes.
  	 */
fdcb45777   Trond Myklebust   NFS: Fix the mapp...
5304
  	status = -EREMOTEIO;
fc01cea96   Andy Adamson   nfs41: sequence o...
5305

fc01cea96   Andy Adamson   nfs41: sequence o...
5306
5307
5308
5309
5310
5311
  	if (memcmp(id.data, res->sr_session->sess_id.data,
  		   NFS4_MAX_SESSIONID_LEN)) {
  		dprintk("%s Invalid session id
  ", __func__);
  		goto out_err;
  	}
e78291e4e   Benny Halevy   nfs: nfs4xdr: int...
5312

c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5313
5314
5315
  	p = xdr_inline_decode(xdr, 20);
  	if (unlikely(!p))
  		goto out_overflow;
e78291e4e   Benny Halevy   nfs: nfs4xdr: int...
5316

fc01cea96   Andy Adamson   nfs41: sequence o...
5317
  	/* seqid */
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5318
  	dummy = be32_to_cpup(p++);
dfb4f3098   Benny Halevy   NFSv4.1: keep seq...
5319
  	if (dummy != res->sr_slot->seq_nr) {
fc01cea96   Andy Adamson   nfs41: sequence o...
5320
5321
5322
5323
5324
  		dprintk("%s Invalid sequence number
  ", __func__);
  		goto out_err;
  	}
  	/* slot id */
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5325
  	dummy = be32_to_cpup(p++);
dfb4f3098   Benny Halevy   NFSv4.1: keep seq...
5326
  	if (dummy != res->sr_slot - res->sr_session->fc_slot_table.slots) {
fc01cea96   Andy Adamson   nfs41: sequence o...
5327
5328
5329
5330
5331
  		dprintk("%s Invalid slot id
  ", __func__);
  		goto out_err;
  	}
  	/* highest slot id - currently not processed */
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5332
  	dummy = be32_to_cpup(p++);
fc01cea96   Andy Adamson   nfs41: sequence o...
5333
  	/* target highest slot id - currently not processed */
6f723f771   Benny Halevy   nfs: nfs4xdr: get...
5334
  	dummy = be32_to_cpup(p++);
0629e370d   Alexandros Batsakis   nfs41: check SEQU...
5335
5336
  	/* result flags */
  	res->sr_status_flags = be32_to_cpup(p);
fc01cea96   Andy Adamson   nfs41: sequence o...
5337
5338
5339
5340
  	status = 0;
  out_err:
  	res->sr_status = status;
  	return status;
c0eae66ec   Benny Halevy   nfs: nfs4xdr: get...
5341
5342
5343
5344
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	status = -EIO;
  	goto out_err;
fc01cea96   Andy Adamson   nfs41: sequence o...
5345
  #else  /* CONFIG_NFS_V4_1 */
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5346
  	return 0;
fc01cea96   Andy Adamson   nfs41: sequence o...
5347
  #endif /* CONFIG_NFS_V4_1 */
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5348
  }
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5349
  #if defined(CONFIG_NFS_V4_1)
7f11d8d38   Andy Adamson   pnfs: GETDEVICELIST
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
  /*
   * TODO: Need to handle case when EOF != true;
   */
  static int decode_getdevicelist(struct xdr_stream *xdr,
  				struct pnfs_devicelist *res)
  {
  	__be32 *p;
  	int status, i;
  	struct nfs_writeverf verftemp;
  
  	status = decode_op_hdr(xdr, OP_GETDEVICELIST);
  	if (status)
  		return status;
  
  	p = xdr_inline_decode(xdr, 8 + 8 + 4);
  	if (unlikely(!p))
  		goto out_overflow;
  
  	/* TODO: Skip cookie for now */
  	p += 2;
  
  	/* Read verifier */
  	p = xdr_decode_opaque_fixed(p, verftemp.verifier, 8);
  
  	res->num_devs = be32_to_cpup(p);
  
  	dprintk("%s: num_dev %d
  ", __func__, res->num_devs);
  
  	if (res->num_devs > NFS4_PNFS_GETDEVLIST_MAXNUM) {
  		printk(KERN_ERR "%s too many result dev_num %u
  ",
  				__func__, res->num_devs);
  		return -EIO;
  	}
  
  	p = xdr_inline_decode(xdr,
  			      res->num_devs * NFS4_DEVICEID4_SIZE + 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	for (i = 0; i < res->num_devs; i++)
  		p = xdr_decode_opaque_fixed(p, res->dev_id[i].data,
  					    NFS4_DEVICEID4_SIZE);
  	res->eof = be32_to_cpup(p);
  	return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
  
  static int decode_getdeviceinfo(struct xdr_stream *xdr,
  				struct pnfs_device *pdev)
  {
  	__be32 *p;
  	uint32_t len, type;
  	int status;
  
  	status = decode_op_hdr(xdr, OP_GETDEVICEINFO);
  	if (status) {
  		if (status == -ETOOSMALL) {
  			p = xdr_inline_decode(xdr, 4);
  			if (unlikely(!p))
  				goto out_overflow;
  			pdev->mincount = be32_to_cpup(p);
  			dprintk("%s: Min count too small. mincnt = %u
  ",
  				__func__, pdev->mincount);
  		}
  		return status;
  	}
  
  	p = xdr_inline_decode(xdr, 8);
  	if (unlikely(!p))
  		goto out_overflow;
  	type = be32_to_cpup(p++);
  	if (type != pdev->layout_type) {
  		dprintk("%s: layout mismatch req: %u pdev: %u
  ",
  			__func__, pdev->layout_type, type);
  		return -EINVAL;
  	}
  	/*
  	 * Get the length of the opaque device_addr4. xdr_read_pages places
  	 * the opaque device_addr4 in the xdr_buf->pages (pnfs_device->pages)
  	 * and places the remaining xdr data in xdr_buf->tail
  	 */
  	pdev->mincount = be32_to_cpup(p);
  	xdr_read_pages(xdr, pdev->mincount); /* include space for the length */
  
  	/* Parse notification bitmap, verifying that it is zero. */
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	len = be32_to_cpup(p);
  	if (len) {
ead005978   Chuck Lever   NFS: Squelch comp...
5445
  		uint32_t i;
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
  
  		p = xdr_inline_decode(xdr, 4 * len);
  		if (unlikely(!p))
  			goto out_overflow;
  		for (i = 0; i < len; i++, p++) {
  			if (be32_to_cpup(p)) {
  				dprintk("%s: notifications not supported
  ",
  					__func__);
  				return -EIO;
  			}
  		}
  	}
  	return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
  
  static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
  			    struct nfs4_layoutget_res *res)
  {
  	__be32 *p;
  	int status;
  	u32 layout_count;
35124a099   Weston Andros Adamson   Cleanup XDR parsi...
5471
5472
5473
  	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
  	struct kvec *iov = rcvbuf->head;
  	u32 hdrlen, recvd;
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
  
  	status = decode_op_hdr(xdr, OP_LAYOUTGET);
  	if (status)
  		return status;
  	p = xdr_inline_decode(xdr, 8 + NFS4_STATEID_SIZE);
  	if (unlikely(!p))
  		goto out_overflow;
  	res->return_on_close = be32_to_cpup(p++);
  	p = xdr_decode_opaque_fixed(p, res->stateid.data, NFS4_STATEID_SIZE);
  	layout_count = be32_to_cpup(p);
  	if (!layout_count) {
  		dprintk("%s: server responded with empty layout array
  ",
  			__func__);
  		return -EINVAL;
  	}
35124a099   Weston Andros Adamson   Cleanup XDR parsi...
5490
  	p = xdr_inline_decode(xdr, 28);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5491
5492
5493
5494
5495
5496
  	if (unlikely(!p))
  		goto out_overflow;
  	p = xdr_decode_hyper(p, &res->range.offset);
  	p = xdr_decode_hyper(p, &res->range.length);
  	res->range.iomode = be32_to_cpup(p++);
  	res->type = be32_to_cpup(p++);
35124a099   Weston Andros Adamson   Cleanup XDR parsi...
5497
  	res->layoutp->len = be32_to_cpup(p);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5498
5499
5500
5501
5502
5503
5504
5505
  
  	dprintk("%s roff:%lu rlen:%lu riomode:%d, lo_type:0x%x, lo.len:%d
  ",
  		__func__,
  		(unsigned long)res->range.offset,
  		(unsigned long)res->range.length,
  		res->range.iomode,
  		res->type,
35124a099   Weston Andros Adamson   Cleanup XDR parsi...
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
  		res->layoutp->len);
  
  	hdrlen = (u8 *) xdr->p - (u8 *) iov->iov_base;
  	recvd = req->rq_rcv_buf.len - hdrlen;
  	if (res->layoutp->len > recvd) {
  		dprintk("NFS: server cheating in layoutget reply: "
  				"layout len %u > recvd %u
  ",
  				res->layoutp->len, recvd);
  		return -EINVAL;
  	}
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5517

35124a099   Weston Andros Adamson   Cleanup XDR parsi...
5518
  	xdr_read_pages(xdr, res->layoutp->len);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
  
  	if (layout_count > 1) {
  		/* We only handle a length one array at the moment.  Any
  		 * further entries are just ignored.  Note that this means
  		 * the client may see a response that is less than the
  		 * minimum it requested.
  		 */
  		dprintk("%s: server responded with %d layouts, dropping tail
  ",
  			__func__, layout_count);
  	}
  
  	return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
5536

cbe826036   Benny Halevy   pnfs: layoutreturn
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
  static int decode_layoutreturn(struct xdr_stream *xdr,
  			       struct nfs4_layoutreturn_res *res)
  {
  	__be32 *p;
  	int status;
  
  	status = decode_op_hdr(xdr, OP_LAYOUTRETURN);
  	if (status)
  		return status;
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	res->lrs_present = be32_to_cpup(p);
  	if (res->lrs_present)
  		status = decode_stateid(xdr, &res->stateid);
  	return status;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
5557
5558
5559
5560
5561
5562
5563
5564
5565
  static int decode_layoutcommit(struct xdr_stream *xdr,
  			       struct rpc_rqst *req,
  			       struct nfs4_layoutcommit_res *res)
  {
  	__be32 *p;
  	__u32 sizechanged;
  	int status;
  
  	status = decode_op_hdr(xdr, OP_LAYOUTCOMMIT);
db29c0890   Andy Adamson   pnfs: cleanup_lay...
5566
  	res->status = status;
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
  	if (status)
  		return status;
  
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	sizechanged = be32_to_cpup(p);
  
  	if (sizechanged) {
  		/* throw away new size */
  		p = xdr_inline_decode(xdr, 8);
  		if (unlikely(!p))
  			goto out_overflow;
  	}
  	return 0;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
7d9747947   Bryan Schumaker   NFS: Added TEST_S...
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
  
  static int decode_test_stateid(struct xdr_stream *xdr,
  			       struct nfs41_test_stateid_res *res)
  {
  	__be32 *p;
  	int status;
  	int num_res;
  
  	status = decode_op_hdr(xdr, OP_TEST_STATEID);
  	if (status)
  		return status;
  
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	num_res = be32_to_cpup(p++);
  	if (num_res != 1)
  		goto out;
  
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	res->status = be32_to_cpup(p++);
  	return res->status;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  out:
  	return -EIO;
  }
9aeda35fd   Bryan Schumaker   NFS: added FREE_S...
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
  
  static int decode_free_stateid(struct xdr_stream *xdr,
  			       struct nfs41_free_stateid_res *res)
  {
  	__be32 *p;
  	int status;
  
  	status = decode_op_hdr(xdr, OP_FREE_STATEID);
  	if (status)
  		return status;
  
  	p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
  	res->status = be32_to_cpup(p++);
  	return res->status;
  out_overflow:
  	print_overflow_msg(__func__, xdr);
  	return -EIO;
  }
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
5635
  #endif /* CONFIG_NFS_V4_1 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5636
  /*
49c2559e2   Benny Halevy   NFS: fix comment ...
5637
5638
5639
5640
   * END OF "GENERIC" DECODE ROUTINES.
   */
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5641
5642
   * Decode OPEN_DOWNGRADE response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5643
5644
5645
  static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp,
  				       struct xdr_stream *xdr,
  				       struct nfs_closeres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5646
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5647
5648
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5649
  	status = decode_compound_hdr(xdr, &hdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5650
5651
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5652
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5653
5654
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5655
  	status = decode_putfh(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5656
5657
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5658
  	status = decode_open_downgrade(xdr, res);
516a6af64   Trond Myklebust   NFS: Add optional...
5659
5660
  	if (status != 0)
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5661
  	decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5662
  out:
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5663
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5664
5665
5666
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5667
5668
   * Decode ACCESS response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5669
5670
  static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			       struct nfs4_accessres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5671
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5672
5673
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5674

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5675
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5676
5677
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5678
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5679
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5680
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5681
  	status = decode_putfh(xdr);
76b32999d   Trond Myklebust   NFSv4: Make NFSv4...
5682
5683
  	if (status != 0)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5684
  	status = decode_access(xdr, res);
76b32999d   Trond Myklebust   NFSv4: Make NFSv4...
5685
5686
  	if (status != 0)
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5687
  	decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5688
5689
5690
5691
5692
5693
5694
  out:
  	return status;
  }
  
  /*
   * Decode LOOKUP response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5695
5696
  static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			       struct nfs4_lookup_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5697
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5698
5699
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5700

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5701
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5702
5703
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5704
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5705
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5706
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5707
5708
  	status = decode_putfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5709
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5710
5711
  	status = decode_lookup(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5712
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5713
5714
  	status = decode_getfh(xdr, res->fh);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5715
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5716
  	status = decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5717
5718
5719
5720
5721
5722
5723
  out:
  	return status;
  }
  
  /*
   * Decode LOOKUP_ROOT response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5724
5725
5726
  static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
  				    struct xdr_stream *xdr,
  				    struct nfs4_lookup_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5727
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5728
5729
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5730

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5731
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5732
5733
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5734
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5735
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5736
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5737
5738
  	status = decode_putrootfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5739
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5740
5741
  	status = decode_getfh(xdr, res->fh);
  	if (status == 0)
6926afd19   Trond Myklebust   NFSv4: Save the o...
5742
  		status = decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5743
5744
5745
5746
5747
5748
5749
  out:
  	return status;
  }
  
  /*
   * Decode REMOVE response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5750
5751
  static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			       struct nfs_removeres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5752
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5753
5754
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5755

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5756
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5757
5758
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5759
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5760
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5761
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5762
5763
  	status = decode_putfh(xdr);
  	if (status)
16e429596   Trond Myklebust   NFSv4: Add post-o...
5764
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5765
5766
  	status = decode_remove(xdr, &res->cinfo);
  	if (status)
16e429596   Trond Myklebust   NFSv4: Add post-o...
5767
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5768
  	decode_getfattr(xdr, res->dir_attr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5769
5770
5771
5772
5773
5774
5775
  out:
  	return status;
  }
  
  /*
   * Decode RENAME response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5776
5777
  static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			       struct nfs_renameres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5778
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5779
5780
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5781

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5782
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5783
5784
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5785
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5786
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5787
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5788
5789
  	status = decode_putfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5790
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5791
5792
  	status = decode_savefh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5793
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5794
5795
  	status = decode_putfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5796
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5797
5798
  	status = decode_rename(xdr, &res->old_cinfo, &res->new_cinfo);
  	if (status)
6caf2c827   Trond Myklebust   NFSv4: Add post-o...
5799
5800
  		goto out;
  	/* Current FH is target directory */
6926afd19   Trond Myklebust   NFSv4: Save the o...
5801
  	if (decode_getfattr(xdr, res->new_fattr, res->server))
6caf2c827   Trond Myklebust   NFSv4: Add post-o...
5802
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5803
5804
  	status = decode_restorefh(xdr);
  	if (status)
6caf2c827   Trond Myklebust   NFSv4: Add post-o...
5805
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5806
  	decode_getfattr(xdr, res->old_fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5807
5808
5809
5810
5811
5812
5813
  out:
  	return status;
  }
  
  /*
   * Decode LINK response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5814
5815
  static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			     struct nfs4_link_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5816
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5817
5818
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5819

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5820
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5821
5822
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5823
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5824
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5825
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5826
5827
  	status = decode_putfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5828
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5829
5830
  	status = decode_savefh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5831
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5832
5833
  	status = decode_putfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5834
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5835
5836
  	status = decode_link(xdr, &res->cinfo);
  	if (status)
91ba2eeec   Trond Myklebust   NFSv4: Add post-o...
5837
5838
5839
5840
5841
  		goto out;
  	/*
  	 * Note order: OP_LINK leaves the directory as the current
  	 *             filehandle.
  	 */
6926afd19   Trond Myklebust   NFSv4: Save the o...
5842
  	if (decode_getfattr(xdr, res->dir_attr, res->server))
91ba2eeec   Trond Myklebust   NFSv4: Add post-o...
5843
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5844
5845
  	status = decode_restorefh(xdr);
  	if (status)
91ba2eeec   Trond Myklebust   NFSv4: Add post-o...
5846
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5847
  	decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5848
5849
5850
5851
5852
5853
5854
  out:
  	return status;
  }
  
  /*
   * Decode CREATE response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5855
5856
  static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			       struct nfs4_create_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5857
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5858
5859
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5860

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5861
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5862
5863
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5864
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5865
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5866
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5867
5868
  	status = decode_putfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5869
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5870
5871
  	status = decode_savefh(xdr);
  	if (status)
56ae19f38   Trond Myklebust   NFSv4: Add direct...
5872
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5873
5874
  	status = decode_create(xdr, &res->dir_cinfo);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5875
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5876
5877
  	status = decode_getfh(xdr, res->fh);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5878
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5879
  	if (decode_getfattr(xdr, res->fattr, res->server))
56ae19f38   Trond Myklebust   NFSv4: Add direct...
5880
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5881
5882
  	status = decode_restorefh(xdr);
  	if (status)
56ae19f38   Trond Myklebust   NFSv4: Add direct...
5883
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5884
  	decode_getfattr(xdr, res->dir_fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5885
5886
5887
5888
5889
5890
5891
  out:
  	return status;
  }
  
  /*
   * Decode SYMLINK response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5892
5893
  static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  				struct nfs4_create_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5894
  {
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5895
  	return nfs4_xdr_dec_create(rqstp, xdr, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5896
5897
5898
5899
5900
  }
  
  /*
   * Decode GETATTR response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5901
5902
  static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  				struct nfs4_getattr_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5903
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5904
5905
  	struct compound_hdr hdr;
  	int status;
6c0195a46   Andy Adamson   NFS: remove white...
5906

bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5907
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5908
5909
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5910
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5911
5912
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5913
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5914
5915
  	if (status)
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
5916
  	status = decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5917
5918
  out:
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5919
  }
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5920
5921
5922
  /*
   * Encode an SETACL request
   */
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
5923
5924
  static void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr,
  				struct nfs_setaclargs *args)
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5925
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5926
  	struct compound_hdr hdr = {
66cc04297   Benny Halevy   nfs41: encode min...
5927
  		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5928
  	};
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5929

9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
5930
5931
5932
5933
  	encode_compound_hdr(xdr, req, &hdr);
  	encode_sequence(xdr, &args->seq_args, &hdr);
  	encode_putfh(xdr, args->fh, &hdr);
  	encode_setacl(xdr, args, &hdr);
d017931cf   Andy Adamson   NFS: increment nu...
5934
  	encode_nops(&hdr);
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5935
  }
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5936

23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5937
5938
5939
5940
  /*
   * Decode SETACL response
   */
  static int
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5941
  nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
73c403a9a   Benny Halevy   nfs41: use nfs4_s...
5942
  		    struct nfs_setaclres *res)
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5943
  {
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5944
5945
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5946
  	status = decode_compound_hdr(xdr, &hdr);
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5947
5948
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5949
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5950
5951
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5952
  	status = decode_putfh(xdr);
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5953
5954
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5955
  	status = decode_setattr(xdr);
23ec6965c   J. Bruce Fields   [PATCH] NFSv4: Cl...
5956
5957
5958
  out:
  	return status;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5959
5960
  
  /*
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
5961
5962
5963
   * Decode GETACL response
   */
  static int
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5964
  nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
663c79b3c   Benny Halevy   nfs41: use nfs4_g...
5965
  		    struct nfs_getaclres *res)
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
5966
  {
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
5967
5968
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5969
  	status = decode_compound_hdr(xdr, &hdr);
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
5970
5971
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5972
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5973
5974
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5975
  	status = decode_putfh(xdr);
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
5976
5977
  	if (status)
  		goto out;
bf118a342   Andy Adamson   NFSv4: include bi...
5978
  	status = decode_getacl(xdr, rqstp, res);
029d105e6   J. Bruce Fields   [PATCH] NFSv4: Cl...
5979
5980
5981
5982
5983
5984
  
  out:
  	return status;
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5985
5986
   * Decode CLOSE response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5987
5988
  static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			      struct nfs_closeres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5989
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5990
5991
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5992
  	status = decode_compound_hdr(xdr, &hdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5993
5994
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5995
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
5996
5997
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
5998
  	status = decode_putfh(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
5999
6000
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6001
  	status = decode_close(xdr, res);
516a6af64   Trond Myklebust   NFS: Add optional...
6002
6003
6004
6005
6006
6007
6008
6009
  	if (status != 0)
  		goto out;
  	/*
  	 * Note: Server may do delete on close for this file
  	 * 	in which case the getattr call will fail with
  	 * 	an ESTALE error. Shouldn't be a problem,
  	 * 	though, since fattr->valid will remain unset.
  	 */
6926afd19   Trond Myklebust   NFSv4: Save the o...
6010
  	decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6011
  out:
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6012
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6013
6014
6015
6016
6017
  }
  
  /*
   * Decode OPEN response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6018
6019
  static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			     struct nfs_openres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6020
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6021
6022
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6023
  	status = decode_compound_hdr(xdr, &hdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6024
6025
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6026
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6027
6028
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6029
  	status = decode_putfh(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6030
6031
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6032
  	status = decode_savefh(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6033
6034
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6035
  	status = decode_open(xdr, res);
56ae19f38   Trond Myklebust   NFSv4: Add direct...
6036
6037
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6038
  	if (decode_getfh(xdr, &res->fh) != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6039
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
6040
  	if (decode_getfattr(xdr, res->f_attr, res->server) != 0)
56ae19f38   Trond Myklebust   NFSv4: Add direct...
6041
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6042
  	if (decode_restorefh(xdr) != 0)
56ae19f38   Trond Myklebust   NFSv4: Add direct...
6043
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
6044
  	decode_getfattr(xdr, res->dir_attr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6045
  out:
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6046
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6047
6048
6049
6050
6051
  }
  
  /*
   * Decode OPEN_CONFIRM response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6052
6053
6054
  static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp,
  				     struct xdr_stream *xdr,
  				     struct nfs_open_confirmres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6055
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6056
6057
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6058
  	status = decode_compound_hdr(xdr, &hdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6059
6060
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6061
  	status = decode_putfh(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6062
6063
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6064
  	status = decode_open_confirm(xdr, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6065
  out:
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6066
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6067
6068
6069
6070
6071
  }
  
  /*
   * Decode OPEN response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6072
6073
6074
  static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp,
  				    struct xdr_stream *xdr,
  				    struct nfs_openres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6075
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6076
6077
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6078
  	status = decode_compound_hdr(xdr, &hdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6079
6080
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6081
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6082
6083
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6084
  	status = decode_putfh(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6085
6086
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6087
  	status = decode_open(xdr, res);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6088
6089
  	if (status)
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
6090
  	decode_getfattr(xdr, res->f_attr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6091
  out:
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6092
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6093
6094
6095
6096
6097
  }
  
  /*
   * Decode SETATTR response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6098
6099
6100
  static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp,
  				struct xdr_stream *xdr,
  				struct nfs_setattrres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6101
  {
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6102
6103
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6104
  	status = decode_compound_hdr(xdr, &hdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6105
6106
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6107
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6108
6109
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6110
  	status = decode_putfh(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6111
6112
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6113
  	status = decode_setattr(xdr);
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6114
6115
  	if (status)
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
6116
  	decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6117
  out:
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6118
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6119
6120
6121
6122
6123
  }
  
  /*
   * Decode LOCK response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6124
6125
  static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			     struct nfs_lock_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6126
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6127
6128
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6129
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6130
6131
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6132
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6133
6134
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6135
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6136
6137
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6138
  	status = decode_lock(xdr, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6139
6140
6141
6142
6143
6144
6145
  out:
  	return status;
  }
  
  /*
   * Decode LOCKT response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6146
6147
  static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			      struct nfs_lockt_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6148
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6149
6150
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6151
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6152
6153
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6154
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6155
6156
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6157
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6158
6159
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6160
  	status = decode_lockt(xdr, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6161
6162
6163
6164
6165
6166
6167
  out:
  	return status;
  }
  
  /*
   * Decode LOCKU response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6168
6169
  static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			      struct nfs_locku_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6170
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6171
6172
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6173
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6174
6175
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6176
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6177
6178
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6179
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6180
6181
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6182
  	status = decode_locku(xdr, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6183
6184
6185
  out:
  	return status;
  }
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6186
6187
  static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp,
  					  struct xdr_stream *xdr, void *dummy)
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
6188
  {
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
6189
6190
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6191
  	status = decode_compound_hdr(xdr, &hdr);
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
6192
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6193
  		status = decode_release_lockowner(xdr);
d3c7b7ccc   Trond Myklebust   NFSv4: Add suppor...
6194
6195
  	return status;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6196
6197
6198
  /*
   * Decode READLINK response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6199
6200
  static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp,
  				 struct xdr_stream *xdr,
f50c70008   Benny Halevy   nfs41: use nfs4_r...
6201
  				 struct nfs4_readlink_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6202
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6203
6204
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6205
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6206
6207
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6208
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6209
6210
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6211
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6212
6213
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6214
  	status = decode_readlink(xdr, rqstp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6215
6216
6217
6218
6219
6220
6221
  out:
  	return status;
  }
  
  /*
   * Decode READDIR response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6222
6223
  static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  				struct nfs4_readdir_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6224
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6225
6226
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6227
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6228
6229
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6230
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6231
6232
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6233
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6234
6235
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6236
  	status = decode_readdir(xdr, rqstp, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6237
6238
6239
6240
6241
6242
6243
  out:
  	return status;
  }
  
  /*
   * Decode Read response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6244
6245
  static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			     struct nfs_readres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6246
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6247
6248
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6249
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6250
6251
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6252
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6253
6254
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6255
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6256
6257
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6258
  	status = decode_read(xdr, rqstp, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6259
6260
6261
6262
6263
6264
6265
6266
6267
  	if (!status)
  		status = res->count;
  out:
  	return status;
  }
  
  /*
   * Decode WRITE response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6268
6269
  static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			      struct nfs_writeres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6270
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6271
6272
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6273
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6274
6275
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6276
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6277
6278
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6279
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6280
6281
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6282
  	status = decode_write(xdr, res);
4f9838c7e   Trond Myklebust   NFSv4: Add post-o...
6283
6284
  	if (status)
  		goto out;
7ffd10640   Fred Isaman   NFSv4.1: remove G...
6285
  	if (res->fattr)
6926afd19   Trond Myklebust   NFSv4: Save the o...
6286
  		decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6287
6288
6289
6290
6291
6292
6293
6294
6295
  	if (!status)
  		status = res->count;
  out:
  	return status;
  }
  
  /*
   * Decode COMMIT response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6296
6297
  static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			       struct nfs_writeres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6298
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6299
6300
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6301
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6302
6303
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6304
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6305
6306
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6307
  	status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6308
6309
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6310
  	status = decode_commit(xdr, res);
4f9838c7e   Trond Myklebust   NFSv4: Add post-o...
6311
6312
  	if (status)
  		goto out;
988b6dceb   Fred Isaman   NFSv4.1: remove G...
6313
  	if (res->fattr)
6926afd19   Trond Myklebust   NFSv4: Save the o...
6314
  		decode_getfattr(xdr, res->fattr, res->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6315
6316
6317
6318
6319
  out:
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6320
   * Decode FSINFO response
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6321
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6322
  static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr,
3dda5e434   Benny Halevy   nfs41: use nfs4_f...
6323
  			       struct nfs4_fsinfo_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6324
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6325
6326
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6327
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6328
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6329
  		status = decode_sequence(xdr, &res->seq_res, req);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6330
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6331
  		status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6332
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6333
  		status = decode_fsinfo(xdr, res->fsinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6334
6335
6336
6337
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6338
   * Decode PATHCONF response
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6339
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6340
  static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr,
d45b2989a   Benny Halevy   nfs41: use nfs4_p...
6341
  				 struct nfs4_pathconf_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6342
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6343
6344
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6345
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6346
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6347
  		status = decode_sequence(xdr, &res->seq_res, req);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6348
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6349
  		status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6350
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6351
  		status = decode_pathconf(xdr, res->pathconf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6352
6353
6354
6355
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6356
   * Decode STATFS response
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6357
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6358
  static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, struct xdr_stream *xdr,
24ad148a0   Benny Halevy   nfs41: use nfs4_s...
6359
  			       struct nfs4_statfs_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6360
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6361
6362
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6363
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6364
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6365
  		status = decode_sequence(xdr, &res->seq_res, req);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6366
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6367
  		status = decode_putfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6368
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6369
  		status = decode_statfs(xdr, res->fsstat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6370
6371
6372
6373
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6374
   * Decode GETATTR_BITMAP response
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6375
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6376
6377
6378
  static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req,
  				    struct xdr_stream *xdr,
  				    struct nfs4_server_caps_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6379
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6380
6381
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6382
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6383
6384
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6385
  	status = decode_sequence(xdr, &res->seq_res, req);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6386
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6387
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6388
6389
  	status = decode_putfh(xdr);
  	if (status)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6390
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6391
  	status = decode_server_caps(xdr, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6392
6393
6394
6395
6396
6397
6398
  out:
  	return status;
  }
  
  /*
   * Decode RENEW response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6399
6400
  static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
  			      void *__unused)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6401
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6402
6403
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6404
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6405
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6406
  		status = decode_renew(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6407
6408
6409
6410
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6411
   * Decode SETCLIENTID response
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6412
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6413
6414
6415
  static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req,
  				    struct xdr_stream *xdr,
  				    struct nfs4_setclientid_res *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6416
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6417
6418
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6419
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6420
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6421
  		status = decode_setclientid(xdr, res);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6422
6423
6424
6425
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6426
   * Decode SETCLIENTID_CONFIRM response
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6427
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6428
6429
6430
  static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req,
  					    struct xdr_stream *xdr,
  					    struct nfs_fsinfo *fsinfo)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6431
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6432
6433
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6434
  	status = decode_compound_hdr(xdr, &hdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6435
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6436
  		status = decode_setclientid_confirm(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6437
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6438
  		status = decode_putrootfh(xdr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6439
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6440
  		status = decode_fsinfo(xdr, fsinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6441
6442
6443
6444
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6445
   * Decode DELEGRETURN response
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6446
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6447
6448
6449
  static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp,
  				    struct xdr_stream *xdr,
  				    struct nfs4_delegreturnres *res)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6450
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6451
6452
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6453
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6454
6455
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6456
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6457
  	if (status)
fa178f29c   Trond Myklebust   NFSv4: Ensure DEL...
6458
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6459
  	status = decode_putfh(xdr);
fa178f29c   Trond Myklebust   NFSv4: Ensure DEL...
6460
6461
  	if (status != 0)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6462
  	status = decode_delegreturn(xdr);
556ae3bb3   Jeff Layton   NFS: don't try to...
6463
6464
  	if (status != 0)
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
6465
  	decode_getfattr(xdr, res->fattr, res->server);
fa178f29c   Trond Myklebust   NFSv4: Ensure DEL...
6466
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6467
6468
  	return status;
  }
683b57b43   Trond Myklebust   NFSv4: Implement ...
6469
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6470
   * Decode FS_LOCATIONS response
683b57b43   Trond Myklebust   NFSv4: Implement ...
6471
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6472
6473
  static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req,
  				     struct xdr_stream *xdr,
22958463d   Benny Halevy   nfs41: use nfs4_f...
6474
  				     struct nfs4_fs_locations_res *res)
683b57b43   Trond Myklebust   NFSv4: Implement ...
6475
  {
683b57b43   Trond Myklebust   NFSv4: Implement ...
6476
6477
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6478
  	status = decode_compound_hdr(xdr, &hdr);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6479
6480
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6481
  	status = decode_sequence(xdr, &res->seq_res, req);
9b7b9fcc9   Andy Adamson   nfs41: xdr {encod...
6482
  	if (status)
683b57b43   Trond Myklebust   NFSv4: Implement ...
6483
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6484
6485
  	status = decode_putfh(xdr);
  	if (status)
683b57b43   Trond Myklebust   NFSv4: Implement ...
6486
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6487
6488
  	status = decode_lookup(xdr);
  	if (status)
683b57b43   Trond Myklebust   NFSv4: Implement ...
6489
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6490
6491
  	xdr_enter_page(xdr, PAGE_SIZE);
  	status = decode_getfattr(xdr, &res->fs_locations->fattr,
6926afd19   Trond Myklebust   NFSv4: Save the o...
6492
  				 res->fs_locations->server);
683b57b43   Trond Myklebust   NFSv4: Implement ...
6493
6494
6495
  out:
  	return status;
  }
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
  /*
   * Decode SECINFO response
   */
  static int nfs4_xdr_dec_secinfo(struct rpc_rqst *rqstp,
  				struct xdr_stream *xdr,
  				struct nfs4_secinfo_res *res)
  {
  	struct compound_hdr hdr;
  	int status;
  
  	status = decode_compound_hdr(xdr, &hdr);
  	if (status)
  		goto out;
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
  	if (status)
  		goto out;
  	status = decode_putfh(xdr);
  	if (status)
  		goto out;
  	status = decode_secinfo(xdr, res);
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
6516
6517
6518
  out:
  	return status;
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
6519
6520
  #if defined(CONFIG_NFS_V4_1)
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6521
   * Decode EXCHANGE_ID response
99fe60d06   Benny Halevy   nfs41: exchange_i...
6522
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6523
6524
  static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp,
  				    struct xdr_stream *xdr,
99fe60d06   Benny Halevy   nfs41: exchange_i...
6525
6526
  				    void *res)
  {
99fe60d06   Benny Halevy   nfs41: exchange_i...
6527
6528
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6529
  	status = decode_compound_hdr(xdr, &hdr);
99fe60d06   Benny Halevy   nfs41: exchange_i...
6530
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6531
  		status = decode_exchange_id(xdr, res);
99fe60d06   Benny Halevy   nfs41: exchange_i...
6532
6533
  	return status;
  }
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6534
6535
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6536
   * Decode CREATE_SESSION response
fc931582c   Andy Adamson   nfs41: create_ses...
6537
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6538
6539
  static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp,
  				       struct xdr_stream *xdr,
fc931582c   Andy Adamson   nfs41: create_ses...
6540
6541
  				       struct nfs41_create_session_res *res)
  {
fc931582c   Andy Adamson   nfs41: create_ses...
6542
6543
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6544
  	status = decode_compound_hdr(xdr, &hdr);
fc931582c   Andy Adamson   nfs41: create_ses...
6545
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6546
  		status = decode_create_session(xdr, res);
fc931582c   Andy Adamson   nfs41: create_ses...
6547
6548
6549
6550
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6551
   * Decode DESTROY_SESSION response
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
6552
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6553
6554
6555
  static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp,
  					struct xdr_stream *xdr,
  					void *res)
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
6556
  {
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
6557
6558
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6559
  	status = decode_compound_hdr(xdr, &hdr);
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
6560
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6561
  		status = decode_destroy_session(xdr, res);
0f3e66c6a   Andy Adamson   nfs41: destroy_se...
6562
6563
6564
6565
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6566
   * Decode SEQUENCE response
fc01cea96   Andy Adamson   nfs41: sequence o...
6567
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6568
6569
  static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp,
  				 struct xdr_stream *xdr,
fc01cea96   Andy Adamson   nfs41: sequence o...
6570
6571
  				 struct nfs4_sequence_res *res)
  {
fc01cea96   Andy Adamson   nfs41: sequence o...
6572
6573
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6574
  	status = decode_compound_hdr(xdr, &hdr);
fc01cea96   Andy Adamson   nfs41: sequence o...
6575
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6576
  		status = decode_sequence(xdr, res, rqstp);
fc01cea96   Andy Adamson   nfs41: sequence o...
6577
6578
6579
6580
  	return status;
  }
  
  /*
8b173218b   Ricardo Labiaga   Cleanup some NFSv...
6581
   * Decode GET_LEASE_TIME response
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6582
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6583
6584
  static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp,
  				       struct xdr_stream *xdr,
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6585
6586
  				       struct nfs4_get_lease_time_res *res)
  {
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6587
6588
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6589
  	status = decode_compound_hdr(xdr, &hdr);
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6590
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6591
  		status = decode_sequence(xdr, &res->lr_seq_res, rqstp);
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6592
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6593
  		status = decode_putrootfh(xdr);
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6594
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6595
  		status = decode_fsinfo(xdr, res->lr_fsinfo);
2050f0cc0   Andy Adamson   nfs41: get_lease_...
6596
6597
  	return status;
  }
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
6598
6599
6600
6601
  
  /*
   * Decode RECLAIM_COMPLETE response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6602
6603
  static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp,
  					 struct xdr_stream *xdr,
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
6604
6605
  					 struct nfs41_reclaim_complete_res *res)
  {
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
6606
6607
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6608
  	status = decode_compound_hdr(xdr, &hdr);
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
6609
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6610
  		status = decode_sequence(xdr, &res->seq_res, rqstp);
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
6611
  	if (!status)
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6612
  		status = decode_reclaim_complete(xdr, (void *)NULL);
180197536   Ricardo Labiaga   nfs41: RECLAIM_CO...
6613
6614
  	return status;
  }
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6615
6616
  
  /*
7f11d8d38   Andy Adamson   pnfs: GETDEVICELIST
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
   * Decode GETDEVICELIST response
   */
  static int nfs4_xdr_dec_getdevicelist(struct rpc_rqst *rqstp,
  				      struct xdr_stream *xdr,
  				      struct nfs4_getdevicelist_res *res)
  {
  	struct compound_hdr hdr;
  	int status;
  
  	dprintk("encoding getdevicelist!
  ");
  
  	status = decode_compound_hdr(xdr, &hdr);
  	if (status != 0)
  		goto out;
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
  	if (status != 0)
  		goto out;
  	status = decode_putfh(xdr);
  	if (status != 0)
  		goto out;
  	status = decode_getdevicelist(xdr, res->devlist);
  out:
  	return status;
  }
  
  /*
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6644
6645
   * Decode GETDEVINFO response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6646
6647
  static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp,
  				      struct xdr_stream *xdr,
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6648
6649
  				      struct nfs4_getdeviceinfo_res *res)
  {
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6650
6651
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6652
  	status = decode_compound_hdr(xdr, &hdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6653
6654
  	if (status != 0)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6655
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6656
6657
  	if (status != 0)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6658
  	status = decode_getdeviceinfo(xdr, res->pdev);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6659
6660
6661
6662
6663
6664
6665
  out:
  	return status;
  }
  
  /*
   * Decode LAYOUTGET response
   */
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6666
6667
  static int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp,
  				  struct xdr_stream *xdr,
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6668
6669
  				  struct nfs4_layoutget_res *res)
  {
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6670
6671
  	struct compound_hdr hdr;
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6672
  	status = decode_compound_hdr(xdr, &hdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6673
6674
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6675
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6676
6677
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6678
  	status = decode_putfh(xdr);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6679
6680
  	if (status)
  		goto out;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6681
  	status = decode_layoutget(xdr, rqstp, res);
b1f69b754   Andy Adamson   NFSv4.1: pnfs: ad...
6682
6683
6684
  out:
  	return status;
  }
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
6685
6686
  
  /*
cbe826036   Benny Halevy   pnfs: layoutreturn
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
   * Decode LAYOUTRETURN response
   */
  static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp,
  				     struct xdr_stream *xdr,
  				     struct nfs4_layoutreturn_res *res)
  {
  	struct compound_hdr hdr;
  	int status;
  
  	status = decode_compound_hdr(xdr, &hdr);
  	if (status)
  		goto out;
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
  	if (status)
  		goto out;
  	status = decode_putfh(xdr);
  	if (status)
  		goto out;
  	status = decode_layoutreturn(xdr, res);
  out:
  	return status;
  }
  
  /*
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
   * Decode LAYOUTCOMMIT response
   */
  static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
  				     struct xdr_stream *xdr,
  				     struct nfs4_layoutcommit_res *res)
  {
  	struct compound_hdr hdr;
  	int status;
  
  	status = decode_compound_hdr(xdr, &hdr);
  	if (status)
  		goto out;
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
  	if (status)
  		goto out;
  	status = decode_putfh(xdr);
  	if (status)
  		goto out;
  	status = decode_layoutcommit(xdr, rqstp, res);
  	if (status)
  		goto out;
6926afd19   Trond Myklebust   NFSv4: Save the o...
6732
  	decode_getfattr(xdr, res->fattr, res->server);
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
6733
6734
6735
  out:
  	return status;
  }
fca78d6d2   Bryan Schumaker   NFS: Add SECINFO_...
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
  
  /*
   * Decode SECINFO_NO_NAME response
   */
  static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp,
  					struct xdr_stream *xdr,
  					struct nfs4_secinfo_res *res)
  {
  	struct compound_hdr hdr;
  	int status;
  
  	status = decode_compound_hdr(xdr, &hdr);
  	if (status)
  		goto out;
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
  	if (status)
  		goto out;
  	status = decode_putrootfh(xdr);
  	if (status)
  		goto out;
  	status = decode_secinfo(xdr, res);
  out:
  	return status;
  }
7d9747947   Bryan Schumaker   NFS: Added TEST_S...
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
  
  /*
   * Decode TEST_STATEID response
   */
  static int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp,
  				     struct xdr_stream *xdr,
  				     struct nfs41_test_stateid_res *res)
  {
  	struct compound_hdr hdr;
  	int status;
  
  	status = decode_compound_hdr(xdr, &hdr);
  	if (status)
  		goto out;
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
  	if (status)
  		goto out;
  	status = decode_test_stateid(xdr, res);
  out:
  	return status;
  }
9aeda35fd   Bryan Schumaker   NFS: added FREE_S...
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
  
  /*
   * Decode FREE_STATEID response
   */
  static int nfs4_xdr_dec_free_stateid(struct rpc_rqst *rqstp,
  				     struct xdr_stream *xdr,
  				     struct nfs41_free_stateid_res *res)
  {
  	struct compound_hdr hdr;
  	int status;
  
  	status = decode_compound_hdr(xdr, &hdr);
  	if (status)
  		goto out;
  	status = decode_sequence(xdr, &res->seq_res, rqstp);
  	if (status)
  		goto out;
  	status = decode_free_stateid(xdr, res);
  out:
  	return status;
  }
99fe60d06   Benny Halevy   nfs41: exchange_i...
6802
  #endif /* CONFIG_NFS_V4_1 */
573c4e1ef   Chuck Lever   NFS: Simplify ->d...
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
  /**
   * nfs4_decode_dirent - Decode a single NFSv4 directory entry stored in
   *                      the local page cache.
   * @xdr: XDR stream where entry resides
   * @entry: buffer to fill in with entry data
   * @plus: boolean indicating whether this should be a readdirplus entry
   *
   * Returns zero if successful, otherwise a negative errno value is
   * returned.
   *
   * This function is not invoked during READDIR reply decoding, but
   * rather whenever an application invokes the getdents(2) system call
   * on a directory already in our cache.
   */
  int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
  		       int plus)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6819
  {
dae100c2b   Fred Isaman   pnfs: ask for lay...
6820
  	uint32_t bitmap[3] = {0};
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6821
  	uint32_t len;
babddc72a   Bryan Schumaker   NFS: decode_diren...
6822
6823
6824
  	__be32 *p = xdr_inline_decode(xdr, 4);
  	if (unlikely(!p))
  		goto out_overflow;
c08e76d0c   Chuck Lever   NFS: Micro-optimi...
6825
  	if (*p == xdr_zero) {
babddc72a   Bryan Schumaker   NFS: decode_diren...
6826
6827
6828
  		p = xdr_inline_decode(xdr, 4);
  		if (unlikely(!p))
  			goto out_overflow;
c08e76d0c   Chuck Lever   NFS: Micro-optimi...
6829
  		if (*p == xdr_zero)
573c4e1ef   Chuck Lever   NFS: Simplify ->d...
6830
  			return -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6831
  		entry->eof = 1;
573c4e1ef   Chuck Lever   NFS: Simplify ->d...
6832
  		return -EBADCOOKIE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6833
  	}
babddc72a   Bryan Schumaker   NFS: decode_diren...
6834
6835
6836
  	p = xdr_inline_decode(xdr, 12);
  	if (unlikely(!p))
  		goto out_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6837
6838
  	entry->prev_cookie = entry->cookie;
  	p = xdr_decode_hyper(p, &entry->cookie);
c08e76d0c   Chuck Lever   NFS: Micro-optimi...
6839
  	entry->len = be32_to_cpup(p);
babddc72a   Bryan Schumaker   NFS: decode_diren...
6840

9af8c222c   Trond Myklebust   NFSv4: Clean up n...
6841
  	p = xdr_inline_decode(xdr, entry->len);
babddc72a   Bryan Schumaker   NFS: decode_diren...
6842
6843
  	if (unlikely(!p))
  		goto out_overflow;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6844
  	entry->name = (const char *) p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6845
6846
6847
6848
6849
6850
6851
  
  	/*
  	 * In case the server doesn't return an inode number,
  	 * we fake one here.  (We don't use inode number 0,
  	 * since glibc seems to choke on it...)
  	 */
  	entry->ino = 1;
4f082222f   Trond Myklebust   NFSv4: nfs4_decod...
6852
  	entry->fattr->valid = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6853

9af8c222c   Trond Myklebust   NFSv4: Clean up n...
6854
6855
6856
6857
6858
  	if (decode_attr_bitmap(xdr, bitmap) < 0)
  		goto out_overflow;
  
  	if (decode_attr_length(xdr, &len, &p) < 0)
  		goto out_overflow;
573c4e1ef   Chuck Lever   NFS: Simplify ->d...
6859
  	if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh,
6926afd19   Trond Myklebust   NFSv4: Save the o...
6860
  					entry->server) < 0)
9af8c222c   Trond Myklebust   NFSv4: Clean up n...
6861
  		goto out_overflow;
28331a46d   Trond Myklebust   NFSv4: Ensure we ...
6862
6863
6864
  	if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
  		entry->ino = entry->fattr->mounted_on_fileid;
  	else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID)
9af8c222c   Trond Myklebust   NFSv4: Clean up n...
6865
  		entry->ino = entry->fattr->fileid;
0b26a0bf6   Trond Myklebust   NFS: Ensure we re...
6866
6867
6868
  	entry->d_type = DT_UNKNOWN;
  	if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE)
  		entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
573c4e1ef   Chuck Lever   NFS: Simplify ->d...
6869
  	return 0;
babddc72a   Bryan Schumaker   NFS: decode_diren...
6870
6871
6872
  
  out_overflow:
  	print_overflow_msg(__func__, xdr);
573c4e1ef   Chuck Lever   NFS: Simplify ->d...
6873
  	return -EAGAIN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
  }
  
  /*
   * We need to translate between nfs status return values and
   * the local errno values which may not be the same.
   */
  static struct {
  	int stat;
  	int errno;
  } nfs_errtbl[] = {
  	{ NFS4_OK,		0		},
856dff3d3   Benny Halevy   nfs: return negat...
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
  	{ NFS4ERR_PERM,		-EPERM		},
  	{ NFS4ERR_NOENT,	-ENOENT		},
  	{ NFS4ERR_IO,		-errno_NFSERR_IO},
  	{ NFS4ERR_NXIO,		-ENXIO		},
  	{ NFS4ERR_ACCESS,	-EACCES		},
  	{ NFS4ERR_EXIST,	-EEXIST		},
  	{ NFS4ERR_XDEV,		-EXDEV		},
  	{ NFS4ERR_NOTDIR,	-ENOTDIR	},
  	{ NFS4ERR_ISDIR,	-EISDIR		},
  	{ NFS4ERR_INVAL,	-EINVAL		},
  	{ NFS4ERR_FBIG,		-EFBIG		},
  	{ NFS4ERR_NOSPC,	-ENOSPC		},
  	{ NFS4ERR_ROFS,		-EROFS		},
  	{ NFS4ERR_MLINK,	-EMLINK		},
  	{ NFS4ERR_NAMETOOLONG,	-ENAMETOOLONG	},
  	{ NFS4ERR_NOTEMPTY,	-ENOTEMPTY	},
  	{ NFS4ERR_DQUOT,	-EDQUOT		},
  	{ NFS4ERR_STALE,	-ESTALE		},
  	{ NFS4ERR_BADHANDLE,	-EBADHANDLE	},
856dff3d3   Benny Halevy   nfs: return negat...
6904
6905
6906
  	{ NFS4ERR_BAD_COOKIE,	-EBADCOOKIE	},
  	{ NFS4ERR_NOTSUPP,	-ENOTSUPP	},
  	{ NFS4ERR_TOOSMALL,	-ETOOSMALL	},
fdcb45777   Trond Myklebust   NFS: Fix the mapp...
6907
  	{ NFS4ERR_SERVERFAULT,	-EREMOTEIO	},
856dff3d3   Benny Halevy   nfs: return negat...
6908
6909
  	{ NFS4ERR_BADTYPE,	-EBADTYPE	},
  	{ NFS4ERR_LOCKED,	-EAGAIN		},
856dff3d3   Benny Halevy   nfs: return negat...
6910
6911
6912
  	{ NFS4ERR_SYMLINK,	-ELOOP		},
  	{ NFS4ERR_OP_ILLEGAL,	-EOPNOTSUPP	},
  	{ NFS4ERR_DEADLOCK,	-EDEADLK	},
856dff3d3   Benny Halevy   nfs: return negat...
6913
  	{ -1,			-EIO		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6914
6915
6916
6917
6918
6919
6920
  };
  
  /*
   * Convert an NFS error code to a local one.
   * This one is used jointly by NFSv2 and NFSv3.
   */
  static int
0a8ea4372   David Howells   NFS: Disambiguate...
6921
  nfs4_stat_to_errno(int stat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6922
6923
6924
6925
6926
6927
6928
6929
  {
  	int i;
  	for (i = 0; nfs_errtbl[i].stat != -1; i++) {
  		if (nfs_errtbl[i].stat == stat)
  			return nfs_errtbl[i].errno;
  	}
  	if (stat <= 10000 || stat > 10100) {
  		/* The server is looney tunes. */
fdcb45777   Trond Myklebust   NFS: Fix the mapp...
6930
  		return -EREMOTEIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6931
6932
6933
6934
6935
6936
  	}
  	/* If we cannot translate the error, the recovery routines should
  	 * handle it.
  	 * Note: remaining NFSv4 error codes have values > 10000, so should
  	 * not conflict with native Linux error codes.
  	 */
856dff3d3   Benny Halevy   nfs: return negat...
6937
  	return -stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6938
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6939
6940
6941
  #define PROC(proc, argtype, restype)				\
  [NFSPROC4_CLNT_##proc] = {					\
  	.p_proc   = NFSPROC4_COMPOUND,				\
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
6942
  	.p_encode = (kxdreproc_t)nfs4_xdr_##argtype,		\
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
6943
  	.p_decode = (kxdrdproc_t)nfs4_xdr_##restype,		\
2bea90d43   Chuck Lever   SUNRPC: RPC buffe...
6944
6945
  	.p_arglen = NFS4_##argtype##_sz,			\
  	.p_replen = NFS4_##restype##_sz,			\
cc0175c1d   Chuck Lever   SUNRPC: display h...
6946
6947
  	.p_statidx = NFSPROC4_CLNT_##proc,			\
  	.p_name   = #proc,					\
05d564fe0   Andy Adamson   NFS: fix tabs in ...
6948
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6949
6950
  
  struct rpc_procinfo	nfs4_procedures[] = {
7d93bd71c   Chuck Lever   NFS: Repair white...
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
  	PROC(READ,		enc_read,		dec_read),
  	PROC(WRITE,		enc_write,		dec_write),
  	PROC(COMMIT,		enc_commit,		dec_commit),
  	PROC(OPEN,		enc_open,		dec_open),
  	PROC(OPEN_CONFIRM,	enc_open_confirm,	dec_open_confirm),
  	PROC(OPEN_NOATTR,	enc_open_noattr,	dec_open_noattr),
  	PROC(OPEN_DOWNGRADE,	enc_open_downgrade,	dec_open_downgrade),
  	PROC(CLOSE,		enc_close,		dec_close),
  	PROC(SETATTR,		enc_setattr,		dec_setattr),
  	PROC(FSINFO,		enc_fsinfo,		dec_fsinfo),
  	PROC(RENEW,		enc_renew,		dec_renew),
  	PROC(SETCLIENTID,	enc_setclientid,	dec_setclientid),
  	PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm),
  	PROC(LOCK,		enc_lock,		dec_lock),
  	PROC(LOCKT,		enc_lockt,		dec_lockt),
  	PROC(LOCKU,		enc_locku,		dec_locku),
  	PROC(ACCESS,		enc_access,		dec_access),
  	PROC(GETATTR,		enc_getattr,		dec_getattr),
  	PROC(LOOKUP,		enc_lookup,		dec_lookup),
  	PROC(LOOKUP_ROOT,	enc_lookup_root,	dec_lookup_root),
  	PROC(REMOVE,		enc_remove,		dec_remove),
  	PROC(RENAME,		enc_rename,		dec_rename),
  	PROC(LINK,		enc_link,		dec_link),
  	PROC(SYMLINK,		enc_symlink,		dec_symlink),
  	PROC(CREATE,		enc_create,		dec_create),
  	PROC(PATHCONF,		enc_pathconf,		dec_pathconf),
  	PROC(STATFS,		enc_statfs,		dec_statfs),
  	PROC(READLINK,		enc_readlink,		dec_readlink),
  	PROC(READDIR,		enc_readdir,		dec_readdir),
  	PROC(SERVER_CAPS,	enc_server_caps,	dec_server_caps),
  	PROC(DELEGRETURN,	enc_delegreturn,	dec_delegreturn),
  	PROC(GETACL,		enc_getacl,		dec_getacl),
  	PROC(SETACL,		enc_setacl,		dec_setacl),
  	PROC(FS_LOCATIONS,	enc_fs_locations,	dec_fs_locations),
  	PROC(RELEASE_LOCKOWNER,	enc_release_lockowner,	dec_release_lockowner),
5a5ea0d48   Bryan Schumaker   NFS: Add secinfo ...
6986
  	PROC(SECINFO,		enc_secinfo,		dec_secinfo),
99fe60d06   Benny Halevy   nfs41: exchange_i...
6987
  #if defined(CONFIG_NFS_V4_1)
7d93bd71c   Chuck Lever   NFS: Repair white...
6988
6989
6990
6991
6992
6993
6994
6995
  	PROC(EXCHANGE_ID,	enc_exchange_id,	dec_exchange_id),
  	PROC(CREATE_SESSION,	enc_create_session,	dec_create_session),
  	PROC(DESTROY_SESSION,	enc_destroy_session,	dec_destroy_session),
  	PROC(SEQUENCE,		enc_sequence,		dec_sequence),
  	PROC(GET_LEASE_TIME,	enc_get_lease_time,	dec_get_lease_time),
  	PROC(RECLAIM_COMPLETE,	enc_reclaim_complete,	dec_reclaim_complete),
  	PROC(GETDEVICEINFO,	enc_getdeviceinfo,	dec_getdeviceinfo),
  	PROC(LAYOUTGET,		enc_layoutget,		dec_layoutget),
863a3c6c6   Andy Adamson   NFSv4.1: layoutco...
6996
  	PROC(LAYOUTCOMMIT,	enc_layoutcommit,	dec_layoutcommit),
cbe826036   Benny Halevy   pnfs: layoutreturn
6997
  	PROC(LAYOUTRETURN,	enc_layoutreturn,	dec_layoutreturn),
fca78d6d2   Bryan Schumaker   NFS: Add SECINFO_...
6998
  	PROC(SECINFO_NO_NAME,	enc_secinfo_no_name,	dec_secinfo_no_name),
7d9747947   Bryan Schumaker   NFS: Added TEST_S...
6999
  	PROC(TEST_STATEID,	enc_test_stateid,	dec_test_stateid),
9aeda35fd   Bryan Schumaker   NFS: added FREE_S...
7000
  	PROC(FREE_STATEID,	enc_free_stateid,	dec_free_stateid),
7f11d8d38   Andy Adamson   pnfs: GETDEVICELIST
7001
  	PROC(GETDEVICELIST,	enc_getdevicelist,	dec_getdevicelist),
99fe60d06   Benny Halevy   nfs41: exchange_i...
7002
  #endif /* CONFIG_NFS_V4_1 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7003
7004
7005
7006
  };
  
  struct rpc_version		nfs_version4 = {
  	.number			= 4,
e8c96f8c2   Tobias Klauser   [PATCH] fs: Use A...
7007
  	.nrprocs		= ARRAY_SIZE(nfs4_procedures),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7008
7009
7010
7011
7012
7013
7014
7015
  	.procs			= nfs4_procedures
  };
  
  /*
   * Local variables:
   *  c-basic-offset: 8
   * End:
   */