xref: /openbmc/linux/fs/nfsd/nfs3xdr.c (revision 160b8e75)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * XDR support for nfsd/protocol version 3.
4  *
5  * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
6  *
7  * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()!
8  */
9 
10 #include <linux/namei.h>
11 #include <linux/sunrpc/svc_xprt.h>
12 #include "xdr3.h"
13 #include "auth.h"
14 #include "netns.h"
15 #include "vfs.h"
16 
17 #define NFSDDBG_FACILITY		NFSDDBG_XDR
18 
19 
20 /*
21  * Mapping of S_IF* types to NFS file types
22  */
23 static u32	nfs3_ftypes[] = {
24 	NF3NON,  NF3FIFO, NF3CHR, NF3BAD,
25 	NF3DIR,  NF3BAD,  NF3BLK, NF3BAD,
26 	NF3REG,  NF3BAD,  NF3LNK, NF3BAD,
27 	NF3SOCK, NF3BAD,  NF3LNK, NF3BAD,
28 };
29 
30 /*
31  * XDR functions for basic NFS types
32  */
33 static __be32 *
34 encode_time3(__be32 *p, struct timespec *time)
35 {
36 	*p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
37 	return p;
38 }
39 
40 static __be32 *
41 decode_time3(__be32 *p, struct timespec *time)
42 {
43 	time->tv_sec = ntohl(*p++);
44 	time->tv_nsec = ntohl(*p++);
45 	return p;
46 }
47 
48 static __be32 *
49 decode_fh(__be32 *p, struct svc_fh *fhp)
50 {
51 	unsigned int size;
52 	fh_init(fhp, NFS3_FHSIZE);
53 	size = ntohl(*p++);
54 	if (size > NFS3_FHSIZE)
55 		return NULL;
56 
57 	memcpy(&fhp->fh_handle.fh_base, p, size);
58 	fhp->fh_handle.fh_size = size;
59 	return p + XDR_QUADLEN(size);
60 }
61 
62 /* Helper function for NFSv3 ACL code */
63 __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp)
64 {
65 	return decode_fh(p, fhp);
66 }
67 
68 static __be32 *
69 encode_fh(__be32 *p, struct svc_fh *fhp)
70 {
71 	unsigned int size = fhp->fh_handle.fh_size;
72 	*p++ = htonl(size);
73 	if (size) p[XDR_QUADLEN(size)-1]=0;
74 	memcpy(p, &fhp->fh_handle.fh_base, size);
75 	return p + XDR_QUADLEN(size);
76 }
77 
78 /*
79  * Decode a file name and make sure that the path contains
80  * no slashes or null bytes.
81  */
82 static __be32 *
83 decode_filename(__be32 *p, char **namp, unsigned int *lenp)
84 {
85 	char		*name;
86 	unsigned int	i;
87 
88 	if ((p = xdr_decode_string_inplace(p, namp, lenp, NFS3_MAXNAMLEN)) != NULL) {
89 		for (i = 0, name = *namp; i < *lenp; i++, name++) {
90 			if (*name == '\0' || *name == '/')
91 				return NULL;
92 		}
93 	}
94 
95 	return p;
96 }
97 
98 static __be32 *
99 decode_sattr3(__be32 *p, struct iattr *iap)
100 {
101 	u32	tmp;
102 
103 	iap->ia_valid = 0;
104 
105 	if (*p++) {
106 		iap->ia_valid |= ATTR_MODE;
107 		iap->ia_mode = ntohl(*p++);
108 	}
109 	if (*p++) {
110 		iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
111 		if (uid_valid(iap->ia_uid))
112 			iap->ia_valid |= ATTR_UID;
113 	}
114 	if (*p++) {
115 		iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
116 		if (gid_valid(iap->ia_gid))
117 			iap->ia_valid |= ATTR_GID;
118 	}
119 	if (*p++) {
120 		u64	newsize;
121 
122 		iap->ia_valid |= ATTR_SIZE;
123 		p = xdr_decode_hyper(p, &newsize);
124 		iap->ia_size = min_t(u64, newsize, NFS_OFFSET_MAX);
125 	}
126 	if ((tmp = ntohl(*p++)) == 1) {	/* set to server time */
127 		iap->ia_valid |= ATTR_ATIME;
128 	} else if (tmp == 2) {		/* set to client time */
129 		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
130 		iap->ia_atime.tv_sec = ntohl(*p++);
131 		iap->ia_atime.tv_nsec = ntohl(*p++);
132 	}
133 	if ((tmp = ntohl(*p++)) == 1) {	/* set to server time */
134 		iap->ia_valid |= ATTR_MTIME;
135 	} else if (tmp == 2) {		/* set to client time */
136 		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
137 		iap->ia_mtime.tv_sec = ntohl(*p++);
138 		iap->ia_mtime.tv_nsec = ntohl(*p++);
139 	}
140 	return p;
141 }
142 
143 static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
144 {
145 	u64 f;
146 	switch(fsid_source(fhp)) {
147 	default:
148 	case FSIDSOURCE_DEV:
149 		p = xdr_encode_hyper(p, (u64)huge_encode_dev
150 				     (fhp->fh_dentry->d_sb->s_dev));
151 		break;
152 	case FSIDSOURCE_FSID:
153 		p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
154 		break;
155 	case FSIDSOURCE_UUID:
156 		f = ((u64*)fhp->fh_export->ex_uuid)[0];
157 		f ^= ((u64*)fhp->fh_export->ex_uuid)[1];
158 		p = xdr_encode_hyper(p, f);
159 		break;
160 	}
161 	return p;
162 }
163 
164 static __be32 *
165 encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
166 	      struct kstat *stat)
167 {
168 	*p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
169 	*p++ = htonl((u32) (stat->mode & S_IALLUGO));
170 	*p++ = htonl((u32) stat->nlink);
171 	*p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
172 	*p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
173 	if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
174 		p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
175 	} else {
176 		p = xdr_encode_hyper(p, (u64) stat->size);
177 	}
178 	p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
179 	*p++ = htonl((u32) MAJOR(stat->rdev));
180 	*p++ = htonl((u32) MINOR(stat->rdev));
181 	p = encode_fsid(p, fhp);
182 	p = xdr_encode_hyper(p, stat->ino);
183 	p = encode_time3(p, &stat->atime);
184 	p = encode_time3(p, &stat->mtime);
185 	p = encode_time3(p, &stat->ctime);
186 
187 	return p;
188 }
189 
190 static __be32 *
191 encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
192 {
193 	/* Attributes to follow */
194 	*p++ = xdr_one;
195 	return encode_fattr3(rqstp, p, fhp, &fhp->fh_post_attr);
196 }
197 
198 /*
199  * Encode post-operation attributes.
200  * The inode may be NULL if the call failed because of a stale file
201  * handle. In this case, no attributes are returned.
202  */
203 static __be32 *
204 encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
205 {
206 	struct dentry *dentry = fhp->fh_dentry;
207 	if (dentry && d_really_is_positive(dentry)) {
208 	        __be32 err;
209 		struct kstat stat;
210 
211 		err = fh_getattr(fhp, &stat);
212 		if (!err) {
213 			*p++ = xdr_one;		/* attributes follow */
214 			lease_get_mtime(d_inode(dentry), &stat.mtime);
215 			return encode_fattr3(rqstp, p, fhp, &stat);
216 		}
217 	}
218 	*p++ = xdr_zero;
219 	return p;
220 }
221 
222 /* Helper for NFSv3 ACLs */
223 __be32 *
224 nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
225 {
226 	return encode_post_op_attr(rqstp, p, fhp);
227 }
228 
229 /*
230  * Enocde weak cache consistency data
231  */
232 static __be32 *
233 encode_wcc_data(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
234 {
235 	struct dentry	*dentry = fhp->fh_dentry;
236 
237 	if (dentry && d_really_is_positive(dentry) && fhp->fh_post_saved) {
238 		if (fhp->fh_pre_saved) {
239 			*p++ = xdr_one;
240 			p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size);
241 			p = encode_time3(p, &fhp->fh_pre_mtime);
242 			p = encode_time3(p, &fhp->fh_pre_ctime);
243 		} else {
244 			*p++ = xdr_zero;
245 		}
246 		return encode_saved_post_attr(rqstp, p, fhp);
247 	}
248 	/* no pre- or post-attrs */
249 	*p++ = xdr_zero;
250 	return encode_post_op_attr(rqstp, p, fhp);
251 }
252 
253 /*
254  * Fill in the pre_op attr for the wcc data
255  */
256 void fill_pre_wcc(struct svc_fh *fhp)
257 {
258 	struct inode    *inode;
259 	struct kstat	stat;
260 	__be32 err;
261 
262 	if (fhp->fh_pre_saved)
263 		return;
264 
265 	inode = d_inode(fhp->fh_dentry);
266 	err = fh_getattr(fhp, &stat);
267 	if (err) {
268 		/* Grab the times from inode anyway */
269 		stat.mtime = inode->i_mtime;
270 		stat.ctime = inode->i_ctime;
271 		stat.size  = inode->i_size;
272 	}
273 
274 	fhp->fh_pre_mtime = stat.mtime;
275 	fhp->fh_pre_ctime = stat.ctime;
276 	fhp->fh_pre_size  = stat.size;
277 	fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
278 	fhp->fh_pre_saved = true;
279 }
280 
281 /*
282  * Fill in the post_op attr for the wcc data
283  */
284 void fill_post_wcc(struct svc_fh *fhp)
285 {
286 	__be32 err;
287 
288 	if (fhp->fh_post_saved)
289 		printk("nfsd: inode locked twice during operation.\n");
290 
291 	err = fh_getattr(fhp, &fhp->fh_post_attr);
292 	fhp->fh_post_change = nfsd4_change_attribute(&fhp->fh_post_attr,
293 						     d_inode(fhp->fh_dentry));
294 	if (err) {
295 		fhp->fh_post_saved = false;
296 		/* Grab the ctime anyway - set_change_info might use it */
297 		fhp->fh_post_attr.ctime = d_inode(fhp->fh_dentry)->i_ctime;
298 	} else
299 		fhp->fh_post_saved = true;
300 }
301 
302 /*
303  * XDR decode functions
304  */
305 int
306 nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p)
307 {
308 	struct nfsd_fhandle *args = rqstp->rq_argp;
309 
310 	p = decode_fh(p, &args->fh);
311 	if (!p)
312 		return 0;
313 	return xdr_argsize_check(rqstp, p);
314 }
315 
316 int
317 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
318 {
319 	struct nfsd3_sattrargs *args = rqstp->rq_argp;
320 
321 	p = decode_fh(p, &args->fh);
322 	if (!p)
323 		return 0;
324 	p = decode_sattr3(p, &args->attrs);
325 
326 	if ((args->check_guard = ntohl(*p++)) != 0) {
327 		struct timespec time;
328 		p = decode_time3(p, &time);
329 		args->guardtime = time.tv_sec;
330 	}
331 
332 	return xdr_argsize_check(rqstp, p);
333 }
334 
335 int
336 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p)
337 {
338 	struct nfsd3_diropargs *args = rqstp->rq_argp;
339 
340 	if (!(p = decode_fh(p, &args->fh))
341 	 || !(p = decode_filename(p, &args->name, &args->len)))
342 		return 0;
343 
344 	return xdr_argsize_check(rqstp, p);
345 }
346 
347 int
348 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p)
349 {
350 	struct nfsd3_accessargs *args = rqstp->rq_argp;
351 
352 	p = decode_fh(p, &args->fh);
353 	if (!p)
354 		return 0;
355 	args->access = ntohl(*p++);
356 
357 	return xdr_argsize_check(rqstp, p);
358 }
359 
360 int
361 nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p)
362 {
363 	struct nfsd3_readargs *args = rqstp->rq_argp;
364 	unsigned int len;
365 	int v;
366 	u32 max_blocksize = svc_max_payload(rqstp);
367 
368 	p = decode_fh(p, &args->fh);
369 	if (!p)
370 		return 0;
371 	p = xdr_decode_hyper(p, &args->offset);
372 
373 	args->count = ntohl(*p++);
374 	len = min(args->count, max_blocksize);
375 
376 	/* set up the kvec */
377 	v=0;
378 	while (len > 0) {
379 		struct page *p = *(rqstp->rq_next_page++);
380 
381 		rqstp->rq_vec[v].iov_base = page_address(p);
382 		rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE);
383 		len -= rqstp->rq_vec[v].iov_len;
384 		v++;
385 	}
386 	args->vlen = v;
387 	return xdr_argsize_check(rqstp, p);
388 }
389 
390 int
391 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
392 {
393 	struct nfsd3_writeargs *args = rqstp->rq_argp;
394 	unsigned int len, v, hdr, dlen;
395 	u32 max_blocksize = svc_max_payload(rqstp);
396 	struct kvec *head = rqstp->rq_arg.head;
397 	struct kvec *tail = rqstp->rq_arg.tail;
398 
399 	p = decode_fh(p, &args->fh);
400 	if (!p)
401 		return 0;
402 	p = xdr_decode_hyper(p, &args->offset);
403 
404 	args->count = ntohl(*p++);
405 	args->stable = ntohl(*p++);
406 	len = args->len = ntohl(*p++);
407 	if ((void *)p > head->iov_base + head->iov_len)
408 		return 0;
409 	/*
410 	 * The count must equal the amount of data passed.
411 	 */
412 	if (args->count != args->len)
413 		return 0;
414 
415 	/*
416 	 * Check to make sure that we got the right number of
417 	 * bytes.
418 	 */
419 	hdr = (void*)p - head->iov_base;
420 	dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr;
421 	/*
422 	 * Round the length of the data which was specified up to
423 	 * the next multiple of XDR units and then compare that
424 	 * against the length which was actually received.
425 	 * Note that when RPCSEC/GSS (for example) is used, the
426 	 * data buffer can be padded so dlen might be larger
427 	 * than required.  It must never be smaller.
428 	 */
429 	if (dlen < XDR_QUADLEN(len)*4)
430 		return 0;
431 
432 	if (args->count > max_blocksize) {
433 		args->count = max_blocksize;
434 		len = args->len = max_blocksize;
435 	}
436 	rqstp->rq_vec[0].iov_base = (void*)p;
437 	rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
438 	v = 0;
439 	while (len > rqstp->rq_vec[v].iov_len) {
440 		len -= rqstp->rq_vec[v].iov_len;
441 		v++;
442 		rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
443 		rqstp->rq_vec[v].iov_len = PAGE_SIZE;
444 	}
445 	rqstp->rq_vec[v].iov_len = len;
446 	args->vlen = v + 1;
447 	return 1;
448 }
449 
450 int
451 nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p)
452 {
453 	struct nfsd3_createargs *args = rqstp->rq_argp;
454 
455 	if (!(p = decode_fh(p, &args->fh))
456 	 || !(p = decode_filename(p, &args->name, &args->len)))
457 		return 0;
458 
459 	switch (args->createmode = ntohl(*p++)) {
460 	case NFS3_CREATE_UNCHECKED:
461 	case NFS3_CREATE_GUARDED:
462 		p = decode_sattr3(p, &args->attrs);
463 		break;
464 	case NFS3_CREATE_EXCLUSIVE:
465 		args->verf = p;
466 		p += 2;
467 		break;
468 	default:
469 		return 0;
470 	}
471 
472 	return xdr_argsize_check(rqstp, p);
473 }
474 
475 int
476 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p)
477 {
478 	struct nfsd3_createargs *args = rqstp->rq_argp;
479 
480 	if (!(p = decode_fh(p, &args->fh)) ||
481 	    !(p = decode_filename(p, &args->name, &args->len)))
482 		return 0;
483 	p = decode_sattr3(p, &args->attrs);
484 
485 	return xdr_argsize_check(rqstp, p);
486 }
487 
488 int
489 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
490 {
491 	struct nfsd3_symlinkargs *args = rqstp->rq_argp;
492 	unsigned int len, avail;
493 	char *old, *new;
494 	struct kvec *vec;
495 
496 	if (!(p = decode_fh(p, &args->ffh)) ||
497 	    !(p = decode_filename(p, &args->fname, &args->flen))
498 		)
499 		return 0;
500 	p = decode_sattr3(p, &args->attrs);
501 
502 	/* now decode the pathname, which might be larger than the first page.
503 	 * As we have to check for nul's anyway, we copy it into a new page
504 	 * This page appears in the rq_res.pages list, but as pages_len is always
505 	 * 0, it won't get in the way
506 	 */
507 	len = ntohl(*p++);
508 	if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
509 		return 0;
510 	args->tname = new = page_address(*(rqstp->rq_next_page++));
511 	args->tlen = len;
512 	/* first copy and check from the first page */
513 	old = (char*)p;
514 	vec = &rqstp->rq_arg.head[0];
515 	if ((void *)old > vec->iov_base + vec->iov_len)
516 		return 0;
517 	avail = vec->iov_len - (old - (char*)vec->iov_base);
518 	while (len && avail && *old) {
519 		*new++ = *old++;
520 		len--;
521 		avail--;
522 	}
523 	/* now copy next page if there is one */
524 	if (len && !avail && rqstp->rq_arg.page_len) {
525 		avail = min_t(unsigned int, rqstp->rq_arg.page_len, PAGE_SIZE);
526 		old = page_address(rqstp->rq_arg.pages[0]);
527 	}
528 	while (len && avail && *old) {
529 		*new++ = *old++;
530 		len--;
531 		avail--;
532 	}
533 	*new = '\0';
534 	if (len)
535 		return 0;
536 
537 	return 1;
538 }
539 
540 int
541 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p)
542 {
543 	struct nfsd3_mknodargs *args = rqstp->rq_argp;
544 
545 	if (!(p = decode_fh(p, &args->fh))
546 	 || !(p = decode_filename(p, &args->name, &args->len)))
547 		return 0;
548 
549 	args->ftype = ntohl(*p++);
550 
551 	if (args->ftype == NF3BLK  || args->ftype == NF3CHR
552 	 || args->ftype == NF3SOCK || args->ftype == NF3FIFO)
553 		p = decode_sattr3(p, &args->attrs);
554 
555 	if (args->ftype == NF3BLK || args->ftype == NF3CHR) {
556 		args->major = ntohl(*p++);
557 		args->minor = ntohl(*p++);
558 	}
559 
560 	return xdr_argsize_check(rqstp, p);
561 }
562 
563 int
564 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p)
565 {
566 	struct nfsd3_renameargs *args = rqstp->rq_argp;
567 
568 	if (!(p = decode_fh(p, &args->ffh))
569 	 || !(p = decode_filename(p, &args->fname, &args->flen))
570 	 || !(p = decode_fh(p, &args->tfh))
571 	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
572 		return 0;
573 
574 	return xdr_argsize_check(rqstp, p);
575 }
576 
577 int
578 nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p)
579 {
580 	struct nfsd3_readlinkargs *args = rqstp->rq_argp;
581 
582 	p = decode_fh(p, &args->fh);
583 	if (!p)
584 		return 0;
585 	args->buffer = page_address(*(rqstp->rq_next_page++));
586 
587 	return xdr_argsize_check(rqstp, p);
588 }
589 
590 int
591 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p)
592 {
593 	struct nfsd3_linkargs *args = rqstp->rq_argp;
594 
595 	if (!(p = decode_fh(p, &args->ffh))
596 	 || !(p = decode_fh(p, &args->tfh))
597 	 || !(p = decode_filename(p, &args->tname, &args->tlen)))
598 		return 0;
599 
600 	return xdr_argsize_check(rqstp, p);
601 }
602 
603 int
604 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
605 {
606 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
607 	p = decode_fh(p, &args->fh);
608 	if (!p)
609 		return 0;
610 	p = xdr_decode_hyper(p, &args->cookie);
611 	args->verf   = p; p += 2;
612 	args->dircount = ~0;
613 	args->count  = ntohl(*p++);
614 	args->count  = min_t(u32, args->count, PAGE_SIZE);
615 	args->buffer = page_address(*(rqstp->rq_next_page++));
616 
617 	return xdr_argsize_check(rqstp, p);
618 }
619 
620 int
621 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p)
622 {
623 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
624 	int len;
625 	u32 max_blocksize = svc_max_payload(rqstp);
626 
627 	p = decode_fh(p, &args->fh);
628 	if (!p)
629 		return 0;
630 	p = xdr_decode_hyper(p, &args->cookie);
631 	args->verf     = p; p += 2;
632 	args->dircount = ntohl(*p++);
633 	args->count    = ntohl(*p++);
634 
635 	len = args->count = min(args->count, max_blocksize);
636 	while (len > 0) {
637 		struct page *p = *(rqstp->rq_next_page++);
638 		if (!args->buffer)
639 			args->buffer = page_address(p);
640 		len -= PAGE_SIZE;
641 	}
642 
643 	return xdr_argsize_check(rqstp, p);
644 }
645 
646 int
647 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p)
648 {
649 	struct nfsd3_commitargs *args = rqstp->rq_argp;
650 	p = decode_fh(p, &args->fh);
651 	if (!p)
652 		return 0;
653 	p = xdr_decode_hyper(p, &args->offset);
654 	args->count = ntohl(*p++);
655 
656 	return xdr_argsize_check(rqstp, p);
657 }
658 
659 /*
660  * XDR encode functions
661  */
662 /*
663  * There must be an encoding function for void results so svc_process
664  * will work properly.
665  */
666 int
667 nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p)
668 {
669 	return xdr_ressize_check(rqstp, p);
670 }
671 
672 /* GETATTR */
673 int
674 nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p)
675 {
676 	struct nfsd3_attrstat *resp = rqstp->rq_resp;
677 
678 	if (resp->status == 0) {
679 		lease_get_mtime(d_inode(resp->fh.fh_dentry),
680 				&resp->stat.mtime);
681 		p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat);
682 	}
683 	return xdr_ressize_check(rqstp, p);
684 }
685 
686 /* SETATTR, REMOVE, RMDIR */
687 int
688 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p)
689 {
690 	struct nfsd3_attrstat *resp = rqstp->rq_resp;
691 
692 	p = encode_wcc_data(rqstp, p, &resp->fh);
693 	return xdr_ressize_check(rqstp, p);
694 }
695 
696 /* LOOKUP */
697 int
698 nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p)
699 {
700 	struct nfsd3_diropres *resp = rqstp->rq_resp;
701 
702 	if (resp->status == 0) {
703 		p = encode_fh(p, &resp->fh);
704 		p = encode_post_op_attr(rqstp, p, &resp->fh);
705 	}
706 	p = encode_post_op_attr(rqstp, p, &resp->dirfh);
707 	return xdr_ressize_check(rqstp, p);
708 }
709 
710 /* ACCESS */
711 int
712 nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p)
713 {
714 	struct nfsd3_accessres *resp = rqstp->rq_resp;
715 
716 	p = encode_post_op_attr(rqstp, p, &resp->fh);
717 	if (resp->status == 0)
718 		*p++ = htonl(resp->access);
719 	return xdr_ressize_check(rqstp, p);
720 }
721 
722 /* READLINK */
723 int
724 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p)
725 {
726 	struct nfsd3_readlinkres *resp = rqstp->rq_resp;
727 
728 	p = encode_post_op_attr(rqstp, p, &resp->fh);
729 	if (resp->status == 0) {
730 		*p++ = htonl(resp->len);
731 		xdr_ressize_check(rqstp, p);
732 		rqstp->rq_res.page_len = resp->len;
733 		if (resp->len & 3) {
734 			/* need to pad the tail */
735 			rqstp->rq_res.tail[0].iov_base = p;
736 			*p = 0;
737 			rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
738 		}
739 		return 1;
740 	} else
741 		return xdr_ressize_check(rqstp, p);
742 }
743 
744 /* READ */
745 int
746 nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p)
747 {
748 	struct nfsd3_readres *resp = rqstp->rq_resp;
749 
750 	p = encode_post_op_attr(rqstp, p, &resp->fh);
751 	if (resp->status == 0) {
752 		*p++ = htonl(resp->count);
753 		*p++ = htonl(resp->eof);
754 		*p++ = htonl(resp->count);	/* xdr opaque count */
755 		xdr_ressize_check(rqstp, p);
756 		/* now update rqstp->rq_res to reflect data as well */
757 		rqstp->rq_res.page_len = resp->count;
758 		if (resp->count & 3) {
759 			/* need to pad the tail */
760 			rqstp->rq_res.tail[0].iov_base = p;
761 			*p = 0;
762 			rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
763 		}
764 		return 1;
765 	} else
766 		return xdr_ressize_check(rqstp, p);
767 }
768 
769 /* WRITE */
770 int
771 nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p)
772 {
773 	struct nfsd3_writeres *resp = rqstp->rq_resp;
774 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
775 
776 	p = encode_wcc_data(rqstp, p, &resp->fh);
777 	if (resp->status == 0) {
778 		*p++ = htonl(resp->count);
779 		*p++ = htonl(resp->committed);
780 		/* unique identifier, y2038 overflow can be ignored */
781 		*p++ = htonl((u32)nn->nfssvc_boot.tv_sec);
782 		*p++ = htonl(nn->nfssvc_boot.tv_nsec);
783 	}
784 	return xdr_ressize_check(rqstp, p);
785 }
786 
787 /* CREATE, MKDIR, SYMLINK, MKNOD */
788 int
789 nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p)
790 {
791 	struct nfsd3_diropres *resp = rqstp->rq_resp;
792 
793 	if (resp->status == 0) {
794 		*p++ = xdr_one;
795 		p = encode_fh(p, &resp->fh);
796 		p = encode_post_op_attr(rqstp, p, &resp->fh);
797 	}
798 	p = encode_wcc_data(rqstp, p, &resp->dirfh);
799 	return xdr_ressize_check(rqstp, p);
800 }
801 
802 /* RENAME */
803 int
804 nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p)
805 {
806 	struct nfsd3_renameres *resp = rqstp->rq_resp;
807 
808 	p = encode_wcc_data(rqstp, p, &resp->ffh);
809 	p = encode_wcc_data(rqstp, p, &resp->tfh);
810 	return xdr_ressize_check(rqstp, p);
811 }
812 
813 /* LINK */
814 int
815 nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p)
816 {
817 	struct nfsd3_linkres *resp = rqstp->rq_resp;
818 
819 	p = encode_post_op_attr(rqstp, p, &resp->fh);
820 	p = encode_wcc_data(rqstp, p, &resp->tfh);
821 	return xdr_ressize_check(rqstp, p);
822 }
823 
824 /* READDIR */
825 int
826 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p)
827 {
828 	struct nfsd3_readdirres *resp = rqstp->rq_resp;
829 
830 	p = encode_post_op_attr(rqstp, p, &resp->fh);
831 
832 	if (resp->status == 0) {
833 		/* stupid readdir cookie */
834 		memcpy(p, resp->verf, 8); p += 2;
835 		xdr_ressize_check(rqstp, p);
836 		if (rqstp->rq_res.head[0].iov_len + (2<<2) > PAGE_SIZE)
837 			return 1; /*No room for trailer */
838 		rqstp->rq_res.page_len = (resp->count) << 2;
839 
840 		/* add the 'tail' to the end of the 'head' page - page 0. */
841 		rqstp->rq_res.tail[0].iov_base = p;
842 		*p++ = 0;		/* no more entries */
843 		*p++ = htonl(resp->common.err == nfserr_eof);
844 		rqstp->rq_res.tail[0].iov_len = 2<<2;
845 		return 1;
846 	} else
847 		return xdr_ressize_check(rqstp, p);
848 }
849 
850 static __be32 *
851 encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name,
852 	     int namlen, u64 ino)
853 {
854 	*p++ = xdr_one;				 /* mark entry present */
855 	p    = xdr_encode_hyper(p, ino);	 /* file id */
856 	p    = xdr_encode_array(p, name, namlen);/* name length & name */
857 
858 	cd->offset = p;				/* remember pointer */
859 	p = xdr_encode_hyper(p, NFS_OFFSET_MAX);/* offset of next entry */
860 
861 	return p;
862 }
863 
864 static __be32
865 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
866 		 const char *name, int namlen, u64 ino)
867 {
868 	struct svc_export	*exp;
869 	struct dentry		*dparent, *dchild;
870 	__be32 rv = nfserr_noent;
871 
872 	dparent = cd->fh.fh_dentry;
873 	exp  = cd->fh.fh_export;
874 
875 	if (isdotent(name, namlen)) {
876 		if (namlen == 2) {
877 			dchild = dget_parent(dparent);
878 			/* filesystem root - cannot return filehandle for ".." */
879 			if (dchild == dparent)
880 				goto out;
881 		} else
882 			dchild = dget(dparent);
883 	} else
884 		dchild = lookup_one_len_unlocked(name, dparent, namlen);
885 	if (IS_ERR(dchild))
886 		return rv;
887 	if (d_mountpoint(dchild))
888 		goto out;
889 	if (d_really_is_negative(dchild))
890 		goto out;
891 	if (dchild->d_inode->i_ino != ino)
892 		goto out;
893 	rv = fh_compose(fhp, exp, dchild, &cd->fh);
894 out:
895 	dput(dchild);
896 	return rv;
897 }
898 
899 static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen, u64 ino)
900 {
901 	struct svc_fh	*fh = &cd->scratch;
902 	__be32 err;
903 
904 	fh_init(fh, NFS3_FHSIZE);
905 	err = compose_entry_fh(cd, fh, name, namlen, ino);
906 	if (err) {
907 		*p++ = 0;
908 		*p++ = 0;
909 		goto out;
910 	}
911 	p = encode_post_op_attr(cd->rqstp, p, fh);
912 	*p++ = xdr_one;			/* yes, a file handle follows */
913 	p = encode_fh(p, fh);
914 out:
915 	fh_put(fh);
916 	return p;
917 }
918 
919 /*
920  * Encode a directory entry. This one works for both normal readdir
921  * and readdirplus.
922  * The normal readdir reply requires 2 (fileid) + 1 (stringlen)
923  * + string + 2 (cookie) + 1 (next) words, i.e. 6 + strlen.
924  *
925  * The readdirplus baggage is 1+21 words for post_op_attr, plus the
926  * file handle.
927  */
928 
929 #define NFS3_ENTRY_BAGGAGE	(2 + 1 + 2 + 1)
930 #define NFS3_ENTRYPLUS_BAGGAGE	(1 + 21 + 1 + (NFS3_FHSIZE >> 2))
931 static int
932 encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
933 	     loff_t offset, u64 ino, unsigned int d_type, int plus)
934 {
935 	struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres,
936 		       					common);
937 	__be32		*p = cd->buffer;
938 	caddr_t		curr_page_addr = NULL;
939 	struct page **	page;
940 	int		slen;		/* string (name) length */
941 	int		elen;		/* estimated entry length in words */
942 	int		num_entry_words = 0;	/* actual number of words */
943 
944 	if (cd->offset) {
945 		u64 offset64 = offset;
946 
947 		if (unlikely(cd->offset1)) {
948 			/* we ended up with offset on a page boundary */
949 			*cd->offset = htonl(offset64 >> 32);
950 			*cd->offset1 = htonl(offset64 & 0xffffffff);
951 			cd->offset1 = NULL;
952 		} else {
953 			xdr_encode_hyper(cd->offset, offset64);
954 		}
955 	}
956 
957 	/*
958 	dprintk("encode_entry(%.*s @%ld%s)\n",
959 		namlen, name, (long) offset, plus? " plus" : "");
960 	 */
961 
962 	/* truncate filename if too long */
963 	namlen = min(namlen, NFS3_MAXNAMLEN);
964 
965 	slen = XDR_QUADLEN(namlen);
966 	elen = slen + NFS3_ENTRY_BAGGAGE
967 		+ (plus? NFS3_ENTRYPLUS_BAGGAGE : 0);
968 
969 	if (cd->buflen < elen) {
970 		cd->common.err = nfserr_toosmall;
971 		return -EINVAL;
972 	}
973 
974 	/* determine which page in rq_respages[] we are currently filling */
975 	for (page = cd->rqstp->rq_respages + 1;
976 				page < cd->rqstp->rq_next_page; page++) {
977 		curr_page_addr = page_address(*page);
978 
979 		if (((caddr_t)cd->buffer >= curr_page_addr) &&
980 		    ((caddr_t)cd->buffer <  curr_page_addr + PAGE_SIZE))
981 			break;
982 	}
983 
984 	if ((caddr_t)(cd->buffer + elen) < (curr_page_addr + PAGE_SIZE)) {
985 		/* encode entry in current page */
986 
987 		p = encode_entry_baggage(cd, p, name, namlen, ino);
988 
989 		if (plus)
990 			p = encode_entryplus_baggage(cd, p, name, namlen, ino);
991 		num_entry_words = p - cd->buffer;
992 	} else if (*(page+1) != NULL) {
993 		/* temporarily encode entry into next page, then move back to
994 		 * current and next page in rq_respages[] */
995 		__be32 *p1, *tmp;
996 		int len1, len2;
997 
998 		/* grab next page for temporary storage of entry */
999 		p1 = tmp = page_address(*(page+1));
1000 
1001 		p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
1002 
1003 		if (plus)
1004 			p1 = encode_entryplus_baggage(cd, p1, name, namlen, ino);
1005 
1006 		/* determine entry word length and lengths to go in pages */
1007 		num_entry_words = p1 - tmp;
1008 		len1 = curr_page_addr + PAGE_SIZE - (caddr_t)cd->buffer;
1009 		if ((num_entry_words << 2) < len1) {
1010 			/* the actual number of words in the entry is less
1011 			 * than elen and can still fit in the current page
1012 			 */
1013 			memmove(p, tmp, num_entry_words << 2);
1014 			p += num_entry_words;
1015 
1016 			/* update offset */
1017 			cd->offset = cd->buffer + (cd->offset - tmp);
1018 		} else {
1019 			unsigned int offset_r = (cd->offset - tmp) << 2;
1020 
1021 			/* update pointer to offset location.
1022 			 * This is a 64bit quantity, so we need to
1023 			 * deal with 3 cases:
1024 			 *  -	entirely in first page
1025 			 *  -	entirely in second page
1026 			 *  -	4 bytes in each page
1027 			 */
1028 			if (offset_r + 8 <= len1) {
1029 				cd->offset = p + (cd->offset - tmp);
1030 			} else if (offset_r >= len1) {
1031 				cd->offset -= len1 >> 2;
1032 			} else {
1033 				/* sitting on the fence */
1034 				BUG_ON(offset_r != len1 - 4);
1035 				cd->offset = p + (cd->offset - tmp);
1036 				cd->offset1 = tmp;
1037 			}
1038 
1039 			len2 = (num_entry_words << 2) - len1;
1040 
1041 			/* move from temp page to current and next pages */
1042 			memmove(p, tmp, len1);
1043 			memmove(tmp, (caddr_t)tmp+len1, len2);
1044 
1045 			p = tmp + (len2 >> 2);
1046 		}
1047 	}
1048 	else {
1049 		cd->common.err = nfserr_toosmall;
1050 		return -EINVAL;
1051 	}
1052 
1053 	cd->buflen -= num_entry_words;
1054 	cd->buffer = p;
1055 	cd->common.err = nfs_ok;
1056 	return 0;
1057 
1058 }
1059 
1060 int
1061 nfs3svc_encode_entry(void *cd, const char *name,
1062 		     int namlen, loff_t offset, u64 ino, unsigned int d_type)
1063 {
1064 	return encode_entry(cd, name, namlen, offset, ino, d_type, 0);
1065 }
1066 
1067 int
1068 nfs3svc_encode_entry_plus(void *cd, const char *name,
1069 			  int namlen, loff_t offset, u64 ino,
1070 			  unsigned int d_type)
1071 {
1072 	return encode_entry(cd, name, namlen, offset, ino, d_type, 1);
1073 }
1074 
1075 /* FSSTAT */
1076 int
1077 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p)
1078 {
1079 	struct nfsd3_fsstatres *resp = rqstp->rq_resp;
1080 	struct kstatfs	*s = &resp->stats;
1081 	u64		bs = s->f_bsize;
1082 
1083 	*p++ = xdr_zero;	/* no post_op_attr */
1084 
1085 	if (resp->status == 0) {
1086 		p = xdr_encode_hyper(p, bs * s->f_blocks);	/* total bytes */
1087 		p = xdr_encode_hyper(p, bs * s->f_bfree);	/* free bytes */
1088 		p = xdr_encode_hyper(p, bs * s->f_bavail);	/* user available bytes */
1089 		p = xdr_encode_hyper(p, s->f_files);	/* total inodes */
1090 		p = xdr_encode_hyper(p, s->f_ffree);	/* free inodes */
1091 		p = xdr_encode_hyper(p, s->f_ffree);	/* user available inodes */
1092 		*p++ = htonl(resp->invarsec);	/* mean unchanged time */
1093 	}
1094 	return xdr_ressize_check(rqstp, p);
1095 }
1096 
1097 /* FSINFO */
1098 int
1099 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p)
1100 {
1101 	struct nfsd3_fsinfores *resp = rqstp->rq_resp;
1102 
1103 	*p++ = xdr_zero;	/* no post_op_attr */
1104 
1105 	if (resp->status == 0) {
1106 		*p++ = htonl(resp->f_rtmax);
1107 		*p++ = htonl(resp->f_rtpref);
1108 		*p++ = htonl(resp->f_rtmult);
1109 		*p++ = htonl(resp->f_wtmax);
1110 		*p++ = htonl(resp->f_wtpref);
1111 		*p++ = htonl(resp->f_wtmult);
1112 		*p++ = htonl(resp->f_dtpref);
1113 		p = xdr_encode_hyper(p, resp->f_maxfilesize);
1114 		*p++ = xdr_one;
1115 		*p++ = xdr_zero;
1116 		*p++ = htonl(resp->f_properties);
1117 	}
1118 
1119 	return xdr_ressize_check(rqstp, p);
1120 }
1121 
1122 /* PATHCONF */
1123 int
1124 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p)
1125 {
1126 	struct nfsd3_pathconfres *resp = rqstp->rq_resp;
1127 
1128 	*p++ = xdr_zero;	/* no post_op_attr */
1129 
1130 	if (resp->status == 0) {
1131 		*p++ = htonl(resp->p_link_max);
1132 		*p++ = htonl(resp->p_name_max);
1133 		*p++ = htonl(resp->p_no_trunc);
1134 		*p++ = htonl(resp->p_chown_restricted);
1135 		*p++ = htonl(resp->p_case_insensitive);
1136 		*p++ = htonl(resp->p_case_preserving);
1137 	}
1138 
1139 	return xdr_ressize_check(rqstp, p);
1140 }
1141 
1142 /* COMMIT */
1143 int
1144 nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p)
1145 {
1146 	struct nfsd3_commitres *resp = rqstp->rq_resp;
1147 	struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
1148 
1149 	p = encode_wcc_data(rqstp, p, &resp->fh);
1150 	/* Write verifier */
1151 	if (resp->status == 0) {
1152 		/* unique identifier, y2038 overflow can be ignored */
1153 		*p++ = htonl((u32)nn->nfssvc_boot.tv_sec);
1154 		*p++ = htonl(nn->nfssvc_boot.tv_nsec);
1155 	}
1156 	return xdr_ressize_check(rqstp, p);
1157 }
1158 
1159 /*
1160  * XDR release functions
1161  */
1162 void
1163 nfs3svc_release_fhandle(struct svc_rqst *rqstp)
1164 {
1165 	struct nfsd3_attrstat *resp = rqstp->rq_resp;
1166 
1167 	fh_put(&resp->fh);
1168 }
1169 
1170 void
1171 nfs3svc_release_fhandle2(struct svc_rqst *rqstp)
1172 {
1173 	struct nfsd3_fhandle_pair *resp = rqstp->rq_resp;
1174 
1175 	fh_put(&resp->fh1);
1176 	fh_put(&resp->fh2);
1177 }
1178