NFS: Don't use vm_map_ram() in readdir
[deliverable/linux.git] / fs / nfs / nfs3xdr.c
CommitLineData
1da177e4
LT
1/*
2 * linux/fs/nfs/nfs3xdr.c
3 *
4 * XDR functions to encode/decode NFSv3 RPC arguments and results.
5 *
6 * Copyright (C) 1996, 1997 Olaf Kirch
7 */
8
9#include <linux/param.h>
10#include <linux/time.h>
11#include <linux/mm.h>
1da177e4
LT
12#include <linux/errno.h>
13#include <linux/string.h>
14#include <linux/in.h>
15#include <linux/pagemap.h>
16#include <linux/proc_fs.h>
17#include <linux/kdev_t.h>
18#include <linux/sunrpc/clnt.h>
19#include <linux/nfs.h>
20#include <linux/nfs3.h>
21#include <linux/nfs_fs.h>
b7fa0554 22#include <linux/nfsacl.h>
f7b422b1 23#include "internal.h"
1da177e4
LT
24
25#define NFSDBG_FACILITY NFSDBG_XDR
26
27/* Mapping from NFS error code to "errno" error code. */
28#define errno_NFSERR_IO EIO
29
1da177e4
LT
30/*
31 * Declare the space requirements for NFS arguments and replies as
32 * number of 32bit-words
33 */
34#define NFS3_fhandle_sz (1+16)
35#define NFS3_fh_sz (NFS3_fhandle_sz) /* shorthand */
36#define NFS3_sattr_sz (15)
37#define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2))
38#define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2))
39#define NFS3_fattr_sz (21)
40#define NFS3_wcc_attr_sz (6)
41#define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz)
42#define NFS3_post_op_attr_sz (1+NFS3_fattr_sz)
43#define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz)
44#define NFS3_fsstat_sz
45#define NFS3_fsinfo_sz
46#define NFS3_pathconf_sz
47#define NFS3_entry_sz (NFS3_filename_sz+3)
48
49#define NFS3_sattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3)
50#define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz)
4fdc17b2 51#define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz)
1da177e4
LT
52#define NFS3_accessargs_sz (NFS3_fh_sz+1)
53#define NFS3_readlinkargs_sz (NFS3_fh_sz)
54#define NFS3_readargs_sz (NFS3_fh_sz+3)
55#define NFS3_writeargs_sz (NFS3_fh_sz+5)
56#define NFS3_createargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
57#define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz)
94a6d753 58#define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz)
1da177e4
LT
59#define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz)
60#define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz)
61#define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz)
62#define NFS3_readdirargs_sz (NFS3_fh_sz+2)
63#define NFS3_commitargs_sz (NFS3_fh_sz+3)
64
65#define NFS3_attrstat_sz (1+NFS3_fattr_sz)
66#define NFS3_wccstat_sz (1+NFS3_wcc_data_sz)
4fdc17b2 67#define NFS3_removeres_sz (NFS3_wccstat_sz)
1da177e4
LT
68#define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz))
69#define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1)
70#define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1)
71#define NFS3_readres_sz (1+NFS3_post_op_attr_sz+3)
72#define NFS3_writeres_sz (1+NFS3_wcc_data_sz+4)
73#define NFS3_createres_sz (1+NFS3_fh_sz+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
74#define NFS3_renameres_sz (1+(2 * NFS3_wcc_data_sz))
75#define NFS3_linkres_sz (1+NFS3_post_op_attr_sz+NFS3_wcc_data_sz)
76#define NFS3_readdirres_sz (1+NFS3_post_op_attr_sz+2)
77#define NFS3_fsstatres_sz (1+NFS3_post_op_attr_sz+13)
78#define NFS3_fsinfores_sz (1+NFS3_post_op_attr_sz+12)
79#define NFS3_pathconfres_sz (1+NFS3_post_op_attr_sz+6)
80#define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2)
81
b7fa0554 82#define ACL3_getaclargs_sz (NFS3_fh_sz+1)
ae46141f
TM
83#define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \
84 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
85#define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \
86 XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
b7fa0554
AG
87#define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
88
1da177e4
LT
89/*
90 * Map file type to S_IFMT bits
91 */
bca79478
TM
92static const umode_t nfs_type2fmt[] = {
93 [NF3BAD] = 0,
94 [NF3REG] = S_IFREG,
95 [NF3DIR] = S_IFDIR,
96 [NF3BLK] = S_IFBLK,
97 [NF3CHR] = S_IFCHR,
98 [NF3LNK] = S_IFLNK,
99 [NF3SOCK] = S_IFSOCK,
100 [NF3FIFO] = S_IFIFO,
1da177e4
LT
101};
102
babddc72
BS
103static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
104{
105 dprintk("nfs: %s: prematurely hit end of receive buffer. "
106 "Remaining buffer length is %tu words.\n",
107 func, xdr->end - xdr->p);
108}
109
1da177e4
LT
110/*
111 * Common NFS XDR functions as inlines
112 */
d61005a6 113static inline __be32 *
4fdc17b2 114xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh)
1da177e4
LT
115{
116 return xdr_encode_array(p, fh->data, fh->size);
117}
118
d61005a6
AV
119static inline __be32 *
120xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh)
1da177e4
LT
121{
122 if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) {
123 memcpy(fh->data, p, fh->size);
124 return p + XDR_QUADLEN(fh->size);
125 }
126 return NULL;
127}
128
babddc72
BS
129static inline __be32 *
130xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh)
131{
132 __be32 *p;
133 p = xdr_inline_decode(xdr, 4);
134 if (unlikely(!p))
135 goto out_overflow;
136 fh->size = ntohl(*p++);
137
138 if (fh->size <= NFS3_FHSIZE) {
139 p = xdr_inline_decode(xdr, fh->size);
140 if (unlikely(!p))
141 goto out_overflow;
142 memcpy(fh->data, p, fh->size);
143 return p + XDR_QUADLEN(fh->size);
144 }
145 return NULL;
146
147out_overflow:
148 print_overflow_msg(__func__, xdr);
149 return ERR_PTR(-EIO);
150}
151
1da177e4
LT
152/*
153 * Encode/decode time.
154 */
d61005a6
AV
155static inline __be32 *
156xdr_encode_time3(__be32 *p, struct timespec *timep)
1da177e4
LT
157{
158 *p++ = htonl(timep->tv_sec);
159 *p++ = htonl(timep->tv_nsec);
160 return p;
161}
162
d61005a6
AV
163static inline __be32 *
164xdr_decode_time3(__be32 *p, struct timespec *timep)
1da177e4
LT
165{
166 timep->tv_sec = ntohl(*p++);
167 timep->tv_nsec = ntohl(*p++);
168 return p;
169}
170
d61005a6
AV
171static __be32 *
172xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
173{
174 unsigned int type, major, minor;
bca79478 175 umode_t fmode;
1da177e4
LT
176
177 type = ntohl(*p++);
bca79478
TM
178 if (type > NF3FIFO)
179 type = NF3NON;
180 fmode = nfs_type2fmt[type];
1da177e4
LT
181 fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode;
182 fattr->nlink = ntohl(*p++);
183 fattr->uid = ntohl(*p++);
184 fattr->gid = ntohl(*p++);
185 p = xdr_decode_hyper(p, &fattr->size);
186 p = xdr_decode_hyper(p, &fattr->du.nfs3.used);
187
188 /* Turn remote device info into Linux-specific dev_t */
189 major = ntohl(*p++);
190 minor = ntohl(*p++);
191 fattr->rdev = MKDEV(major, minor);
192 if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
193 fattr->rdev = 0;
194
8b4bdcf8
TM
195 p = xdr_decode_hyper(p, &fattr->fsid.major);
196 fattr->fsid.minor = 0;
1da177e4
LT
197 p = xdr_decode_hyper(p, &fattr->fileid);
198 p = xdr_decode_time3(p, &fattr->atime);
199 p = xdr_decode_time3(p, &fattr->mtime);
200 p = xdr_decode_time3(p, &fattr->ctime);
201
202 /* Update the mode bits */
9e6e70f8 203 fattr->valid |= NFS_ATTR_FATTR_V3;
1da177e4
LT
204 return p;
205}
206
d61005a6
AV
207static inline __be32 *
208xdr_encode_sattr(__be32 *p, struct iattr *attr)
1da177e4
LT
209{
210 if (attr->ia_valid & ATTR_MODE) {
211 *p++ = xdr_one;
cf3fff54 212 *p++ = htonl(attr->ia_mode & S_IALLUGO);
1da177e4
LT
213 } else {
214 *p++ = xdr_zero;
215 }
216 if (attr->ia_valid & ATTR_UID) {
217 *p++ = xdr_one;
218 *p++ = htonl(attr->ia_uid);
219 } else {
220 *p++ = xdr_zero;
221 }
222 if (attr->ia_valid & ATTR_GID) {
223 *p++ = xdr_one;
224 *p++ = htonl(attr->ia_gid);
225 } else {
226 *p++ = xdr_zero;
227 }
228 if (attr->ia_valid & ATTR_SIZE) {
229 *p++ = xdr_one;
230 p = xdr_encode_hyper(p, (__u64) attr->ia_size);
231 } else {
232 *p++ = xdr_zero;
233 }
234 if (attr->ia_valid & ATTR_ATIME_SET) {
235 *p++ = xdr_two;
236 p = xdr_encode_time3(p, &attr->ia_atime);
237 } else if (attr->ia_valid & ATTR_ATIME) {
238 *p++ = xdr_one;
239 } else {
240 *p++ = xdr_zero;
241 }
242 if (attr->ia_valid & ATTR_MTIME_SET) {
243 *p++ = xdr_two;
244 p = xdr_encode_time3(p, &attr->ia_mtime);
245 } else if (attr->ia_valid & ATTR_MTIME) {
246 *p++ = xdr_one;
247 } else {
248 *p++ = xdr_zero;
249 }
250 return p;
251}
252
d61005a6
AV
253static inline __be32 *
254xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
255{
256 p = xdr_decode_hyper(p, &fattr->pre_size);
257 p = xdr_decode_time3(p, &fattr->pre_mtime);
258 p = xdr_decode_time3(p, &fattr->pre_ctime);
9e6e70f8
TM
259 fattr->valid |= NFS_ATTR_FATTR_PRESIZE
260 | NFS_ATTR_FATTR_PREMTIME
261 | NFS_ATTR_FATTR_PRECTIME;
1da177e4
LT
262 return p;
263}
264
d61005a6
AV
265static inline __be32 *
266xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
267{
268 if (*p++)
269 p = xdr_decode_fattr(p, fattr);
270 return p;
271}
272
babddc72
BS
273static inline __be32 *
274xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr)
275{
276 __be32 *p;
277
278 p = xdr_inline_decode(xdr, 4);
279 if (unlikely(!p))
280 goto out_overflow;
281 if (ntohl(*p++)) {
282 p = xdr_inline_decode(xdr, 84);
283 if (unlikely(!p))
284 goto out_overflow;
285 p = xdr_decode_fattr(p, fattr);
286 }
287 return p;
288out_overflow:
289 print_overflow_msg(__func__, xdr);
290 return ERR_PTR(-EIO);
291}
292
d61005a6
AV
293static inline __be32 *
294xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
295{
296 if (*p++)
297 return xdr_decode_wcc_attr(p, fattr);
298 return p;
299}
300
301
d61005a6
AV
302static inline __be32 *
303xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
304{
305 p = xdr_decode_pre_op_attr(p, fattr);
306 return xdr_decode_post_op_attr(p, fattr);
307}
308
309/*
310 * NFS encode functions
311 */
312
313/*
314 * Encode file handle argument
315 */
316static int
d61005a6 317nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
1da177e4
LT
318{
319 p = xdr_encode_fhandle(p, fh);
320 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
321 return 0;
322}
323
324/*
325 * Encode SETATTR arguments
326 */
327static int
d61005a6 328nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args)
1da177e4
LT
329{
330 p = xdr_encode_fhandle(p, args->fh);
331 p = xdr_encode_sattr(p, args->sattr);
332 *p++ = htonl(args->guard);
333 if (args->guard)
334 p = xdr_encode_time3(p, &args->guardtime);
335 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
336 return 0;
337}
338
339/*
340 * Encode directory ops argument
341 */
342static int
d61005a6 343nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args)
1da177e4
LT
344{
345 p = xdr_encode_fhandle(p, args->fh);
346 p = xdr_encode_array(p, args->name, args->len);
347 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
348 return 0;
349}
350
4fdc17b2
TM
351/*
352 * Encode REMOVE argument
353 */
354static int
355nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
356{
357 p = xdr_encode_fhandle(p, args->fh);
358 p = xdr_encode_array(p, args->name.name, args->name.len);
359 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
360 return 0;
361}
362
1da177e4
LT
363/*
364 * Encode access() argument
365 */
366static int
d61005a6 367nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args)
1da177e4
LT
368{
369 p = xdr_encode_fhandle(p, args->fh);
370 *p++ = htonl(args->access);
371 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
372 return 0;
373}
374
375/*
376 * Arguments to a READ call. Since we read data directly into the page
377 * cache, we also set up the reply iovec here so that iov[1] points
378 * exactly to the page we want to fetch.
379 */
380static int
d61005a6 381nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
1da177e4 382{
a17c2153 383 struct rpc_auth *auth = req->rq_cred->cr_auth;
1da177e4
LT
384 unsigned int replen;
385 u32 count = args->count;
386
387 p = xdr_encode_fhandle(p, args->fh);
388 p = xdr_encode_hyper(p, args->offset);
389 *p++ = htonl(count);
390 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
391
392 /* Inline the page array */
393 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2;
394 xdr_inline_pages(&req->rq_rcv_buf, replen,
395 args->pages, args->pgbase, count);
4f22ccc3 396 req->rq_rcv_buf.flags |= XDRBUF_READ;
1da177e4
LT
397 return 0;
398}
399
400/*
401 * Write arguments. Splice the buffer to be written into the iovec.
402 */
403static int
d61005a6 404nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
1da177e4
LT
405{
406 struct xdr_buf *sndbuf = &req->rq_snd_buf;
407 u32 count = args->count;
408
409 p = xdr_encode_fhandle(p, args->fh);
410 p = xdr_encode_hyper(p, args->offset);
411 *p++ = htonl(count);
412 *p++ = htonl(args->stable);
413 *p++ = htonl(count);
414 sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
415
416 /* Copy the page array */
417 xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
4f22ccc3 418 sndbuf->flags |= XDRBUF_WRITE;
1da177e4
LT
419 return 0;
420}
421
422/*
423 * Encode CREATE arguments
424 */
425static int
d61005a6 426nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args)
1da177e4
LT
427{
428 p = xdr_encode_fhandle(p, args->fh);
429 p = xdr_encode_array(p, args->name, args->len);
430
431 *p++ = htonl(args->createmode);
432 if (args->createmode == NFS3_CREATE_EXCLUSIVE) {
433 *p++ = args->verifier[0];
434 *p++ = args->verifier[1];
435 } else
436 p = xdr_encode_sattr(p, args->sattr);
437
438 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
439 return 0;
440}
441
442/*
443 * Encode MKDIR arguments
444 */
445static int
d61005a6 446nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args)
1da177e4
LT
447{
448 p = xdr_encode_fhandle(p, args->fh);
449 p = xdr_encode_array(p, args->name, args->len);
450 p = xdr_encode_sattr(p, args->sattr);
451 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
452 return 0;
453}
454
455/*
456 * Encode SYMLINK arguments
457 */
458static int
d61005a6 459nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args)
1da177e4
LT
460{
461 p = xdr_encode_fhandle(p, args->fromfh);
462 p = xdr_encode_array(p, args->fromname, args->fromlen);
463 p = xdr_encode_sattr(p, args->sattr);
94a6d753 464 *p++ = htonl(args->pathlen);
1da177e4 465 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
94a6d753
CL
466
467 /* Copy the page */
468 xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen);
1da177e4
LT
469 return 0;
470}
471
472/*
473 * Encode MKNOD arguments
474 */
475static int
d61005a6 476nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args)
1da177e4
LT
477{
478 p = xdr_encode_fhandle(p, args->fh);
479 p = xdr_encode_array(p, args->name, args->len);
480 *p++ = htonl(args->type);
481 p = xdr_encode_sattr(p, args->sattr);
482 if (args->type == NF3CHR || args->type == NF3BLK) {
483 *p++ = htonl(MAJOR(args->rdev));
484 *p++ = htonl(MINOR(args->rdev));
485 }
486
487 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
488 return 0;
489}
490
491/*
492 * Encode RENAME arguments
493 */
494static int
920769f0 495nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
1da177e4 496{
920769f0
JL
497 p = xdr_encode_fhandle(p, args->old_dir);
498 p = xdr_encode_array(p, args->old_name->name, args->old_name->len);
499 p = xdr_encode_fhandle(p, args->new_dir);
500 p = xdr_encode_array(p, args->new_name->name, args->new_name->len);
1da177e4
LT
501 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
502 return 0;
503}
504
505/*
506 * Encode LINK arguments
507 */
508static int
d61005a6 509nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args)
1da177e4
LT
510{
511 p = xdr_encode_fhandle(p, args->fromfh);
512 p = xdr_encode_fhandle(p, args->tofh);
513 p = xdr_encode_array(p, args->toname, args->tolen);
514 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
515 return 0;
516}
517
518/*
519 * Encode arguments to readdir call
520 */
521static int
d61005a6 522nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args)
1da177e4 523{
a17c2153 524 struct rpc_auth *auth = req->rq_cred->cr_auth;
1da177e4
LT
525 unsigned int replen;
526 u32 count = args->count;
527
528 p = xdr_encode_fhandle(p, args->fh);
529 p = xdr_encode_hyper(p, args->cookie);
530 *p++ = args->verf[0];
531 *p++ = args->verf[1];
532 if (args->plus) {
533 /* readdirplus: need dircount + buffer size.
534 * We just make sure we make dircount big enough */
535 *p++ = htonl(count >> 3);
536 }
537 *p++ = htonl(count);
538 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
539
540 /* Inline the page array */
541 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readdirres_sz) << 2;
542 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
543 return 0;
544}
545
546/*
547 * Decode the result of a readdir call.
548 * We just check for syntactical correctness.
549 */
550static int
d61005a6 551nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res)
1da177e4
LT
552{
553 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
554 struct kvec *iov = rcvbuf->head;
555 struct page **page;
c957c526 556 size_t hdrlen;
afa8ccc9 557 u32 recvd, pglen;
ac396128 558 int status;
1da177e4
LT
559
560 status = ntohl(*p++);
561 /* Decode post_op_attrs */
562 p = xdr_decode_post_op_attr(p, res->dir_attr);
563 if (status)
856dff3d 564 return nfs_stat_to_errno(status);
1da177e4
LT
565 /* Decode verifier cookie */
566 if (res->verf) {
567 res->verf[0] = *p++;
568 res->verf[1] = *p++;
569 } else {
570 p += 2;
571 }
572
573 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
574 if (iov->iov_len < hdrlen) {
fe82a183 575 dprintk("NFS: READDIR reply header overflowed:"
c957c526 576 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1da177e4
LT
577 return -errno_NFSERR_IO;
578 } else if (iov->iov_len != hdrlen) {
579 dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
580 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
581 }
582
583 pglen = rcvbuf->page_len;
584 recvd = rcvbuf->len - hdrlen;
585 if (pglen > recvd)
586 pglen = recvd;
587 page = rcvbuf->pages;
643f8111 588
ac396128 589 return pglen;
1da177e4
LT
590}
591
0dbb4c67 592__be32 *
82f2e547 593nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus)
1da177e4 594{
babddc72 595 __be32 *p;
1da177e4
LT
596 struct nfs_entry old = *entry;
597
babddc72
BS
598 p = xdr_inline_decode(xdr, 4);
599 if (unlikely(!p))
600 goto out_overflow;
601 if (!ntohl(*p++)) {
602 p = xdr_inline_decode(xdr, 4);
603 if (unlikely(!p))
604 goto out_overflow;
605 if (!ntohl(*p++))
1da177e4
LT
606 return ERR_PTR(-EAGAIN);
607 entry->eof = 1;
608 return ERR_PTR(-EBADCOOKIE);
609 }
610
babddc72
BS
611 p = xdr_inline_decode(xdr, 12);
612 if (unlikely(!p))
613 goto out_overflow;
1da177e4
LT
614 p = xdr_decode_hyper(p, &entry->ino);
615 entry->len = ntohl(*p++);
babddc72
BS
616
617 p = xdr_inline_decode(xdr, entry->len + 8);
618 if (unlikely(!p))
619 goto out_overflow;
1da177e4
LT
620 entry->name = (const char *) p;
621 p += XDR_QUADLEN(entry->len);
622 entry->prev_cookie = entry->cookie;
623 p = xdr_decode_hyper(p, &entry->cookie);
624
0b26a0bf 625 entry->d_type = DT_UNKNOWN;
1da177e4
LT
626 if (plus) {
627 entry->fattr->valid = 0;
babddc72
BS
628 p = xdr_decode_post_op_attr_stream(xdr, entry->fattr);
629 if (IS_ERR(p))
630 goto out_overflow_exit;
0b26a0bf 631 entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
1da177e4 632 /* In fact, a post_op_fh3: */
babddc72
BS
633 p = xdr_inline_decode(xdr, 4);
634 if (unlikely(!p))
635 goto out_overflow;
1da177e4 636 if (*p++) {
babddc72
BS
637 p = xdr_decode_fhandle_stream(xdr, entry->fh);
638 if (IS_ERR(p))
639 goto out_overflow_exit;
1da177e4
LT
640 /* Ugh -- server reply was truncated */
641 if (p == NULL) {
642 dprintk("NFS: FH truncated\n");
643 *entry = old;
644 return ERR_PTR(-EAGAIN);
645 }
646 } else
647 memset((u8*)(entry->fh), 0, sizeof(*entry->fh));
648 }
649
1da177e4 650 return p;
babddc72
BS
651
652out_overflow:
653 print_overflow_msg(__func__, xdr);
654out_overflow_exit:
463a376e 655 return ERR_PTR(-EAGAIN);
1da177e4
LT
656}
657
658/*
659 * Encode COMMIT arguments
660 */
661static int
d61005a6 662nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
1da177e4
LT
663{
664 p = xdr_encode_fhandle(p, args->fh);
665 p = xdr_encode_hyper(p, args->offset);
666 *p++ = htonl(args->count);
667 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
668 return 0;
669}
670
b7fa0554
AG
671#ifdef CONFIG_NFS_V3_ACL
672/*
673 * Encode GETACL arguments
674 */
675static int
d61005a6 676nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p,
b7fa0554
AG
677 struct nfs3_getaclargs *args)
678{
a17c2153 679 struct rpc_auth *auth = req->rq_cred->cr_auth;
b7fa0554
AG
680 unsigned int replen;
681
682 p = xdr_encode_fhandle(p, args->fh);
683 *p++ = htonl(args->mask);
684 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
685
686 if (args->mask & (NFS_ACL | NFS_DFACL)) {
687 /* Inline the page array */
688 replen = (RPC_REPHDRSIZE + auth->au_rslack +
689 ACL3_getaclres_sz) << 2;
690 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0,
691 NFSACL_MAXPAGES << PAGE_SHIFT);
692 }
693 return 0;
694}
695
696/*
697 * Encode SETACL arguments
698 */
699static int
d61005a6 700nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p,
b7fa0554
AG
701 struct nfs3_setaclargs *args)
702{
703 struct xdr_buf *buf = &req->rq_snd_buf;
ae46141f
TM
704 unsigned int base;
705 int err;
b7fa0554
AG
706
707 p = xdr_encode_fhandle(p, NFS_FH(args->inode));
708 *p++ = htonl(args->mask);
ae46141f
TM
709 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
710 base = req->rq_slen;
711
712 if (args->npages != 0)
713 xdr_encode_pages(buf, args->pages, 0, args->len);
714 else
83404372
TM
715 req->rq_slen = xdr_adjust_iovec(req->rq_svec,
716 p + XDR_QUADLEN(args->len));
b7fa0554
AG
717
718 err = nfsacl_encode(buf, base, args->inode,
719 (args->mask & NFS_ACL) ?
720 args->acl_access : NULL, 1, 0);
721 if (err > 0)
722 err = nfsacl_encode(buf, base + err, args->inode,
723 (args->mask & NFS_DFACL) ?
724 args->acl_default : NULL, 1,
725 NFS_ACL_DEFAULT);
726 return (err > 0) ? 0 : err;
727}
728#endif /* CONFIG_NFS_V3_ACL */
729
1da177e4
LT
730/*
731 * NFS XDR decode functions
732 */
733
734/*
735 * Decode attrstat reply.
736 */
737static int
d61005a6 738nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
739{
740 int status;
741
742 if ((status = ntohl(*p++)))
856dff3d 743 return nfs_stat_to_errno(status);
1da177e4
LT
744 xdr_decode_fattr(p, fattr);
745 return 0;
746}
747
748/*
749 * Decode status+wcc_data reply
750 * SATTR, REMOVE, RMDIR
751 */
752static int
d61005a6 753nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
754{
755 int status;
756
757 if ((status = ntohl(*p++)))
856dff3d 758 status = nfs_stat_to_errno(status);
1da177e4
LT
759 xdr_decode_wcc_data(p, fattr);
760 return status;
761}
762
4fdc17b2
TM
763static int
764nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res)
765{
d346890b 766 return nfs3_xdr_wccstat(req, p, res->dir_attr);
4fdc17b2
TM
767}
768
1da177e4
LT
769/*
770 * Decode LOOKUP reply
771 */
772static int
d61005a6 773nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1da177e4
LT
774{
775 int status;
776
777 if ((status = ntohl(*p++))) {
856dff3d 778 status = nfs_stat_to_errno(status);
1da177e4
LT
779 } else {
780 if (!(p = xdr_decode_fhandle(p, res->fh)))
781 return -errno_NFSERR_IO;
782 p = xdr_decode_post_op_attr(p, res->fattr);
783 }
784 xdr_decode_post_op_attr(p, res->dir_attr);
785 return status;
786}
787
788/*
789 * Decode ACCESS reply
790 */
791static int
d61005a6 792nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res)
1da177e4
LT
793{
794 int status = ntohl(*p++);
795
796 p = xdr_decode_post_op_attr(p, res->fattr);
797 if (status)
856dff3d 798 return nfs_stat_to_errno(status);
1da177e4
LT
799 res->access = ntohl(*p++);
800 return 0;
801}
802
803static int
d61005a6 804nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args)
1da177e4 805{
a17c2153 806 struct rpc_auth *auth = req->rq_cred->cr_auth;
1da177e4
LT
807 unsigned int replen;
808
809 p = xdr_encode_fhandle(p, args->fh);
810 req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
811
812 /* Inline the page array */
813 replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readlinkres_sz) << 2;
814 xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
815 return 0;
816}
817
818/*
819 * Decode READLINK reply
820 */
821static int
d61005a6 822nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
1da177e4
LT
823{
824 struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
825 struct kvec *iov = rcvbuf->head;
c957c526
CL
826 size_t hdrlen;
827 u32 len, recvd;
1da177e4
LT
828 int status;
829
830 status = ntohl(*p++);
831 p = xdr_decode_post_op_attr(p, fattr);
832
833 if (status != 0)
856dff3d 834 return nfs_stat_to_errno(status);
1da177e4
LT
835
836 /* Convert length of symlink */
837 len = ntohl(*p++);
c957c526 838 if (len >= rcvbuf->page_len) {
fe82a183 839 dprintk("nfs: server returned giant symlink!\n");
1da177e4
LT
840 return -ENAMETOOLONG;
841 }
842
843 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
844 if (iov->iov_len < hdrlen) {
fe82a183 845 dprintk("NFS: READLINK reply header overflowed:"
c957c526 846 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1da177e4
LT
847 return -errno_NFSERR_IO;
848 } else if (iov->iov_len != hdrlen) {
fe82a183
CL
849 dprintk("NFS: READLINK header is short. "
850 "iovec will be shifted.\n");
1da177e4
LT
851 xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
852 }
853 recvd = req->rq_rcv_buf.len - hdrlen;
854 if (recvd < len) {
fe82a183 855 dprintk("NFS: server cheating in readlink reply: "
1da177e4
LT
856 "count %u > recvd %u\n", len, recvd);
857 return -EIO;
858 }
859
b4687da7 860 xdr_terminate_string(rcvbuf, len);
1da177e4
LT
861 return 0;
862}
863
864/*
865 * Decode READ reply
866 */
867static int
d61005a6 868nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
1da177e4
LT
869{
870 struct kvec *iov = req->rq_rcv_buf.head;
c957c526
CL
871 size_t hdrlen;
872 u32 count, ocount, recvd;
873 int status;
1da177e4
LT
874
875 status = ntohl(*p++);
876 p = xdr_decode_post_op_attr(p, res->fattr);
877
878 if (status != 0)
856dff3d 879 return nfs_stat_to_errno(status);
1da177e4 880
c957c526 881 /* Decode reply count and EOF flag. NFSv3 is somewhat redundant
1da177e4
LT
882 * in that it puts the count both in the res struct and in the
883 * opaque data count. */
884 count = ntohl(*p++);
885 res->eof = ntohl(*p++);
886 ocount = ntohl(*p++);
887
888 if (ocount != count) {
fe82a183 889 dprintk("NFS: READ count doesn't match RPC opaque count.\n");
1da177e4
LT
890 return -errno_NFSERR_IO;
891 }
892
893 hdrlen = (u8 *) p - (u8 *) iov->iov_base;
894 if (iov->iov_len < hdrlen) {
fe82a183 895 dprintk("NFS: READ reply header overflowed:"
c957c526 896 "length %Zu > %Zu\n", hdrlen, iov->iov_len);
1da177e4
LT
897 return -errno_NFSERR_IO;
898 } else if (iov->iov_len != hdrlen) {
899 dprintk("NFS: READ header is short. iovec will be shifted.\n");
900 xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
901 }
902
903 recvd = req->rq_rcv_buf.len - hdrlen;
904 if (count > recvd) {
fe82a183 905 dprintk("NFS: server cheating in read reply: "
c957c526 906 "count %u > recvd %u\n", count, recvd);
1da177e4
LT
907 count = recvd;
908 res->eof = 0;
909 }
910
911 if (count < res->count)
912 res->count = count;
913
914 return count;
915}
916
917/*
918 * Decode WRITE response
919 */
920static int
d61005a6 921nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1da177e4
LT
922{
923 int status;
924
925 status = ntohl(*p++);
926 p = xdr_decode_wcc_data(p, res->fattr);
927
928 if (status != 0)
856dff3d 929 return nfs_stat_to_errno(status);
1da177e4
LT
930
931 res->count = ntohl(*p++);
932 res->verf->committed = (enum nfs3_stable_how)ntohl(*p++);
933 res->verf->verifier[0] = *p++;
934 res->verf->verifier[1] = *p++;
935
936 return res->count;
937}
938
939/*
940 * Decode a CREATE response
941 */
942static int
d61005a6 943nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res)
1da177e4
LT
944{
945 int status;
946
947 status = ntohl(*p++);
948 if (status == 0) {
949 if (*p++) {
950 if (!(p = xdr_decode_fhandle(p, res->fh)))
951 return -errno_NFSERR_IO;
952 p = xdr_decode_post_op_attr(p, res->fattr);
953 } else {
954 memset(res->fh, 0, sizeof(*res->fh));
955 /* Do decode post_op_attr but set it to NULL */
956 p = xdr_decode_post_op_attr(p, res->fattr);
957 res->fattr->valid = 0;
958 }
959 } else {
856dff3d 960 status = nfs_stat_to_errno(status);
1da177e4
LT
961 }
962 p = xdr_decode_wcc_data(p, res->dir_attr);
963 return status;
964}
965
966/*
967 * Decode RENAME reply
968 */
969static int
e8582a8b 970nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res)
1da177e4
LT
971{
972 int status;
973
974 if ((status = ntohl(*p++)) != 0)
856dff3d 975 status = nfs_stat_to_errno(status);
e8582a8b
JL
976 p = xdr_decode_wcc_data(p, res->old_fattr);
977 p = xdr_decode_wcc_data(p, res->new_fattr);
1da177e4
LT
978 return status;
979}
980
981/*
982 * Decode LINK reply
983 */
984static int
d61005a6 985nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res)
1da177e4
LT
986{
987 int status;
988
989 if ((status = ntohl(*p++)) != 0)
856dff3d 990 status = nfs_stat_to_errno(status);
1da177e4
LT
991 p = xdr_decode_post_op_attr(p, res->fattr);
992 p = xdr_decode_wcc_data(p, res->dir_attr);
993 return status;
994}
995
996/*
997 * Decode FSSTAT reply
998 */
999static int
d61005a6 1000nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res)
1da177e4
LT
1001{
1002 int status;
1003
1004 status = ntohl(*p++);
1005
1006 p = xdr_decode_post_op_attr(p, res->fattr);
1007 if (status != 0)
856dff3d 1008 return nfs_stat_to_errno(status);
1da177e4
LT
1009
1010 p = xdr_decode_hyper(p, &res->tbytes);
1011 p = xdr_decode_hyper(p, &res->fbytes);
1012 p = xdr_decode_hyper(p, &res->abytes);
1013 p = xdr_decode_hyper(p, &res->tfiles);
1014 p = xdr_decode_hyper(p, &res->ffiles);
1015 p = xdr_decode_hyper(p, &res->afiles);
1016
1017 /* ignore invarsec */
1018 return 0;
1019}
1020
1021/*
1022 * Decode FSINFO reply
1023 */
1024static int
d61005a6 1025nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
1da177e4
LT
1026{
1027 int status;
1028
1029 status = ntohl(*p++);
1030
1031 p = xdr_decode_post_op_attr(p, res->fattr);
1032 if (status != 0)
856dff3d 1033 return nfs_stat_to_errno(status);
1da177e4
LT
1034
1035 res->rtmax = ntohl(*p++);
1036 res->rtpref = ntohl(*p++);
1037 res->rtmult = ntohl(*p++);
1038 res->wtmax = ntohl(*p++);
1039 res->wtpref = ntohl(*p++);
1040 res->wtmult = ntohl(*p++);
1041 res->dtpref = ntohl(*p++);
1042 p = xdr_decode_hyper(p, &res->maxfilesize);
6b96724e 1043 p = xdr_decode_time3(p, &res->time_delta);
1da177e4 1044
6b96724e 1045 /* ignore properties */
1da177e4
LT
1046 res->lease_time = 0;
1047 return 0;
1048}
1049
1050/*
1051 * Decode PATHCONF reply
1052 */
1053static int
d61005a6 1054nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res)
1da177e4
LT
1055{
1056 int status;
1057
1058 status = ntohl(*p++);
1059
1060 p = xdr_decode_post_op_attr(p, res->fattr);
1061 if (status != 0)
856dff3d 1062 return nfs_stat_to_errno(status);
1da177e4
LT
1063 res->max_link = ntohl(*p++);
1064 res->max_namelen = ntohl(*p++);
1065
1066 /* ignore remaining fields */
1067 return 0;
1068}
1069
1070/*
1071 * Decode COMMIT reply
1072 */
1073static int
d61005a6 1074nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
1da177e4
LT
1075{
1076 int status;
1077
1078 status = ntohl(*p++);
1079 p = xdr_decode_wcc_data(p, res->fattr);
1080 if (status != 0)
856dff3d 1081 return nfs_stat_to_errno(status);
1da177e4
LT
1082
1083 res->verf->verifier[0] = *p++;
1084 res->verf->verifier[1] = *p++;
1085 return 0;
1086}
1087
b7fa0554
AG
1088#ifdef CONFIG_NFS_V3_ACL
1089/*
1090 * Decode GETACL reply
1091 */
1092static int
d61005a6 1093nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p,
b7fa0554
AG
1094 struct nfs3_getaclres *res)
1095{
1096 struct xdr_buf *buf = &req->rq_rcv_buf;
1097 int status = ntohl(*p++);
1098 struct posix_acl **acl;
1099 unsigned int *aclcnt;
1100 int err, base;
1101
1102 if (status != 0)
856dff3d 1103 return nfs_stat_to_errno(status);
b7fa0554
AG
1104 p = xdr_decode_post_op_attr(p, res->fattr);
1105 res->mask = ntohl(*p++);
1106 if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
1107 return -EINVAL;
1108 base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base;
1109
1110 acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL;
1111 aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL;
1112 err = nfsacl_decode(buf, base, aclcnt, acl);
1113
1114 acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL;
1115 aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL;
1116 if (err > 0)
1117 err = nfsacl_decode(buf, base + err, aclcnt, acl);
1118 return (err > 0) ? 0 : err;
1119}
1120
1121/*
1122 * Decode setacl reply.
1123 */
1124static int
d61005a6 1125nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
b7fa0554
AG
1126{
1127 int status = ntohl(*p++);
1128
1129 if (status)
856dff3d 1130 return nfs_stat_to_errno(status);
b7fa0554
AG
1131 xdr_decode_post_op_attr(p, fattr);
1132 return 0;
1133}
1134#endif /* CONFIG_NFS_V3_ACL */
1135
1da177e4
LT
1136#define PROC(proc, argtype, restype, timer) \
1137[NFS3PROC_##proc] = { \
1138 .p_proc = NFS3PROC_##proc, \
1139 .p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \
1140 .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \
2bea90d4
CL
1141 .p_arglen = NFS3_##argtype##_sz, \
1142 .p_replen = NFS3_##restype##_sz, \
cc0175c1
CL
1143 .p_timer = timer, \
1144 .p_statidx = NFS3PROC_##proc, \
1145 .p_name = #proc, \
1da177e4
LT
1146 }
1147
1148struct rpc_procinfo nfs3_procedures[] = {
1149 PROC(GETATTR, fhandle, attrstat, 1),
1150 PROC(SETATTR, sattrargs, wccstat, 0),
1151 PROC(LOOKUP, diropargs, lookupres, 2),
1152 PROC(ACCESS, accessargs, accessres, 1),
1153 PROC(READLINK, readlinkargs, readlinkres, 3),
1154 PROC(READ, readargs, readres, 3),
1155 PROC(WRITE, writeargs, writeres, 4),
1156 PROC(CREATE, createargs, createres, 0),
1157 PROC(MKDIR, mkdirargs, createres, 0),
1158 PROC(SYMLINK, symlinkargs, createres, 0),
1159 PROC(MKNOD, mknodargs, createres, 0),
4fdc17b2 1160 PROC(REMOVE, removeargs, removeres, 0),
1da177e4
LT
1161 PROC(RMDIR, diropargs, wccstat, 0),
1162 PROC(RENAME, renameargs, renameres, 0),
1163 PROC(LINK, linkargs, linkres, 0),
1164 PROC(READDIR, readdirargs, readdirres, 3),
1165 PROC(READDIRPLUS, readdirargs, readdirres, 3),
1166 PROC(FSSTAT, fhandle, fsstatres, 0),
1167 PROC(FSINFO, fhandle, fsinfores, 0),
1168 PROC(PATHCONF, fhandle, pathconfres, 0),
1169 PROC(COMMIT, commitargs, commitres, 5),
1170};
1171
1172struct rpc_version nfs_version3 = {
1173 .number = 3,
e8c96f8c 1174 .nrprocs = ARRAY_SIZE(nfs3_procedures),
1da177e4
LT
1175 .procs = nfs3_procedures
1176};
1177
b7fa0554
AG
1178#ifdef CONFIG_NFS_V3_ACL
1179static struct rpc_procinfo nfs3_acl_procedures[] = {
1180 [ACLPROC3_GETACL] = {
1181 .p_proc = ACLPROC3_GETACL,
1182 .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs,
1183 .p_decode = (kxdrproc_t) nfs3_xdr_getaclres,
2bea90d4
CL
1184 .p_arglen = ACL3_getaclargs_sz,
1185 .p_replen = ACL3_getaclres_sz,
b7fa0554 1186 .p_timer = 1,
cc0175c1 1187 .p_name = "GETACL",
b7fa0554
AG
1188 },
1189 [ACLPROC3_SETACL] = {
1190 .p_proc = ACLPROC3_SETACL,
1191 .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs,
1192 .p_decode = (kxdrproc_t) nfs3_xdr_setaclres,
2bea90d4
CL
1193 .p_arglen = ACL3_setaclargs_sz,
1194 .p_replen = ACL3_setaclres_sz,
b7fa0554 1195 .p_timer = 0,
cc0175c1 1196 .p_name = "SETACL",
b7fa0554
AG
1197 },
1198};
1199
1200struct rpc_version nfsacl_version3 = {
1201 .number = 3,
1202 .nrprocs = sizeof(nfs3_acl_procedures)/
1203 sizeof(nfs3_acl_procedures[0]),
1204 .procs = nfs3_acl_procedures,
1205};
1206#endif /* CONFIG_NFS_V3_ACL */
This page took 0.647023 seconds and 5 git commands to generate.