xref: /linux/fs/nfsd/nfs3xdr.c (revision c9d6f6ba2d15f8df32e04d4329ebf3c10bf8285b)
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/nfs3.h>
12 #include <linux/sunrpc/svc_xprt.h>
13 
14 #include "nfsd.h"
15 #include "xdr3.h"
16 #include "auth.h"
17 #include "netns.h"
18 #include "vfs.h"
19 #include "nfserr.h"
20 
21 /*
22  * Force construction of an empty post-op attr
23  */
24 static const struct svc_fh nfs3svc_null_fh = {
25 	.fh_no_wcc	= true,
26 };
27 
28 /*
29  * time_delta. {1, 0} means the server is accurate only
30  * to the nearest second.
31  */
32 static const struct timespec64 nfs3svc_time_delta = {
33 	.tv_sec		= 1,
34 	.tv_nsec	= 0,
35 };
36 
37 /*
38  * Mapping of S_IF* types to NFS file types
39  */
40 static const u32 nfs3_ftypes[] = {
41 	NF3NON,  NF3FIFO, NF3CHR, NF3BAD,
42 	NF3DIR,  NF3BAD,  NF3BLK, NF3BAD,
43 	NF3REG,  NF3BAD,  NF3LNK, NF3BAD,
44 	NF3SOCK, NF3BAD,  NF3LNK, NF3BAD,
45 };
46 
47 
48 /*
49  * Basic NFSv3 data types (RFC 1813 Sections 2.5 and 2.6)
50  */
51 
52 static __be32 *
53 encode_nfstime3(__be32 *p, const struct timespec64 *time)
54 {
55 	*p++ = cpu_to_be32((u32)time->tv_sec);
56 	*p++ = cpu_to_be32(time->tv_nsec);
57 
58 	return p;
59 }
60 
61 static bool
62 svcxdr_decode_nfstime3(struct xdr_stream *xdr, struct timespec64 *timep)
63 {
64 	__be32 *p;
65 
66 	p = xdr_inline_decode(xdr, XDR_UNIT * 2);
67 	if (!p)
68 		return false;
69 	timep->tv_sec = be32_to_cpup(p++);
70 	timep->tv_nsec = be32_to_cpup(p);
71 
72 	return true;
73 }
74 
75 /**
76  * svcxdr_decode_nfs_fh3 - Decode an NFSv3 file handle
77  * @xdr: XDR stream positioned at an undecoded NFSv3 FH
78  * @fhp: OUT: filled-in server file handle
79  *
80  * Return values:
81  *  %false: The encoded file handle was not valid
82  *  %true: @fhp has been initialized
83  */
84 bool
85 svcxdr_decode_nfs_fh3(struct xdr_stream *xdr, struct svc_fh *fhp)
86 {
87 	__be32 *p;
88 	u32 size;
89 
90 	if (xdr_stream_decode_u32(xdr, &size) < 0)
91 		return false;
92 	if (size == 0 || size > NFS3_FHSIZE)
93 		return false;
94 	p = xdr_inline_decode(xdr, size);
95 	if (!p)
96 		return false;
97 	fh_init(fhp, NFS3_FHSIZE);
98 	fhp->fh_handle.fh_size = size;
99 	memcpy(&fhp->fh_handle.fh_raw, p, size);
100 
101 	return true;
102 }
103 
104 /**
105  * svcxdr_encode_nfsstat3 - Encode an NFSv3 status code
106  * @xdr: XDR stream
107  * @status: status value to encode
108  *
109  * Return values:
110  *   %false: Send buffer space was exhausted
111  *   %true: Success
112  */
113 bool
114 svcxdr_encode_nfsstat3(struct xdr_stream *xdr, __be32 status)
115 {
116 	__be32 *p;
117 
118 	p = xdr_reserve_space(xdr, sizeof(status));
119 	if (!p)
120 		return false;
121 	*p = status;
122 
123 	return true;
124 }
125 
126 static bool
127 svcxdr_encode_nfs_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)
128 {
129 	u32 size = fhp->fh_handle.fh_size;
130 	__be32 *p;
131 
132 	p = xdr_reserve_space(xdr, XDR_UNIT + size);
133 	if (!p)
134 		return false;
135 	*p++ = cpu_to_be32(size);
136 	if (size)
137 		p[XDR_QUADLEN(size) - 1] = 0;
138 	memcpy(p, &fhp->fh_handle.fh_raw, size);
139 
140 	return true;
141 }
142 
143 static bool
144 svcxdr_encode_post_op_fh3(struct xdr_stream *xdr, const struct svc_fh *fhp)
145 {
146 	if (xdr_stream_encode_item_present(xdr) < 0)
147 		return false;
148 	if (!svcxdr_encode_nfs_fh3(xdr, fhp))
149 		return false;
150 
151 	return true;
152 }
153 
154 static bool
155 svcxdr_encode_cookieverf3(struct xdr_stream *xdr, const __be32 *verf)
156 {
157 	__be32 *p;
158 
159 	p = xdr_reserve_space(xdr, NFS3_COOKIEVERFSIZE);
160 	if (!p)
161 		return false;
162 	memcpy(p, verf, NFS3_COOKIEVERFSIZE);
163 
164 	return true;
165 }
166 
167 static bool
168 svcxdr_encode_writeverf3(struct xdr_stream *xdr, const __be32 *verf)
169 {
170 	__be32 *p;
171 
172 	p = xdr_reserve_space(xdr, NFS3_WRITEVERFSIZE);
173 	if (!p)
174 		return false;
175 	memcpy(p, verf, NFS3_WRITEVERFSIZE);
176 
177 	return true;
178 }
179 
180 static bool
181 svcxdr_decode_filename3(struct xdr_stream *xdr, char **name, unsigned int *len)
182 {
183 	u32 size, i;
184 	__be32 *p;
185 	char *c;
186 
187 	if (xdr_stream_decode_u32(xdr, &size) < 0)
188 		return false;
189 	if (size == 0 || size > NFS3_MAXNAMLEN)
190 		return false;
191 	p = xdr_inline_decode(xdr, size);
192 	if (!p)
193 		return false;
194 
195 	*len = size;
196 	*name = (char *)p;
197 	for (i = 0, c = *name; i < size; i++, c++) {
198 		if (*c == '\0' || *c == '/')
199 			return false;
200 	}
201 
202 	return true;
203 }
204 
205 static bool
206 svcxdr_decode_diropargs3(struct xdr_stream *xdr, struct svc_fh *fhp,
207 			 char **name, unsigned int *len)
208 {
209 	return svcxdr_decode_nfs_fh3(xdr, fhp) &&
210 		svcxdr_decode_filename3(xdr, name, len);
211 }
212 
213 static bool
214 svcxdr_decode_sattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
215 		     struct iattr *iap)
216 {
217 	u32 set_it;
218 
219 	iap->ia_valid = 0;
220 
221 	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
222 		return false;
223 	if (set_it) {
224 		u32 mode;
225 
226 		if (xdr_stream_decode_u32(xdr, &mode) < 0)
227 			return false;
228 		iap->ia_valid |= ATTR_MODE;
229 		iap->ia_mode = mode;
230 	}
231 	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
232 		return false;
233 	if (set_it) {
234 		u32 uid;
235 
236 		if (xdr_stream_decode_u32(xdr, &uid) < 0)
237 			return false;
238 		iap->ia_uid = make_kuid(nfsd_user_namespace(rqstp), uid);
239 		if (uid_valid(iap->ia_uid))
240 			iap->ia_valid |= ATTR_UID;
241 	}
242 	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
243 		return false;
244 	if (set_it) {
245 		u32 gid;
246 
247 		if (xdr_stream_decode_u32(xdr, &gid) < 0)
248 			return false;
249 		iap->ia_gid = make_kgid(nfsd_user_namespace(rqstp), gid);
250 		if (gid_valid(iap->ia_gid))
251 			iap->ia_valid |= ATTR_GID;
252 	}
253 	if (xdr_stream_decode_bool(xdr, &set_it) < 0)
254 		return false;
255 	if (set_it) {
256 		u64 newsize;
257 
258 		if (xdr_stream_decode_u64(xdr, &newsize) < 0)
259 			return false;
260 		iap->ia_valid |= ATTR_SIZE;
261 		iap->ia_size = newsize;
262 	}
263 	if (xdr_stream_decode_u32(xdr, &set_it) < 0)
264 		return false;
265 	switch (set_it) {
266 	case DONT_CHANGE:
267 		break;
268 	case SET_TO_SERVER_TIME:
269 		iap->ia_valid |= ATTR_ATIME;
270 		break;
271 	case SET_TO_CLIENT_TIME:
272 		if (!svcxdr_decode_nfstime3(xdr, &iap->ia_atime))
273 			return false;
274 		iap->ia_valid |= ATTR_ATIME | ATTR_ATIME_SET;
275 		break;
276 	default:
277 		return false;
278 	}
279 	if (xdr_stream_decode_u32(xdr, &set_it) < 0)
280 		return false;
281 	switch (set_it) {
282 	case DONT_CHANGE:
283 		break;
284 	case SET_TO_SERVER_TIME:
285 		iap->ia_valid |= ATTR_MTIME;
286 		break;
287 	case SET_TO_CLIENT_TIME:
288 		if (!svcxdr_decode_nfstime3(xdr, &iap->ia_mtime))
289 			return false;
290 		iap->ia_valid |= ATTR_MTIME | ATTR_MTIME_SET;
291 		break;
292 	default:
293 		return false;
294 	}
295 
296 	return true;
297 }
298 
299 static bool
300 svcxdr_decode_sattrguard3(struct xdr_stream *xdr, struct nfsd3_sattrargs *args)
301 {
302 	u32 check;
303 
304 	if (xdr_stream_decode_bool(xdr, &check) < 0)
305 		return false;
306 	if (check) {
307 		if (!svcxdr_decode_nfstime3(xdr, &args->guardtime))
308 			return false;
309 		args->check_guard = 1;
310 	} else
311 		args->check_guard = 0;
312 
313 	return true;
314 }
315 
316 static bool
317 svcxdr_decode_specdata3(struct xdr_stream *xdr, struct nfsd3_mknodargs *args)
318 {
319 	__be32 *p;
320 
321 	p = xdr_inline_decode(xdr, XDR_UNIT * 2);
322 	if (!p)
323 		return false;
324 	args->major = be32_to_cpup(p++);
325 	args->minor = be32_to_cpup(p);
326 
327 	return true;
328 }
329 
330 static bool
331 svcxdr_decode_devicedata3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
332 			  struct nfsd3_mknodargs *args)
333 {
334 	return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
335 		svcxdr_decode_specdata3(xdr, args);
336 }
337 
338 static bool
339 svcxdr_encode_fattr3(struct svc_rqst *rqstp, struct xdr_stream *xdr,
340 		     const struct svc_fh *fhp, const struct kstat *stat)
341 {
342 	struct user_namespace *userns = nfsd_user_namespace(rqstp);
343 	__be32 *p;
344 	u64 fsid;
345 
346 	p = xdr_reserve_space(xdr, XDR_UNIT * 21);
347 	if (!p)
348 		return false;
349 
350 	*p++ = cpu_to_be32(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
351 	*p++ = cpu_to_be32((u32)(stat->mode & S_IALLUGO));
352 	*p++ = cpu_to_be32((u32)stat->nlink);
353 	*p++ = cpu_to_be32((u32)from_kuid_munged(userns, stat->uid));
354 	*p++ = cpu_to_be32((u32)from_kgid_munged(userns, stat->gid));
355 	if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN)
356 		p = xdr_encode_hyper(p, (u64)NFS3_MAXPATHLEN);
357 	else
358 		p = xdr_encode_hyper(p, (u64)stat->size);
359 
360 	/* used */
361 	p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
362 
363 	/* rdev */
364 	*p++ = cpu_to_be32((u32)MAJOR(stat->rdev));
365 	*p++ = cpu_to_be32((u32)MINOR(stat->rdev));
366 
367 	switch(fsid_source(fhp)) {
368 	case FSIDSOURCE_FSID:
369 		fsid = (u64)fhp->fh_export->ex_fsid;
370 		break;
371 	case FSIDSOURCE_UUID:
372 		fsid = ((u64 *)fhp->fh_export->ex_uuid)[0];
373 		fsid ^= ((u64 *)fhp->fh_export->ex_uuid)[1];
374 		break;
375 	default:
376 		fsid = (u64)huge_encode_dev(fhp->fh_dentry->d_sb->s_dev);
377 	}
378 	p = xdr_encode_hyper(p, fsid);
379 
380 	/* fileid */
381 	p = xdr_encode_hyper(p, stat->ino);
382 
383 	p = encode_nfstime3(p, &stat->atime);
384 	p = encode_nfstime3(p, &stat->mtime);
385 	encode_nfstime3(p, &stat->ctime);
386 
387 	return true;
388 }
389 
390 static bool
391 svcxdr_encode_wcc_attr(struct xdr_stream *xdr, const struct svc_fh *fhp)
392 {
393 	__be32 *p;
394 
395 	p = xdr_reserve_space(xdr, XDR_UNIT * 6);
396 	if (!p)
397 		return false;
398 	p = xdr_encode_hyper(p, (u64)fhp->fh_pre_size);
399 	p = encode_nfstime3(p, &fhp->fh_pre_mtime);
400 	encode_nfstime3(p, &fhp->fh_pre_ctime);
401 
402 	return true;
403 }
404 
405 static bool
406 svcxdr_encode_pre_op_attr(struct xdr_stream *xdr, const struct svc_fh *fhp)
407 {
408 	if (!fhp->fh_pre_saved) {
409 		if (xdr_stream_encode_item_absent(xdr) < 0)
410 			return false;
411 		return true;
412 	}
413 
414 	if (xdr_stream_encode_item_present(xdr) < 0)
415 		return false;
416 	return svcxdr_encode_wcc_attr(xdr, fhp);
417 }
418 
419 /**
420  * svcxdr_encode_post_op_attr - Encode NFSv3 post-op attributes
421  * @rqstp: Context of a completed RPC transaction
422  * @xdr: XDR stream
423  * @fhp: File handle to encode
424  *
425  * Return values:
426  *   %false: Send buffer space was exhausted
427  *   %true: Success
428  */
429 bool
430 svcxdr_encode_post_op_attr(struct svc_rqst *rqstp, struct xdr_stream *xdr,
431 			   const struct svc_fh *fhp)
432 {
433 	struct dentry *dentry = fhp->fh_dentry;
434 	struct kstat stat;
435 
436 	/*
437 	 * The inode may be NULL if the call failed because of a
438 	 * stale file handle. In this case, no attributes are
439 	 * returned.
440 	 */
441 	if (fhp->fh_no_wcc || !dentry || !d_really_is_positive(dentry))
442 		goto no_post_op_attrs;
443 	if (fh_getattr(fhp, &stat) != nfs_ok)
444 		goto no_post_op_attrs;
445 
446 	if (xdr_stream_encode_item_present(xdr) < 0)
447 		return false;
448 	lease_get_mtime(d_inode(dentry), &stat.mtime);
449 	if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &stat))
450 		return false;
451 
452 	return true;
453 
454 no_post_op_attrs:
455 	return xdr_stream_encode_item_absent(xdr) > 0;
456 }
457 
458 /*
459  * Encode weak cache consistency data
460  */
461 static bool
462 svcxdr_encode_wcc_data(struct svc_rqst *rqstp, struct xdr_stream *xdr,
463 		       const struct svc_fh *fhp)
464 {
465 	struct dentry *dentry = fhp->fh_dentry;
466 
467 	if (!dentry || !d_really_is_positive(dentry) || !fhp->fh_post_saved)
468 		goto neither;
469 
470 	/* before */
471 	if (!svcxdr_encode_pre_op_attr(xdr, fhp))
472 		return false;
473 
474 	/* after */
475 	if (xdr_stream_encode_item_present(xdr) < 0)
476 		return false;
477 	if (!svcxdr_encode_fattr3(rqstp, xdr, fhp, &fhp->fh_post_attr))
478 		return false;
479 
480 	return true;
481 
482 neither:
483 	if (xdr_stream_encode_item_absent(xdr) < 0)
484 		return false;
485 	if (!svcxdr_encode_post_op_attr(rqstp, xdr, fhp))
486 		return false;
487 
488 	return true;
489 }
490 
491 /*
492  * XDR decode functions
493  */
494 
495 bool
496 nfs3svc_decode_fhandleargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
497 {
498 	struct nfsd_fhandle *args = rqstp->rq_argp;
499 
500 	return svcxdr_decode_nfs_fh3(xdr, &args->fh);
501 }
502 
503 bool
504 nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
505 {
506 	struct nfsd3_sattrargs *args = rqstp->rq_argp;
507 
508 	return svcxdr_decode_nfs_fh3(xdr, &args->fh) &&
509 		svcxdr_decode_sattr3(rqstp, xdr, &args->attrs) &&
510 		svcxdr_decode_sattrguard3(xdr, args);
511 }
512 
513 bool
514 nfs3svc_decode_diropargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
515 {
516 	struct nfsd3_diropargs *args = rqstp->rq_argp;
517 
518 	return svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len);
519 }
520 
521 bool
522 nfs3svc_decode_accessargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
523 {
524 	struct nfsd3_accessargs *args = rqstp->rq_argp;
525 
526 	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
527 		return false;
528 	if (xdr_stream_decode_u32(xdr, &args->access) < 0)
529 		return false;
530 
531 	return true;
532 }
533 
534 bool
535 nfs3svc_decode_readargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
536 {
537 	struct nfsd3_readargs *args = rqstp->rq_argp;
538 
539 	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
540 		return false;
541 	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
542 		return false;
543 	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
544 		return false;
545 
546 	return true;
547 }
548 
549 bool
550 nfs3svc_decode_writeargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
551 {
552 	struct nfsd3_writeargs *args = rqstp->rq_argp;
553 	u32 max_blocksize = svc_max_payload(rqstp);
554 
555 	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
556 		return false;
557 	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
558 		return false;
559 	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
560 		return false;
561 	if (xdr_stream_decode_u32(xdr, &args->stable) < 0)
562 		return false;
563 	if (args->stable > NFS_FILE_SYNC)
564 		return false;
565 
566 	/* opaque data */
567 	if (xdr_stream_decode_u32(xdr, &args->len) < 0)
568 		return false;
569 
570 	/* request sanity */
571 	if (args->count != args->len)
572 		return false;
573 	if (args->count > max_blocksize) {
574 		args->count = max_blocksize;
575 		args->len = max_blocksize;
576 	}
577 
578 	return xdr_stream_subsegment(xdr, &args->payload, args->count);
579 }
580 
581 bool
582 nfs3svc_decode_createargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
583 {
584 	struct nfsd3_createargs *args = rqstp->rq_argp;
585 
586 	if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
587 		return false;
588 	if (xdr_stream_decode_u32(xdr, &args->createmode) < 0)
589 		return false;
590 	switch (args->createmode) {
591 	case NFS3_CREATE_UNCHECKED:
592 	case NFS3_CREATE_GUARDED:
593 		return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
594 	case NFS3_CREATE_EXCLUSIVE:
595 		args->verf = xdr_inline_decode(xdr, NFS3_CREATEVERFSIZE);
596 		if (!args->verf)
597 			return false;
598 		break;
599 	default:
600 		return false;
601 	}
602 	return true;
603 }
604 
605 bool
606 nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
607 {
608 	struct nfsd3_createargs *args = rqstp->rq_argp;
609 
610 	return svcxdr_decode_diropargs3(xdr, &args->fh,
611 					&args->name, &args->len) &&
612 		svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
613 }
614 
615 bool
616 nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
617 {
618 	struct nfsd3_symlinkargs *args = rqstp->rq_argp;
619 	struct kvec *head = rqstp->rq_arg.head;
620 
621 	if (!svcxdr_decode_diropargs3(xdr, &args->ffh, &args->fname, &args->flen))
622 		return false;
623 	if (!svcxdr_decode_sattr3(rqstp, xdr, &args->attrs))
624 		return false;
625 	if (xdr_stream_decode_u32(xdr, &args->tlen) < 0)
626 		return false;
627 
628 	/* symlink_data */
629 	args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
630 	args->first.iov_base = xdr_inline_decode(xdr, args->tlen);
631 	return args->first.iov_base != NULL;
632 }
633 
634 bool
635 nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
636 {
637 	struct nfsd3_mknodargs *args = rqstp->rq_argp;
638 
639 	if (!svcxdr_decode_diropargs3(xdr, &args->fh, &args->name, &args->len))
640 		return false;
641 	if (xdr_stream_decode_u32(xdr, &args->ftype) < 0)
642 		return false;
643 	switch (args->ftype) {
644 	case NF3CHR:
645 	case NF3BLK:
646 		return svcxdr_decode_devicedata3(rqstp, xdr, args);
647 	case NF3SOCK:
648 	case NF3FIFO:
649 		return svcxdr_decode_sattr3(rqstp, xdr, &args->attrs);
650 	case NF3REG:
651 	case NF3DIR:
652 	case NF3LNK:
653 		/* Valid XDR but illegal file types */
654 		break;
655 	default:
656 		return false;
657 	}
658 
659 	return true;
660 }
661 
662 bool
663 nfs3svc_decode_renameargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
664 {
665 	struct nfsd3_renameargs *args = rqstp->rq_argp;
666 
667 	return svcxdr_decode_diropargs3(xdr, &args->ffh,
668 					&args->fname, &args->flen) &&
669 		svcxdr_decode_diropargs3(xdr, &args->tfh,
670 					 &args->tname, &args->tlen);
671 }
672 
673 bool
674 nfs3svc_decode_linkargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
675 {
676 	struct nfsd3_linkargs *args = rqstp->rq_argp;
677 
678 	return svcxdr_decode_nfs_fh3(xdr, &args->ffh) &&
679 		svcxdr_decode_diropargs3(xdr, &args->tfh,
680 					 &args->tname, &args->tlen);
681 }
682 
683 bool
684 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
685 {
686 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
687 
688 	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
689 		return false;
690 	if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
691 		return false;
692 	args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
693 	if (!args->verf)
694 		return false;
695 	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
696 		return false;
697 
698 	return true;
699 }
700 
701 bool
702 nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
703 {
704 	struct nfsd3_readdirargs *args = rqstp->rq_argp;
705 	u32 dircount;
706 
707 	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
708 		return false;
709 	if (xdr_stream_decode_u64(xdr, &args->cookie) < 0)
710 		return false;
711 	args->verf = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE);
712 	if (!args->verf)
713 		return false;
714 	/* dircount is ignored */
715 	if (xdr_stream_decode_u32(xdr, &dircount) < 0)
716 		return false;
717 	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
718 		return false;
719 
720 	return true;
721 }
722 
723 bool
724 nfs3svc_decode_commitargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
725 {
726 	struct nfsd3_commitargs *args = rqstp->rq_argp;
727 
728 	if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
729 		return false;
730 	if (xdr_stream_decode_u64(xdr, &args->offset) < 0)
731 		return false;
732 	if (xdr_stream_decode_u32(xdr, &args->count) < 0)
733 		return false;
734 
735 	return true;
736 }
737 
738 /*
739  * XDR encode functions
740  */
741 
742 /* GETATTR */
743 bool
744 nfs3svc_encode_getattrres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
745 {
746 	struct nfsd3_attrstat *resp = rqstp->rq_resp;
747 
748 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
749 		return false;
750 	switch (resp->status) {
751 	case nfs_ok:
752 		lease_get_mtime(d_inode(resp->fh.fh_dentry), &resp->stat.mtime);
753 		if (!svcxdr_encode_fattr3(rqstp, xdr, &resp->fh, &resp->stat))
754 			return false;
755 		break;
756 	}
757 
758 	return true;
759 }
760 
761 /* SETATTR, REMOVE, RMDIR */
762 bool
763 nfs3svc_encode_wccstat(struct svc_rqst *rqstp, struct xdr_stream *xdr)
764 {
765 	struct nfsd3_attrstat *resp = rqstp->rq_resp;
766 
767 	return svcxdr_encode_nfsstat3(xdr, resp->status) &&
768 		svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh);
769 }
770 
771 /* LOOKUP */
772 bool
773 nfs3svc_encode_lookupres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
774 {
775 	struct nfsd3_diropres *resp = rqstp->rq_resp;
776 
777 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
778 		return false;
779 	switch (resp->status) {
780 	case nfs_ok:
781 		if (!svcxdr_encode_nfs_fh3(xdr, &resp->fh))
782 			return false;
783 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
784 			return false;
785 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh))
786 			return false;
787 		break;
788 	default:
789 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->dirfh))
790 			return false;
791 	}
792 
793 	return true;
794 }
795 
796 /* ACCESS */
797 bool
798 nfs3svc_encode_accessres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
799 {
800 	struct nfsd3_accessres *resp = rqstp->rq_resp;
801 
802 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
803 		return false;
804 	switch (resp->status) {
805 	case nfs_ok:
806 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
807 			return false;
808 		if (xdr_stream_encode_u32(xdr, resp->access) < 0)
809 			return false;
810 		break;
811 	default:
812 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
813 			return false;
814 	}
815 
816 	return true;
817 }
818 
819 /* READLINK */
820 bool
821 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
822 {
823 	struct nfsd3_readlinkres *resp = rqstp->rq_resp;
824 	struct kvec *head = rqstp->rq_res.head;
825 
826 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
827 		return false;
828 	switch (resp->status) {
829 	case nfs_ok:
830 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
831 			return false;
832 		if (xdr_stream_encode_u32(xdr, resp->len) < 0)
833 			return false;
834 		svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages, 0,
835 					   resp->len);
836 		if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0)
837 			return false;
838 		break;
839 	default:
840 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
841 			return false;
842 	}
843 
844 	return true;
845 }
846 
847 /* READ */
848 bool
849 nfs3svc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
850 {
851 	struct nfsd3_readres *resp = rqstp->rq_resp;
852 	struct kvec *head = rqstp->rq_res.head;
853 
854 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
855 		return false;
856 	switch (resp->status) {
857 	case nfs_ok:
858 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
859 			return false;
860 		if (xdr_stream_encode_u32(xdr, resp->count) < 0)
861 			return false;
862 		if (xdr_stream_encode_bool(xdr, resp->eof) < 0)
863 			return false;
864 		if (xdr_stream_encode_u32(xdr, resp->count) < 0)
865 			return false;
866 		svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages,
867 					   rqstp->rq_res.page_base,
868 					   resp->count);
869 		if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0)
870 			return false;
871 		break;
872 	default:
873 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
874 			return false;
875 	}
876 
877 	return true;
878 }
879 
880 /* WRITE */
881 bool
882 nfs3svc_encode_writeres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
883 {
884 	struct nfsd3_writeres *resp = rqstp->rq_resp;
885 
886 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
887 		return false;
888 	switch (resp->status) {
889 	case nfs_ok:
890 		if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
891 			return false;
892 		if (xdr_stream_encode_u32(xdr, resp->count) < 0)
893 			return false;
894 		if (xdr_stream_encode_u32(xdr, resp->committed) < 0)
895 			return false;
896 		if (!svcxdr_encode_writeverf3(xdr, resp->verf))
897 			return false;
898 		break;
899 	default:
900 		if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
901 			return false;
902 	}
903 
904 	return true;
905 }
906 
907 /* CREATE, MKDIR, SYMLINK, MKNOD */
908 bool
909 nfs3svc_encode_createres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
910 {
911 	struct nfsd3_diropres *resp = rqstp->rq_resp;
912 
913 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
914 		return false;
915 	switch (resp->status) {
916 	case nfs_ok:
917 		if (!svcxdr_encode_post_op_fh3(xdr, &resp->fh))
918 			return false;
919 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
920 			return false;
921 		if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh))
922 			return false;
923 		break;
924 	default:
925 		if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->dirfh))
926 			return false;
927 	}
928 
929 	return true;
930 }
931 
932 /* RENAME */
933 bool
934 nfs3svc_encode_renameres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
935 {
936 	struct nfsd3_renameres *resp = rqstp->rq_resp;
937 
938 	return svcxdr_encode_nfsstat3(xdr, resp->status) &&
939 		svcxdr_encode_wcc_data(rqstp, xdr, &resp->ffh) &&
940 		svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh);
941 }
942 
943 /* LINK */
944 bool
945 nfs3svc_encode_linkres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
946 {
947 	struct nfsd3_linkres *resp = rqstp->rq_resp;
948 
949 	return svcxdr_encode_nfsstat3(xdr, resp->status) &&
950 		svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh) &&
951 		svcxdr_encode_wcc_data(rqstp, xdr, &resp->tfh);
952 }
953 
954 /* READDIR */
955 bool
956 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
957 {
958 	struct nfsd3_readdirres *resp = rqstp->rq_resp;
959 	struct xdr_buf *dirlist = &resp->dirlist;
960 
961 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
962 		return false;
963 	switch (resp->status) {
964 	case nfs_ok:
965 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
966 			return false;
967 		if (!svcxdr_encode_cookieverf3(xdr, resp->verf))
968 			return false;
969 		svcxdr_encode_opaque_pages(rqstp, xdr, dirlist->pages, 0,
970 					   dirlist->len);
971 		/* no more entries */
972 		if (xdr_stream_encode_item_absent(xdr) < 0)
973 			return false;
974 		if (xdr_stream_encode_bool(xdr, resp->common.err == nfserr_eof) < 0)
975 			return false;
976 		break;
977 	default:
978 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &resp->fh))
979 			return false;
980 	}
981 
982 	return true;
983 }
984 
985 static __be32
986 compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
987 		 const char *name, int namlen, u64 ino)
988 {
989 	struct svc_export	*exp;
990 	struct dentry		*dparent, *dchild;
991 	__be32 rv = nfserr_noent;
992 
993 	dparent = cd->fh.fh_dentry;
994 	exp  = cd->fh.fh_export;
995 
996 	if (name_is_dot_dotdot(name, namlen)) {
997 		if (namlen == 2) {
998 			dchild = dget_parent(dparent);
999 			/*
1000 			 * Don't return filehandle for ".." if we're at
1001 			 * the filesystem or export root:
1002 			 */
1003 			if (dchild == dparent)
1004 				goto out;
1005 			if (dparent == exp->ex_path.dentry)
1006 				goto out;
1007 		} else
1008 			dchild = dget(dparent);
1009 	} else
1010 		dchild = lookup_one_positive_unlocked(&nop_mnt_idmap,
1011 						      &QSTR_LEN(name, namlen),
1012 						      dparent);
1013 	if (IS_ERR(dchild))
1014 		return rv;
1015 	if (d_mountpoint(dchild))
1016 		goto out;
1017 	if (dchild->d_inode->i_ino != ino)
1018 		goto out;
1019 	rv = fh_compose(fhp, exp, dchild, &cd->fh);
1020 out:
1021 	dput(dchild);
1022 	return rv;
1023 }
1024 
1025 /**
1026  * nfs3svc_encode_cookie3 - Encode a directory offset cookie
1027  * @resp: readdir result context
1028  * @offset: offset cookie to encode
1029  *
1030  * The buffer space for the offset cookie has already been reserved
1031  * by svcxdr_encode_entry3_common().
1032  */
1033 void nfs3svc_encode_cookie3(struct nfsd3_readdirres *resp, u64 offset)
1034 {
1035 	__be64 cookie = cpu_to_be64(offset);
1036 
1037 	if (!resp->cookie_offset)
1038 		return;
1039 	write_bytes_to_xdr_buf(&resp->dirlist, resp->cookie_offset, &cookie,
1040 			       sizeof(cookie));
1041 	resp->cookie_offset = 0;
1042 }
1043 
1044 static bool
1045 svcxdr_encode_entry3_common(struct nfsd3_readdirres *resp, const char *name,
1046 			    int namlen, loff_t offset, u64 ino)
1047 {
1048 	struct xdr_buf *dirlist = &resp->dirlist;
1049 	struct xdr_stream *xdr = &resp->xdr;
1050 
1051 	if (xdr_stream_encode_item_present(xdr) < 0)
1052 		return false;
1053 	/* fileid */
1054 	if (xdr_stream_encode_u64(xdr, ino) < 0)
1055 		return false;
1056 	/* name */
1057 	if (xdr_stream_encode_opaque(xdr, name, min(namlen, NFS3_MAXNAMLEN)) < 0)
1058 		return false;
1059 	/* cookie */
1060 	resp->cookie_offset = dirlist->len;
1061 	if (xdr_stream_encode_u64(xdr, OFFSET_MAX) < 0)
1062 		return false;
1063 
1064 	return true;
1065 }
1066 
1067 /**
1068  * nfs3svc_encode_entry3 - encode one NFSv3 READDIR entry
1069  * @data: directory context
1070  * @name: name of the object to be encoded
1071  * @namlen: length of that name, in bytes
1072  * @offset: the offset of the previous entry
1073  * @ino: the fileid of this entry
1074  * @d_type: unused
1075  *
1076  * Return values:
1077  *   %0: Entry was successfully encoded.
1078  *   %-EINVAL: An encoding problem occurred, secondary status code in resp->common.err
1079  *
1080  * On exit, the following fields are updated:
1081  *   - resp->xdr
1082  *   - resp->common.err
1083  *   - resp->cookie_offset
1084  */
1085 int nfs3svc_encode_entry3(void *data, const char *name, int namlen,
1086 			  loff_t offset, u64 ino, unsigned int d_type)
1087 {
1088 	struct readdir_cd *ccd = data;
1089 	struct nfsd3_readdirres *resp = container_of(ccd,
1090 						     struct nfsd3_readdirres,
1091 						     common);
1092 	unsigned int starting_length = resp->dirlist.len;
1093 
1094 	/* The offset cookie for the previous entry */
1095 	nfs3svc_encode_cookie3(resp, offset);
1096 
1097 	if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino))
1098 		goto out_toosmall;
1099 
1100 	xdr_commit_encode(&resp->xdr);
1101 	resp->common.err = nfs_ok;
1102 	return 0;
1103 
1104 out_toosmall:
1105 	resp->cookie_offset = 0;
1106 	resp->common.err = nfserr_toosmall;
1107 	resp->dirlist.len = starting_length;
1108 	return -EINVAL;
1109 }
1110 
1111 static bool
1112 svcxdr_encode_entry3_plus(struct nfsd3_readdirres *resp, const char *name,
1113 			  int namlen, u64 ino)
1114 {
1115 	struct xdr_stream *xdr = &resp->xdr;
1116 	struct svc_fh *fhp = &resp->scratch;
1117 	bool result;
1118 
1119 	result = false;
1120 	fh_init(fhp, NFS3_FHSIZE);
1121 	if (compose_entry_fh(resp, fhp, name, namlen, ino) != nfs_ok)
1122 		goto out_noattrs;
1123 
1124 	if (!svcxdr_encode_post_op_attr(resp->rqstp, xdr, fhp))
1125 		goto out;
1126 	if (!svcxdr_encode_post_op_fh3(xdr, fhp))
1127 		goto out;
1128 	result = true;
1129 
1130 out:
1131 	fh_put(fhp);
1132 	return result;
1133 
1134 out_noattrs:
1135 	if (xdr_stream_encode_item_absent(xdr) < 0)
1136 		return false;
1137 	if (xdr_stream_encode_item_absent(xdr) < 0)
1138 		return false;
1139 	return true;
1140 }
1141 
1142 /**
1143  * nfs3svc_encode_entryplus3 - encode one NFSv3 READDIRPLUS entry
1144  * @data: directory context
1145  * @name: name of the object to be encoded
1146  * @namlen: length of that name, in bytes
1147  * @offset: the offset of the previous entry
1148  * @ino: the fileid of this entry
1149  * @d_type: unused
1150  *
1151  * Return values:
1152  *   %0: Entry was successfully encoded.
1153  *   %-EINVAL: An encoding problem occurred, secondary status code in resp->common.err
1154  *
1155  * On exit, the following fields are updated:
1156  *   - resp->xdr
1157  *   - resp->common.err
1158  *   - resp->cookie_offset
1159  */
1160 int nfs3svc_encode_entryplus3(void *data, const char *name, int namlen,
1161 			      loff_t offset, u64 ino, unsigned int d_type)
1162 {
1163 	struct readdir_cd *ccd = data;
1164 	struct nfsd3_readdirres *resp = container_of(ccd,
1165 						     struct nfsd3_readdirres,
1166 						     common);
1167 	unsigned int starting_length = resp->dirlist.len;
1168 
1169 	/* The offset cookie for the previous entry */
1170 	nfs3svc_encode_cookie3(resp, offset);
1171 
1172 	if (!svcxdr_encode_entry3_common(resp, name, namlen, offset, ino))
1173 		goto out_toosmall;
1174 	if (!svcxdr_encode_entry3_plus(resp, name, namlen, ino))
1175 		goto out_toosmall;
1176 
1177 	xdr_commit_encode(&resp->xdr);
1178 	resp->common.err = nfs_ok;
1179 	return 0;
1180 
1181 out_toosmall:
1182 	resp->cookie_offset = 0;
1183 	resp->common.err = nfserr_toosmall;
1184 	resp->dirlist.len = starting_length;
1185 	return -EINVAL;
1186 }
1187 
1188 static bool
1189 svcxdr_encode_fsstat3resok(struct xdr_stream *xdr,
1190 			   const struct nfsd3_fsstatres *resp)
1191 {
1192 	const struct kstatfs *s = &resp->stats;
1193 	u64 bs = s->f_bsize;
1194 	__be32 *p;
1195 
1196 	p = xdr_reserve_space(xdr, XDR_UNIT * 13);
1197 	if (!p)
1198 		return false;
1199 	p = xdr_encode_hyper(p, bs * s->f_blocks);	/* total bytes */
1200 	p = xdr_encode_hyper(p, bs * s->f_bfree);	/* free bytes */
1201 	p = xdr_encode_hyper(p, bs * s->f_bavail);	/* user available bytes */
1202 	p = xdr_encode_hyper(p, s->f_files);		/* total inodes */
1203 	p = xdr_encode_hyper(p, s->f_ffree);		/* free inodes */
1204 	p = xdr_encode_hyper(p, s->f_ffree);		/* user available inodes */
1205 	*p = cpu_to_be32(resp->invarsec);		/* mean unchanged time */
1206 
1207 	return true;
1208 }
1209 
1210 /* FSSTAT */
1211 bool
1212 nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1213 {
1214 	struct nfsd3_fsstatres *resp = rqstp->rq_resp;
1215 
1216 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1217 		return false;
1218 	switch (resp->status) {
1219 	case nfs_ok:
1220 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1221 			return false;
1222 		if (!svcxdr_encode_fsstat3resok(xdr, resp))
1223 			return false;
1224 		break;
1225 	default:
1226 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1227 			return false;
1228 	}
1229 
1230 	return true;
1231 }
1232 
1233 static bool
1234 svcxdr_encode_fsinfo3resok(struct xdr_stream *xdr,
1235 			   const struct nfsd3_fsinfores *resp)
1236 {
1237 	__be32 *p;
1238 
1239 	p = xdr_reserve_space(xdr, XDR_UNIT * 12);
1240 	if (!p)
1241 		return false;
1242 	*p++ = cpu_to_be32(resp->f_rtmax);
1243 	*p++ = cpu_to_be32(resp->f_rtpref);
1244 	*p++ = cpu_to_be32(resp->f_rtmult);
1245 	*p++ = cpu_to_be32(resp->f_wtmax);
1246 	*p++ = cpu_to_be32(resp->f_wtpref);
1247 	*p++ = cpu_to_be32(resp->f_wtmult);
1248 	*p++ = cpu_to_be32(resp->f_dtpref);
1249 	p = xdr_encode_hyper(p, resp->f_maxfilesize);
1250 	p = encode_nfstime3(p, &nfs3svc_time_delta);
1251 	*p = cpu_to_be32(resp->f_properties);
1252 
1253 	return true;
1254 }
1255 
1256 /* FSINFO */
1257 bool
1258 nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1259 {
1260 	struct nfsd3_fsinfores *resp = rqstp->rq_resp;
1261 
1262 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1263 		return false;
1264 	switch (resp->status) {
1265 	case nfs_ok:
1266 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1267 			return false;
1268 		if (!svcxdr_encode_fsinfo3resok(xdr, resp))
1269 			return false;
1270 		break;
1271 	default:
1272 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1273 			return false;
1274 	}
1275 
1276 	return true;
1277 }
1278 
1279 static bool
1280 svcxdr_encode_pathconf3resok(struct xdr_stream *xdr,
1281 			     const struct nfsd3_pathconfres *resp)
1282 {
1283 	__be32 *p;
1284 
1285 	p = xdr_reserve_space(xdr, XDR_UNIT * 6);
1286 	if (!p)
1287 		return false;
1288 	*p++ = cpu_to_be32(resp->p_link_max);
1289 	*p++ = cpu_to_be32(resp->p_name_max);
1290 	p = xdr_encode_bool(p, resp->p_no_trunc);
1291 	p = xdr_encode_bool(p, resp->p_chown_restricted);
1292 	p = xdr_encode_bool(p, resp->p_case_insensitive);
1293 	xdr_encode_bool(p, resp->p_case_preserving);
1294 
1295 	return true;
1296 }
1297 
1298 /* PATHCONF */
1299 bool
1300 nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1301 {
1302 	struct nfsd3_pathconfres *resp = rqstp->rq_resp;
1303 
1304 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1305 		return false;
1306 	switch (resp->status) {
1307 	case nfs_ok:
1308 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1309 			return false;
1310 		if (!svcxdr_encode_pathconf3resok(xdr, resp))
1311 			return false;
1312 		break;
1313 	default:
1314 		if (!svcxdr_encode_post_op_attr(rqstp, xdr, &nfs3svc_null_fh))
1315 			return false;
1316 	}
1317 
1318 	return true;
1319 }
1320 
1321 /* COMMIT */
1322 bool
1323 nfs3svc_encode_commitres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
1324 {
1325 	struct nfsd3_commitres *resp = rqstp->rq_resp;
1326 
1327 	if (!svcxdr_encode_nfsstat3(xdr, resp->status))
1328 		return false;
1329 	switch (resp->status) {
1330 	case nfs_ok:
1331 		if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
1332 			return false;
1333 		if (!svcxdr_encode_writeverf3(xdr, resp->verf))
1334 			return false;
1335 		break;
1336 	default:
1337 		if (!svcxdr_encode_wcc_data(rqstp, xdr, &resp->fh))
1338 			return false;
1339 	}
1340 
1341 	return true;
1342 }
1343 
1344 /*
1345  * XDR release functions
1346  */
1347 void
1348 nfs3svc_release_fhandle(struct svc_rqst *rqstp)
1349 {
1350 	struct nfsd3_attrstat *resp = rqstp->rq_resp;
1351 
1352 	fh_put(&resp->fh);
1353 }
1354 
1355 void
1356 nfs3svc_release_fhandle2(struct svc_rqst *rqstp)
1357 {
1358 	struct nfsd3_fhandle_pair *resp = rqstp->rq_resp;
1359 
1360 	fh_put(&resp->fh1);
1361 	fh_put(&resp->fh2);
1362 }
1363