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