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