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