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