xref: /openbmc/linux/fs/nfs/callback_xdr.c (revision de2bdb3d)
1 /*
2  * linux/fs/nfs/callback_xdr.c
3  *
4  * Copyright (C) 2004 Trond Myklebust
5  *
6  * NFSv4 callback encode/decode procedures
7  */
8 #include <linux/kernel.h>
9 #include <linux/sunrpc/svc.h>
10 #include <linux/nfs4.h>
11 #include <linux/nfs_fs.h>
12 #include <linux/ratelimit.h>
13 #include <linux/printk.h>
14 #include <linux/slab.h>
15 #include <linux/sunrpc/bc_xprt.h>
16 #include "nfs4_fs.h"
17 #include "callback.h"
18 #include "internal.h"
19 #include "nfs4session.h"
20 
21 #define CB_OP_TAGLEN_MAXSZ		(512)
22 #define CB_OP_HDR_RES_MAXSZ		(2 * 4) // opcode, status
23 #define CB_OP_GETATTR_BITMAP_MAXSZ	(4 * 4) // bitmap length, 3 bitmaps
24 #define CB_OP_GETATTR_RES_MAXSZ		(CB_OP_HDR_RES_MAXSZ + \
25 					 CB_OP_GETATTR_BITMAP_MAXSZ + \
26 					 /* change, size, ctime, mtime */\
27 					 (2 + 2 + 3 + 3) * 4)
28 #define CB_OP_RECALL_RES_MAXSZ		(CB_OP_HDR_RES_MAXSZ)
29 
30 #if defined(CONFIG_NFS_V4_1)
31 #define CB_OP_LAYOUTRECALL_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ)
32 #define CB_OP_DEVICENOTIFY_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ)
33 #define CB_OP_SEQUENCE_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ + \
34 					 NFS4_MAX_SESSIONID_LEN + \
35 					 (1 + 3) * 4) // seqid, 3 slotids
36 #define CB_OP_RECALLANY_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ)
37 #define CB_OP_RECALLSLOT_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ)
38 #define CB_OP_NOTIFY_LOCK_RES_MAXSZ	(CB_OP_HDR_RES_MAXSZ)
39 #endif /* CONFIG_NFS_V4_1 */
40 
41 #define NFSDBG_FACILITY NFSDBG_CALLBACK
42 
43 /* Internal error code */
44 #define NFS4ERR_RESOURCE_HDR	11050
45 
46 typedef __be32 (*callback_process_op_t)(void *, void *,
47 					struct cb_process_state *);
48 typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *);
49 typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *);
50 
51 
52 struct callback_op {
53 	callback_process_op_t process_op;
54 	callback_decode_arg_t decode_args;
55 	callback_encode_res_t encode_res;
56 	long res_maxsize;
57 };
58 
59 static struct callback_op callback_ops[];
60 
61 static __be32 nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp)
62 {
63 	return htonl(NFS4_OK);
64 }
65 
66 static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
67 {
68 	return xdr_argsize_check(rqstp, p);
69 }
70 
71 static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy)
72 {
73 	return xdr_ressize_check(rqstp, p);
74 }
75 
76 static __be32 *read_buf(struct xdr_stream *xdr, size_t nbytes)
77 {
78 	__be32 *p;
79 
80 	p = xdr_inline_decode(xdr, nbytes);
81 	if (unlikely(p == NULL))
82 		printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n");
83 	return p;
84 }
85 
86 static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, const char **str)
87 {
88 	__be32 *p;
89 
90 	p = read_buf(xdr, 4);
91 	if (unlikely(p == NULL))
92 		return htonl(NFS4ERR_RESOURCE);
93 	*len = ntohl(*p);
94 
95 	if (*len != 0) {
96 		p = read_buf(xdr, *len);
97 		if (unlikely(p == NULL))
98 			return htonl(NFS4ERR_RESOURCE);
99 		*str = (const char *)p;
100 	} else
101 		*str = NULL;
102 
103 	return 0;
104 }
105 
106 static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh)
107 {
108 	__be32 *p;
109 
110 	p = read_buf(xdr, 4);
111 	if (unlikely(p == NULL))
112 		return htonl(NFS4ERR_RESOURCE);
113 	fh->size = ntohl(*p);
114 	if (fh->size > NFS4_FHSIZE)
115 		return htonl(NFS4ERR_BADHANDLE);
116 	p = read_buf(xdr, fh->size);
117 	if (unlikely(p == NULL))
118 		return htonl(NFS4ERR_RESOURCE);
119 	memcpy(&fh->data[0], p, fh->size);
120 	memset(&fh->data[fh->size], 0, sizeof(fh->data) - fh->size);
121 	return 0;
122 }
123 
124 static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
125 {
126 	__be32 *p;
127 	unsigned int attrlen;
128 
129 	p = read_buf(xdr, 4);
130 	if (unlikely(p == NULL))
131 		return htonl(NFS4ERR_RESOURCE);
132 	attrlen = ntohl(*p);
133 	p = read_buf(xdr, attrlen << 2);
134 	if (unlikely(p == NULL))
135 		return htonl(NFS4ERR_RESOURCE);
136 	if (likely(attrlen > 0))
137 		bitmap[0] = ntohl(*p++);
138 	if (attrlen > 1)
139 		bitmap[1] = ntohl(*p);
140 	return 0;
141 }
142 
143 static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
144 {
145 	__be32 *p;
146 
147 	p = read_buf(xdr, NFS4_STATEID_SIZE);
148 	if (unlikely(p == NULL))
149 		return htonl(NFS4ERR_RESOURCE);
150 	memcpy(stateid->data, p, NFS4_STATEID_SIZE);
151 	return 0;
152 }
153 
154 static __be32 decode_delegation_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
155 {
156 	stateid->type = NFS4_DELEGATION_STATEID_TYPE;
157 	return decode_stateid(xdr, stateid);
158 }
159 
160 static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound_hdr_arg *hdr)
161 {
162 	__be32 *p;
163 	__be32 status;
164 
165 	status = decode_string(xdr, &hdr->taglen, &hdr->tag);
166 	if (unlikely(status != 0))
167 		return status;
168 	/* We do not like overly long tags! */
169 	if (hdr->taglen > CB_OP_TAGLEN_MAXSZ) {
170 		printk("NFS: NFSv4 CALLBACK %s: client sent tag of length %u\n",
171 				__func__, hdr->taglen);
172 		return htonl(NFS4ERR_RESOURCE);
173 	}
174 	p = read_buf(xdr, 12);
175 	if (unlikely(p == NULL))
176 		return htonl(NFS4ERR_RESOURCE);
177 	hdr->minorversion = ntohl(*p++);
178 	/* Check for minor version support */
179 	if (hdr->minorversion <= NFS4_MAX_MINOR_VERSION) {
180 		hdr->cb_ident = ntohl(*p++); /* ignored by v4.1 and v4.2 */
181 	} else {
182 		pr_warn_ratelimited("NFS: %s: NFSv4 server callback with "
183 			"illegal minor version %u!\n",
184 			__func__, hdr->minorversion);
185 		return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
186 	}
187 	hdr->nops = ntohl(*p);
188 	dprintk("%s: minorversion %d nops %d\n", __func__,
189 		hdr->minorversion, hdr->nops);
190 	return 0;
191 }
192 
193 static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op)
194 {
195 	__be32 *p;
196 	p = read_buf(xdr, 4);
197 	if (unlikely(p == NULL))
198 		return htonl(NFS4ERR_RESOURCE_HDR);
199 	*op = ntohl(*p);
200 	return 0;
201 }
202 
203 static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args)
204 {
205 	__be32 status;
206 
207 	status = decode_fh(xdr, &args->fh);
208 	if (unlikely(status != 0))
209 		goto out;
210 	status = decode_bitmap(xdr, args->bitmap);
211 out:
212 	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
213 	return status;
214 }
215 
216 static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args)
217 {
218 	__be32 *p;
219 	__be32 status;
220 
221 	status = decode_delegation_stateid(xdr, &args->stateid);
222 	if (unlikely(status != 0))
223 		goto out;
224 	p = read_buf(xdr, 4);
225 	if (unlikely(p == NULL)) {
226 		status = htonl(NFS4ERR_RESOURCE);
227 		goto out;
228 	}
229 	args->truncate = ntohl(*p);
230 	status = decode_fh(xdr, &args->fh);
231 out:
232 	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
233 	return status;
234 }
235 
236 #if defined(CONFIG_NFS_V4_1)
237 static __be32 decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid)
238 {
239 	stateid->type = NFS4_LAYOUT_STATEID_TYPE;
240 	return decode_stateid(xdr, stateid);
241 }
242 
243 static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp,
244 				       struct xdr_stream *xdr,
245 				       struct cb_layoutrecallargs *args)
246 {
247 	__be32 *p;
248 	__be32 status = 0;
249 	uint32_t iomode;
250 
251 	p = read_buf(xdr, 4 * sizeof(uint32_t));
252 	if (unlikely(p == NULL)) {
253 		status = htonl(NFS4ERR_BADXDR);
254 		goto out;
255 	}
256 
257 	args->cbl_layout_type = ntohl(*p++);
258 	/* Depite the spec's xdr, iomode really belongs in the FILE switch,
259 	 * as it is unusable and ignored with the other types.
260 	 */
261 	iomode = ntohl(*p++);
262 	args->cbl_layoutchanged = ntohl(*p++);
263 	args->cbl_recall_type = ntohl(*p++);
264 
265 	if (args->cbl_recall_type == RETURN_FILE) {
266 		args->cbl_range.iomode = iomode;
267 		status = decode_fh(xdr, &args->cbl_fh);
268 		if (unlikely(status != 0))
269 			goto out;
270 
271 		p = read_buf(xdr, 2 * sizeof(uint64_t));
272 		if (unlikely(p == NULL)) {
273 			status = htonl(NFS4ERR_BADXDR);
274 			goto out;
275 		}
276 		p = xdr_decode_hyper(p, &args->cbl_range.offset);
277 		p = xdr_decode_hyper(p, &args->cbl_range.length);
278 		status = decode_layout_stateid(xdr, &args->cbl_stateid);
279 		if (unlikely(status != 0))
280 			goto out;
281 	} else if (args->cbl_recall_type == RETURN_FSID) {
282 		p = read_buf(xdr, 2 * sizeof(uint64_t));
283 		if (unlikely(p == NULL)) {
284 			status = htonl(NFS4ERR_BADXDR);
285 			goto out;
286 		}
287 		p = xdr_decode_hyper(p, &args->cbl_fsid.major);
288 		p = xdr_decode_hyper(p, &args->cbl_fsid.minor);
289 	} else if (args->cbl_recall_type != RETURN_ALL) {
290 		status = htonl(NFS4ERR_BADXDR);
291 		goto out;
292 	}
293 	dprintk("%s: ltype 0x%x iomode %d changed %d recall_type %d\n",
294 		__func__,
295 		args->cbl_layout_type, iomode,
296 		args->cbl_layoutchanged, args->cbl_recall_type);
297 out:
298 	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
299 	return status;
300 }
301 
302 static
303 __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
304 				struct xdr_stream *xdr,
305 				struct cb_devicenotifyargs *args)
306 {
307 	__be32 *p;
308 	__be32 status = 0;
309 	u32 tmp;
310 	int n, i;
311 	args->ndevs = 0;
312 
313 	/* Num of device notifications */
314 	p = read_buf(xdr, sizeof(uint32_t));
315 	if (unlikely(p == NULL)) {
316 		status = htonl(NFS4ERR_BADXDR);
317 		goto out;
318 	}
319 	n = ntohl(*p++);
320 	if (n <= 0)
321 		goto out;
322 	if (n > ULONG_MAX / sizeof(*args->devs)) {
323 		status = htonl(NFS4ERR_BADXDR);
324 		goto out;
325 	}
326 
327 	args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL);
328 	if (!args->devs) {
329 		status = htonl(NFS4ERR_DELAY);
330 		goto out;
331 	}
332 
333 	/* Decode each dev notification */
334 	for (i = 0; i < n; i++) {
335 		struct cb_devicenotifyitem *dev = &args->devs[i];
336 
337 		p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE);
338 		if (unlikely(p == NULL)) {
339 			status = htonl(NFS4ERR_BADXDR);
340 			goto err;
341 		}
342 
343 		tmp = ntohl(*p++);	/* bitmap size */
344 		if (tmp != 1) {
345 			status = htonl(NFS4ERR_INVAL);
346 			goto err;
347 		}
348 		dev->cbd_notify_type = ntohl(*p++);
349 		if (dev->cbd_notify_type != NOTIFY_DEVICEID4_CHANGE &&
350 		    dev->cbd_notify_type != NOTIFY_DEVICEID4_DELETE) {
351 			status = htonl(NFS4ERR_INVAL);
352 			goto err;
353 		}
354 
355 		tmp = ntohl(*p++);	/* opaque size */
356 		if (((dev->cbd_notify_type == NOTIFY_DEVICEID4_CHANGE) &&
357 		     (tmp != NFS4_DEVICEID4_SIZE + 8)) ||
358 		    ((dev->cbd_notify_type == NOTIFY_DEVICEID4_DELETE) &&
359 		     (tmp != NFS4_DEVICEID4_SIZE + 4))) {
360 			status = htonl(NFS4ERR_INVAL);
361 			goto err;
362 		}
363 		dev->cbd_layout_type = ntohl(*p++);
364 		memcpy(dev->cbd_dev_id.data, p, NFS4_DEVICEID4_SIZE);
365 		p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE);
366 
367 		if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) {
368 			p = read_buf(xdr, sizeof(uint32_t));
369 			if (unlikely(p == NULL)) {
370 				status = htonl(NFS4ERR_BADXDR);
371 				goto err;
372 			}
373 			dev->cbd_immediate = ntohl(*p++);
374 		} else {
375 			dev->cbd_immediate = 0;
376 		}
377 
378 		args->ndevs++;
379 
380 		dprintk("%s: type %d layout 0x%x immediate %d\n",
381 			__func__, dev->cbd_notify_type, dev->cbd_layout_type,
382 			dev->cbd_immediate);
383 	}
384 out:
385 	dprintk("%s: status %d ndevs %d\n",
386 		__func__, ntohl(status), args->ndevs);
387 	return status;
388 err:
389 	kfree(args->devs);
390 	goto out;
391 }
392 
393 static __be32 decode_sessionid(struct xdr_stream *xdr,
394 				 struct nfs4_sessionid *sid)
395 {
396 	__be32 *p;
397 
398 	p = read_buf(xdr, NFS4_MAX_SESSIONID_LEN);
399 	if (unlikely(p == NULL))
400 		return htonl(NFS4ERR_RESOURCE);
401 
402 	memcpy(sid->data, p, NFS4_MAX_SESSIONID_LEN);
403 	return 0;
404 }
405 
406 static __be32 decode_rc_list(struct xdr_stream *xdr,
407 			       struct referring_call_list *rc_list)
408 {
409 	__be32 *p;
410 	int i;
411 	__be32 status;
412 
413 	status = decode_sessionid(xdr, &rc_list->rcl_sessionid);
414 	if (status)
415 		goto out;
416 
417 	status = htonl(NFS4ERR_RESOURCE);
418 	p = read_buf(xdr, sizeof(uint32_t));
419 	if (unlikely(p == NULL))
420 		goto out;
421 
422 	rc_list->rcl_nrefcalls = ntohl(*p++);
423 	if (rc_list->rcl_nrefcalls) {
424 		p = read_buf(xdr,
425 			     rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t));
426 		if (unlikely(p == NULL))
427 			goto out;
428 		rc_list->rcl_refcalls = kmalloc_array(rc_list->rcl_nrefcalls,
429 						sizeof(*rc_list->rcl_refcalls),
430 						GFP_KERNEL);
431 		if (unlikely(rc_list->rcl_refcalls == NULL))
432 			goto out;
433 		for (i = 0; i < rc_list->rcl_nrefcalls; i++) {
434 			rc_list->rcl_refcalls[i].rc_sequenceid = ntohl(*p++);
435 			rc_list->rcl_refcalls[i].rc_slotid = ntohl(*p++);
436 		}
437 	}
438 	status = 0;
439 
440 out:
441 	return status;
442 }
443 
444 static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp,
445 					struct xdr_stream *xdr,
446 					struct cb_sequenceargs *args)
447 {
448 	__be32 *p;
449 	int i;
450 	__be32 status;
451 
452 	status = decode_sessionid(xdr, &args->csa_sessionid);
453 	if (status)
454 		goto out;
455 
456 	status = htonl(NFS4ERR_RESOURCE);
457 	p = read_buf(xdr, 5 * sizeof(uint32_t));
458 	if (unlikely(p == NULL))
459 		goto out;
460 
461 	args->csa_addr = svc_addr(rqstp);
462 	args->csa_sequenceid = ntohl(*p++);
463 	args->csa_slotid = ntohl(*p++);
464 	args->csa_highestslotid = ntohl(*p++);
465 	args->csa_cachethis = ntohl(*p++);
466 	args->csa_nrclists = ntohl(*p++);
467 	args->csa_rclists = NULL;
468 	if (args->csa_nrclists) {
469 		args->csa_rclists = kmalloc_array(args->csa_nrclists,
470 						  sizeof(*args->csa_rclists),
471 						  GFP_KERNEL);
472 		if (unlikely(args->csa_rclists == NULL))
473 			goto out;
474 
475 		for (i = 0; i < args->csa_nrclists; i++) {
476 			status = decode_rc_list(xdr, &args->csa_rclists[i]);
477 			if (status) {
478 				args->csa_nrclists = i;
479 				goto out_free;
480 			}
481 		}
482 	}
483 	status = 0;
484 
485 	dprintk("%s: sessionid %x:%x:%x:%x sequenceid %u slotid %u "
486 		"highestslotid %u cachethis %d nrclists %u\n",
487 		__func__,
488 		((u32 *)&args->csa_sessionid)[0],
489 		((u32 *)&args->csa_sessionid)[1],
490 		((u32 *)&args->csa_sessionid)[2],
491 		((u32 *)&args->csa_sessionid)[3],
492 		args->csa_sequenceid, args->csa_slotid,
493 		args->csa_highestslotid, args->csa_cachethis,
494 		args->csa_nrclists);
495 out:
496 	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
497 	return status;
498 
499 out_free:
500 	for (i = 0; i < args->csa_nrclists; i++)
501 		kfree(args->csa_rclists[i].rcl_refcalls);
502 	kfree(args->csa_rclists);
503 	goto out;
504 }
505 
506 static __be32 decode_recallany_args(struct svc_rqst *rqstp,
507 				      struct xdr_stream *xdr,
508 				      struct cb_recallanyargs *args)
509 {
510 	uint32_t bitmap[2];
511 	__be32 *p, status;
512 
513 	p = read_buf(xdr, 4);
514 	if (unlikely(p == NULL))
515 		return htonl(NFS4ERR_BADXDR);
516 	args->craa_objs_to_keep = ntohl(*p++);
517 	status = decode_bitmap(xdr, bitmap);
518 	if (unlikely(status))
519 		return status;
520 	args->craa_type_mask = bitmap[0];
521 
522 	return 0;
523 }
524 
525 static __be32 decode_recallslot_args(struct svc_rqst *rqstp,
526 					struct xdr_stream *xdr,
527 					struct cb_recallslotargs *args)
528 {
529 	__be32 *p;
530 
531 	p = read_buf(xdr, 4);
532 	if (unlikely(p == NULL))
533 		return htonl(NFS4ERR_BADXDR);
534 	args->crsa_target_highest_slotid = ntohl(*p++);
535 	return 0;
536 }
537 
538 static __be32 decode_lockowner(struct xdr_stream *xdr, struct cb_notify_lock_args *args)
539 {
540 	__be32		*p;
541 	unsigned int	len;
542 
543 	p = read_buf(xdr, 12);
544 	if (unlikely(p == NULL))
545 		return htonl(NFS4ERR_BADXDR);
546 
547 	p = xdr_decode_hyper(p, &args->cbnl_owner.clientid);
548 	len = be32_to_cpu(*p);
549 
550 	p = read_buf(xdr, len);
551 	if (unlikely(p == NULL))
552 		return htonl(NFS4ERR_BADXDR);
553 
554 	/* Only try to decode if the length is right */
555 	if (len == 20) {
556 		p += 2;	/* skip "lock id:" */
557 		args->cbnl_owner.s_dev = be32_to_cpu(*p++);
558 		xdr_decode_hyper(p, &args->cbnl_owner.id);
559 		args->cbnl_valid = true;
560 	} else {
561 		args->cbnl_owner.s_dev = 0;
562 		args->cbnl_owner.id = 0;
563 		args->cbnl_valid = false;
564 	}
565 	return 0;
566 }
567 
568 static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_notify_lock_args *args)
569 {
570 	__be32 status;
571 
572 	status = decode_fh(xdr, &args->cbnl_fh);
573 	if (unlikely(status != 0))
574 		goto out;
575 	status = decode_lockowner(xdr, args);
576 out:
577 	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
578 	return status;
579 }
580 
581 #endif /* CONFIG_NFS_V4_1 */
582 
583 static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
584 {
585 	__be32 *p;
586 
587 	p = xdr_reserve_space(xdr, 4 + len);
588 	if (unlikely(p == NULL))
589 		return htonl(NFS4ERR_RESOURCE);
590 	xdr_encode_opaque(p, str, len);
591 	return 0;
592 }
593 
594 #define CB_SUPPORTED_ATTR0 (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE)
595 #define CB_SUPPORTED_ATTR1 (FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY)
596 static __be32 encode_attr_bitmap(struct xdr_stream *xdr, const uint32_t *bitmap, __be32 **savep)
597 {
598 	__be32 bm[2];
599 	__be32 *p;
600 
601 	bm[0] = htonl(bitmap[0] & CB_SUPPORTED_ATTR0);
602 	bm[1] = htonl(bitmap[1] & CB_SUPPORTED_ATTR1);
603 	if (bm[1] != 0) {
604 		p = xdr_reserve_space(xdr, 16);
605 		if (unlikely(p == NULL))
606 			return htonl(NFS4ERR_RESOURCE);
607 		*p++ = htonl(2);
608 		*p++ = bm[0];
609 		*p++ = bm[1];
610 	} else if (bm[0] != 0) {
611 		p = xdr_reserve_space(xdr, 12);
612 		if (unlikely(p == NULL))
613 			return htonl(NFS4ERR_RESOURCE);
614 		*p++ = htonl(1);
615 		*p++ = bm[0];
616 	} else {
617 		p = xdr_reserve_space(xdr, 8);
618 		if (unlikely(p == NULL))
619 			return htonl(NFS4ERR_RESOURCE);
620 		*p++ = htonl(0);
621 	}
622 	*savep = p;
623 	return 0;
624 }
625 
626 static __be32 encode_attr_change(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t change)
627 {
628 	__be32 *p;
629 
630 	if (!(bitmap[0] & FATTR4_WORD0_CHANGE))
631 		return 0;
632 	p = xdr_reserve_space(xdr, 8);
633 	if (unlikely(!p))
634 		return htonl(NFS4ERR_RESOURCE);
635 	p = xdr_encode_hyper(p, change);
636 	return 0;
637 }
638 
639 static __be32 encode_attr_size(struct xdr_stream *xdr, const uint32_t *bitmap, uint64_t size)
640 {
641 	__be32 *p;
642 
643 	if (!(bitmap[0] & FATTR4_WORD0_SIZE))
644 		return 0;
645 	p = xdr_reserve_space(xdr, 8);
646 	if (unlikely(!p))
647 		return htonl(NFS4ERR_RESOURCE);
648 	p = xdr_encode_hyper(p, size);
649 	return 0;
650 }
651 
652 static __be32 encode_attr_time(struct xdr_stream *xdr, const struct timespec *time)
653 {
654 	__be32 *p;
655 
656 	p = xdr_reserve_space(xdr, 12);
657 	if (unlikely(!p))
658 		return htonl(NFS4ERR_RESOURCE);
659 	p = xdr_encode_hyper(p, time->tv_sec);
660 	*p = htonl(time->tv_nsec);
661 	return 0;
662 }
663 
664 static __be32 encode_attr_ctime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
665 {
666 	if (!(bitmap[1] & FATTR4_WORD1_TIME_METADATA))
667 		return 0;
668 	return encode_attr_time(xdr,time);
669 }
670 
671 static __be32 encode_attr_mtime(struct xdr_stream *xdr, const uint32_t *bitmap, const struct timespec *time)
672 {
673 	if (!(bitmap[1] & FATTR4_WORD1_TIME_MODIFY))
674 		return 0;
675 	return encode_attr_time(xdr,time);
676 }
677 
678 static __be32 encode_compound_hdr_res(struct xdr_stream *xdr, struct cb_compound_hdr_res *hdr)
679 {
680 	__be32 status;
681 
682 	hdr->status = xdr_reserve_space(xdr, 4);
683 	if (unlikely(hdr->status == NULL))
684 		return htonl(NFS4ERR_RESOURCE);
685 	status = encode_string(xdr, hdr->taglen, hdr->tag);
686 	if (unlikely(status != 0))
687 		return status;
688 	hdr->nops = xdr_reserve_space(xdr, 4);
689 	if (unlikely(hdr->nops == NULL))
690 		return htonl(NFS4ERR_RESOURCE);
691 	return 0;
692 }
693 
694 static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res)
695 {
696 	__be32 *p;
697 
698 	p = xdr_reserve_space(xdr, 8);
699 	if (unlikely(p == NULL))
700 		return htonl(NFS4ERR_RESOURCE_HDR);
701 	*p++ = htonl(op);
702 	*p = res;
703 	return 0;
704 }
705 
706 static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res)
707 {
708 	__be32 *savep = NULL;
709 	__be32 status = res->status;
710 
711 	if (unlikely(status != 0))
712 		goto out;
713 	status = encode_attr_bitmap(xdr, res->bitmap, &savep);
714 	if (unlikely(status != 0))
715 		goto out;
716 	status = encode_attr_change(xdr, res->bitmap, res->change_attr);
717 	if (unlikely(status != 0))
718 		goto out;
719 	status = encode_attr_size(xdr, res->bitmap, res->size);
720 	if (unlikely(status != 0))
721 		goto out;
722 	status = encode_attr_ctime(xdr, res->bitmap, &res->ctime);
723 	if (unlikely(status != 0))
724 		goto out;
725 	status = encode_attr_mtime(xdr, res->bitmap, &res->mtime);
726 	*savep = htonl((unsigned int)((char *)xdr->p - (char *)(savep+1)));
727 out:
728 	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
729 	return status;
730 }
731 
732 #if defined(CONFIG_NFS_V4_1)
733 
734 static __be32 encode_sessionid(struct xdr_stream *xdr,
735 				 const struct nfs4_sessionid *sid)
736 {
737 	__be32 *p;
738 
739 	p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN);
740 	if (unlikely(p == NULL))
741 		return htonl(NFS4ERR_RESOURCE);
742 
743 	memcpy(p, sid, NFS4_MAX_SESSIONID_LEN);
744 	return 0;
745 }
746 
747 static __be32 encode_cb_sequence_res(struct svc_rqst *rqstp,
748 				       struct xdr_stream *xdr,
749 				       const struct cb_sequenceres *res)
750 {
751 	__be32 *p;
752 	__be32 status = res->csr_status;
753 
754 	if (unlikely(status != 0))
755 		goto out;
756 
757 	status = encode_sessionid(xdr, &res->csr_sessionid);
758 	if (status)
759 		goto out;
760 
761 	p = xdr_reserve_space(xdr, 4 * sizeof(uint32_t));
762 	if (unlikely(p == NULL))
763 		return htonl(NFS4ERR_RESOURCE);
764 
765 	*p++ = htonl(res->csr_sequenceid);
766 	*p++ = htonl(res->csr_slotid);
767 	*p++ = htonl(res->csr_highestslotid);
768 	*p++ = htonl(res->csr_target_highestslotid);
769 out:
770 	dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
771 	return status;
772 }
773 
774 static __be32
775 preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
776 {
777 	if (op_nr == OP_CB_SEQUENCE) {
778 		if (nop != 0)
779 			return htonl(NFS4ERR_SEQUENCE_POS);
780 	} else {
781 		if (nop == 0)
782 			return htonl(NFS4ERR_OP_NOT_IN_SESSION);
783 	}
784 
785 	switch (op_nr) {
786 	case OP_CB_GETATTR:
787 	case OP_CB_RECALL:
788 	case OP_CB_SEQUENCE:
789 	case OP_CB_RECALL_ANY:
790 	case OP_CB_RECALL_SLOT:
791 	case OP_CB_LAYOUTRECALL:
792 	case OP_CB_NOTIFY_DEVICEID:
793 	case OP_CB_NOTIFY_LOCK:
794 		*op = &callback_ops[op_nr];
795 		break;
796 
797 	case OP_CB_NOTIFY:
798 	case OP_CB_PUSH_DELEG:
799 	case OP_CB_RECALLABLE_OBJ_AVAIL:
800 	case OP_CB_WANTS_CANCELLED:
801 		return htonl(NFS4ERR_NOTSUPP);
802 
803 	default:
804 		return htonl(NFS4ERR_OP_ILLEGAL);
805 	}
806 
807 	return htonl(NFS_OK);
808 }
809 
810 static void nfs4_callback_free_slot(struct nfs4_session *session,
811 		struct nfs4_slot *slot)
812 {
813 	struct nfs4_slot_table *tbl = &session->bc_slot_table;
814 
815 	spin_lock(&tbl->slot_tbl_lock);
816 	/*
817 	 * Let the state manager know callback processing done.
818 	 * A single slot, so highest used slotid is either 0 or -1
819 	 */
820 	nfs4_free_slot(tbl, slot);
821 	nfs4_slot_tbl_drain_complete(tbl);
822 	spin_unlock(&tbl->slot_tbl_lock);
823 }
824 
825 static void nfs4_cb_free_slot(struct cb_process_state *cps)
826 {
827 	if (cps->slot) {
828 		nfs4_callback_free_slot(cps->clp->cl_session, cps->slot);
829 		cps->slot = NULL;
830 	}
831 }
832 
833 #else /* CONFIG_NFS_V4_1 */
834 
835 static __be32
836 preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
837 {
838 	return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
839 }
840 
841 static void nfs4_cb_free_slot(struct cb_process_state *cps)
842 {
843 }
844 #endif /* CONFIG_NFS_V4_1 */
845 
846 #ifdef CONFIG_NFS_V4_2
847 static __be32
848 preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op)
849 {
850 	__be32 status = preprocess_nfs41_op(nop, op_nr, op);
851 	if (status != htonl(NFS4ERR_OP_ILLEGAL))
852 		return status;
853 
854 	if (op_nr == OP_CB_OFFLOAD)
855 		return htonl(NFS4ERR_NOTSUPP);
856 	return htonl(NFS4ERR_OP_ILLEGAL);
857 }
858 #else /* CONFIG_NFS_V4_2 */
859 static __be32
860 preprocess_nfs42_op(int nop, unsigned int op_nr, struct callback_op **op)
861 {
862 	return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
863 }
864 #endif /* CONFIG_NFS_V4_2 */
865 
866 static __be32
867 preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op)
868 {
869 	switch (op_nr) {
870 	case OP_CB_GETATTR:
871 	case OP_CB_RECALL:
872 		*op = &callback_ops[op_nr];
873 		break;
874 	default:
875 		return htonl(NFS4ERR_OP_ILLEGAL);
876 	}
877 
878 	return htonl(NFS_OK);
879 }
880 
881 static __be32 process_op(int nop, struct svc_rqst *rqstp,
882 		struct xdr_stream *xdr_in, void *argp,
883 		struct xdr_stream *xdr_out, void *resp,
884 		struct cb_process_state *cps)
885 {
886 	struct callback_op *op = &callback_ops[0];
887 	unsigned int op_nr;
888 	__be32 status;
889 	long maxlen;
890 	__be32 res;
891 
892 	dprintk("%s: start\n", __func__);
893 	status = decode_op_hdr(xdr_in, &op_nr);
894 	if (unlikely(status))
895 		return status;
896 
897 	dprintk("%s: minorversion=%d nop=%d op_nr=%u\n",
898 		__func__, cps->minorversion, nop, op_nr);
899 
900 	switch (cps->minorversion) {
901 	case 0:
902 		status = preprocess_nfs4_op(op_nr, &op);
903 		break;
904 	case 1:
905 		status = preprocess_nfs41_op(nop, op_nr, &op);
906 		break;
907 	case 2:
908 		status = preprocess_nfs42_op(nop, op_nr, &op);
909 		break;
910 	default:
911 		status = htonl(NFS4ERR_MINOR_VERS_MISMATCH);
912 	}
913 
914 	if (status == htonl(NFS4ERR_OP_ILLEGAL))
915 		op_nr = OP_CB_ILLEGAL;
916 	if (status)
917 		goto encode_hdr;
918 
919 	if (cps->drc_status) {
920 		status = cps->drc_status;
921 		goto encode_hdr;
922 	}
923 
924 	maxlen = xdr_out->end - xdr_out->p;
925 	if (maxlen > 0 && maxlen < PAGE_SIZE) {
926 		status = op->decode_args(rqstp, xdr_in, argp);
927 		if (likely(status == 0))
928 			status = op->process_op(argp, resp, cps);
929 	} else
930 		status = htonl(NFS4ERR_RESOURCE);
931 
932 encode_hdr:
933 	res = encode_op_hdr(xdr_out, op_nr, status);
934 	if (unlikely(res))
935 		return res;
936 	if (op->encode_res != NULL && status == 0)
937 		status = op->encode_res(rqstp, xdr_out, resp);
938 	dprintk("%s: done, status = %d\n", __func__, ntohl(status));
939 	return status;
940 }
941 
942 /*
943  * Decode, process and encode a COMPOUND
944  */
945 static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp)
946 {
947 	struct cb_compound_hdr_arg hdr_arg = { 0 };
948 	struct cb_compound_hdr_res hdr_res = { NULL };
949 	struct xdr_stream xdr_in, xdr_out;
950 	__be32 *p, status;
951 	struct cb_process_state cps = {
952 		.drc_status = 0,
953 		.clp = NULL,
954 		.net = SVC_NET(rqstp),
955 	};
956 	unsigned int nops = 0;
957 
958 	dprintk("%s: start\n", __func__);
959 
960 	xdr_init_decode(&xdr_in, &rqstp->rq_arg, rqstp->rq_arg.head[0].iov_base);
961 
962 	p = (__be32*)((char *)rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len);
963 	xdr_init_encode(&xdr_out, &rqstp->rq_res, p);
964 
965 	status = decode_compound_hdr_arg(&xdr_in, &hdr_arg);
966 	if (status == htonl(NFS4ERR_RESOURCE))
967 		return rpc_garbage_args;
968 
969 	if (hdr_arg.minorversion == 0) {
970 		cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
971 		if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
972 			goto out_invalidcred;
973 	}
974 
975 	cps.minorversion = hdr_arg.minorversion;
976 	hdr_res.taglen = hdr_arg.taglen;
977 	hdr_res.tag = hdr_arg.tag;
978 	if (encode_compound_hdr_res(&xdr_out, &hdr_res) != 0)
979 		return rpc_system_err;
980 
981 	while (status == 0 && nops != hdr_arg.nops) {
982 		status = process_op(nops, rqstp, &xdr_in,
983 				    argp, &xdr_out, resp, &cps);
984 		nops++;
985 	}
986 
987 	/* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return
988 	* resource error in cb_compound status without returning op */
989 	if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) {
990 		status = htonl(NFS4ERR_RESOURCE);
991 		nops--;
992 	}
993 
994 	*hdr_res.status = status;
995 	*hdr_res.nops = htonl(nops);
996 	nfs4_cb_free_slot(&cps);
997 	nfs_put_client(cps.clp);
998 	dprintk("%s: done, status = %u\n", __func__, ntohl(status));
999 	return rpc_success;
1000 
1001 out_invalidcred:
1002 	pr_warn_ratelimited("NFS: NFSv4 callback contains invalid cred\n");
1003 	return rpc_autherr_badcred;
1004 }
1005 
1006 /*
1007  * Define NFS4 callback COMPOUND ops.
1008  */
1009 static struct callback_op callback_ops[] = {
1010 	[0] = {
1011 		.res_maxsize = CB_OP_HDR_RES_MAXSZ,
1012 	},
1013 	[OP_CB_GETATTR] = {
1014 		.process_op = (callback_process_op_t)nfs4_callback_getattr,
1015 		.decode_args = (callback_decode_arg_t)decode_getattr_args,
1016 		.encode_res = (callback_encode_res_t)encode_getattr_res,
1017 		.res_maxsize = CB_OP_GETATTR_RES_MAXSZ,
1018 	},
1019 	[OP_CB_RECALL] = {
1020 		.process_op = (callback_process_op_t)nfs4_callback_recall,
1021 		.decode_args = (callback_decode_arg_t)decode_recall_args,
1022 		.res_maxsize = CB_OP_RECALL_RES_MAXSZ,
1023 	},
1024 #if defined(CONFIG_NFS_V4_1)
1025 	[OP_CB_LAYOUTRECALL] = {
1026 		.process_op = (callback_process_op_t)nfs4_callback_layoutrecall,
1027 		.decode_args =
1028 			(callback_decode_arg_t)decode_layoutrecall_args,
1029 		.res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ,
1030 	},
1031 	[OP_CB_NOTIFY_DEVICEID] = {
1032 		.process_op = (callback_process_op_t)nfs4_callback_devicenotify,
1033 		.decode_args =
1034 			(callback_decode_arg_t)decode_devicenotify_args,
1035 		.res_maxsize = CB_OP_DEVICENOTIFY_RES_MAXSZ,
1036 	},
1037 	[OP_CB_SEQUENCE] = {
1038 		.process_op = (callback_process_op_t)nfs4_callback_sequence,
1039 		.decode_args = (callback_decode_arg_t)decode_cb_sequence_args,
1040 		.encode_res = (callback_encode_res_t)encode_cb_sequence_res,
1041 		.res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ,
1042 	},
1043 	[OP_CB_RECALL_ANY] = {
1044 		.process_op = (callback_process_op_t)nfs4_callback_recallany,
1045 		.decode_args = (callback_decode_arg_t)decode_recallany_args,
1046 		.res_maxsize = CB_OP_RECALLANY_RES_MAXSZ,
1047 	},
1048 	[OP_CB_RECALL_SLOT] = {
1049 		.process_op = (callback_process_op_t)nfs4_callback_recallslot,
1050 		.decode_args = (callback_decode_arg_t)decode_recallslot_args,
1051 		.res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ,
1052 	},
1053 	[OP_CB_NOTIFY_LOCK] = {
1054 		.process_op = (callback_process_op_t)nfs4_callback_notify_lock,
1055 		.decode_args = (callback_decode_arg_t)decode_notify_lock_args,
1056 		.res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ,
1057 	},
1058 #endif /* CONFIG_NFS_V4_1 */
1059 };
1060 
1061 /*
1062  * Define NFS4 callback procedures
1063  */
1064 static struct svc_procedure nfs4_callback_procedures1[] = {
1065 	[CB_NULL] = {
1066 		.pc_func = nfs4_callback_null,
1067 		.pc_decode = (kxdrproc_t)nfs4_decode_void,
1068 		.pc_encode = (kxdrproc_t)nfs4_encode_void,
1069 		.pc_xdrressize = 1,
1070 	},
1071 	[CB_COMPOUND] = {
1072 		.pc_func = nfs4_callback_compound,
1073 		.pc_encode = (kxdrproc_t)nfs4_encode_void,
1074 		.pc_argsize = 256,
1075 		.pc_ressize = 256,
1076 		.pc_xdrressize = NFS4_CALLBACK_BUFSIZE,
1077 	}
1078 };
1079 
1080 struct svc_version nfs4_callback_version1 = {
1081 	.vs_vers = 1,
1082 	.vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1),
1083 	.vs_proc = nfs4_callback_procedures1,
1084 	.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
1085 	.vs_dispatch = NULL,
1086 	.vs_hidden = 1,
1087 };
1088 
1089 struct svc_version nfs4_callback_version4 = {
1090 	.vs_vers = 4,
1091 	.vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1),
1092 	.vs_proc = nfs4_callback_procedures1,
1093 	.vs_xdrsize = NFS4_CALLBACK_XDRSIZE,
1094 	.vs_dispatch = NULL,
1095 	.vs_hidden = 1,
1096 };
1097