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