xref: /openbmc/linux/fs/afs/yfsclient.c (revision cb1aaebe)
1 /* YFS File Server client stubs
2  *
3  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
11 
12 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/sched.h>
15 #include <linux/circ_buf.h>
16 #include <linux/iversion.h>
17 #include "internal.h"
18 #include "afs_fs.h"
19 #include "xdr_fs.h"
20 #include "protocol_yfs.h"
21 
22 static const struct afs_fid afs_zero_fid;
23 
24 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
25 {
26 	call->cbi = afs_get_cb_interest(cbi);
27 }
28 
29 #define xdr_size(x) (sizeof(*x) / sizeof(__be32))
30 
31 static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
32 {
33 	const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
34 
35 	fid->vid	= xdr_to_u64(x->volume);
36 	fid->vnode	= xdr_to_u64(x->vnode.lo);
37 	fid->vnode_hi	= ntohl(x->vnode.hi);
38 	fid->unique	= ntohl(x->vnode.unique);
39 	*_bp += xdr_size(x);
40 }
41 
42 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
43 {
44 	*bp++ = htonl(n);
45 	return bp;
46 }
47 
48 static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
49 {
50 	struct yfs_xdr_u64 *x = (void *)bp;
51 
52 	*x = u64_to_xdr(n);
53 	return bp + xdr_size(x);
54 }
55 
56 static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
57 {
58 	struct yfs_xdr_YFSFid *x = (void *)bp;
59 
60 	x->volume	= u64_to_xdr(fid->vid);
61 	x->vnode.lo	= u64_to_xdr(fid->vnode);
62 	x->vnode.hi	= htonl(fid->vnode_hi);
63 	x->vnode.unique	= htonl(fid->unique);
64 	return bp + xdr_size(x);
65 }
66 
67 static size_t xdr_strlen(unsigned int len)
68 {
69 	return sizeof(__be32) + round_up(len, sizeof(__be32));
70 }
71 
72 static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
73 {
74 	bp = xdr_encode_u32(bp, len);
75 	bp = memcpy(bp, p, len);
76 	if (len & 3) {
77 		unsigned int pad = 4 - (len & 3);
78 
79 		memset((u8 *)bp + len, 0, pad);
80 		len += pad;
81 	}
82 
83 	return bp + len / sizeof(__be32);
84 }
85 
86 static s64 linux_to_yfs_time(const struct timespec64 *t)
87 {
88 	/* Convert to 100ns intervals. */
89 	return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
90 }
91 
92 static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
93 {
94 	struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
95 
96 	x->mask		= htonl(AFS_SET_MODE);
97 	x->mode		= htonl(mode & S_IALLUGO);
98 	x->mtime_client	= u64_to_xdr(0);
99 	x->owner	= u64_to_xdr(0);
100 	x->group	= u64_to_xdr(0);
101 	return bp + xdr_size(x);
102 }
103 
104 static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
105 {
106 	struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
107 	s64 mtime = linux_to_yfs_time(t);
108 
109 	x->mask		= htonl(AFS_SET_MTIME);
110 	x->mode		= htonl(0);
111 	x->mtime_client	= u64_to_xdr(mtime);
112 	x->owner	= u64_to_xdr(0);
113 	x->group	= u64_to_xdr(0);
114 	return bp + xdr_size(x);
115 }
116 
117 /*
118  * Convert a signed 100ns-resolution 64-bit time into a timespec.
119  */
120 static struct timespec64 yfs_time_to_linux(s64 t)
121 {
122 	struct timespec64 ts;
123 	u64 abs_t;
124 
125 	/*
126 	 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
127 	 * the alternative, do_div, does not work with negative numbers so have
128 	 * to special case them
129 	 */
130 	if (t < 0) {
131 		abs_t = -t;
132 		ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
133 		ts.tv_nsec = -ts.tv_nsec;
134 		ts.tv_sec = -abs_t;
135 	} else {
136 		abs_t = t;
137 		ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
138 		ts.tv_sec = abs_t;
139 	}
140 
141 	return ts;
142 }
143 
144 static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
145 {
146 	s64 t = xdr_to_u64(xdr);
147 
148 	return yfs_time_to_linux(t);
149 }
150 
151 static void yfs_check_req(struct afs_call *call, __be32 *bp)
152 {
153 	size_t len = (void *)bp - call->request;
154 
155 	if (len > call->request_size)
156 		pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
157 		       call->type->name, len, call->request_size);
158 	else if (len < call->request_size)
159 		pr_warning("kAFS: %s: Request buffer underflow (%zu<%u)\n",
160 			   call->type->name, len, call->request_size);
161 }
162 
163 /*
164  * Dump a bad file status record.
165  */
166 static void xdr_dump_bad(const __be32 *bp)
167 {
168 	__be32 x[4];
169 	int i;
170 
171 	pr_notice("YFS XDR: Bad status record\n");
172 	for (i = 0; i < 5 * 4 * 4; i += 16) {
173 		memcpy(x, bp, 16);
174 		bp += 4;
175 		pr_notice("%03x: %08x %08x %08x %08x\n",
176 			  i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
177 	}
178 
179 	memcpy(x, bp, 4);
180 	pr_notice("0x50: %08x\n", ntohl(x[0]));
181 }
182 
183 /*
184  * Decode a YFSFetchStatus block
185  */
186 static int xdr_decode_YFSFetchStatus(const __be32 **_bp,
187 				     struct afs_call *call,
188 				     struct afs_status_cb *scb)
189 {
190 	const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
191 	struct afs_file_status *status = &scb->status;
192 	u32 type;
193 
194 	status->abort_code = ntohl(xdr->abort_code);
195 	if (status->abort_code != 0) {
196 		if (status->abort_code == VNOVNODE)
197 			status->nlink = 0;
198 		scb->have_error = true;
199 		return 0;
200 	}
201 
202 	type = ntohl(xdr->type);
203 	switch (type) {
204 	case AFS_FTYPE_FILE:
205 	case AFS_FTYPE_DIR:
206 	case AFS_FTYPE_SYMLINK:
207 		status->type = type;
208 		break;
209 	default:
210 		goto bad;
211 	}
212 
213 	status->nlink		= ntohl(xdr->nlink);
214 	status->author		= xdr_to_u64(xdr->author);
215 	status->owner		= xdr_to_u64(xdr->owner);
216 	status->caller_access	= ntohl(xdr->caller_access); /* Ticket dependent */
217 	status->anon_access	= ntohl(xdr->anon_access);
218 	status->mode		= ntohl(xdr->mode) & S_IALLUGO;
219 	status->group		= xdr_to_u64(xdr->group);
220 	status->lock_count	= ntohl(xdr->lock_count);
221 
222 	status->mtime_client	= xdr_to_time(xdr->mtime_client);
223 	status->mtime_server	= xdr_to_time(xdr->mtime_server);
224 	status->size		= xdr_to_u64(xdr->size);
225 	status->data_version	= xdr_to_u64(xdr->data_version);
226 	scb->have_status	= true;
227 
228 	*_bp += xdr_size(xdr);
229 	return 0;
230 
231 bad:
232 	xdr_dump_bad(*_bp);
233 	return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
234 }
235 
236 /*
237  * Decode a YFSCallBack block
238  */
239 static void xdr_decode_YFSCallBack(const __be32 **_bp,
240 				   struct afs_call *call,
241 				   struct afs_status_cb *scb)
242 {
243 	struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
244 	struct afs_callback *cb = &scb->callback;
245 	ktime_t cb_expiry;
246 
247 	cb_expiry = call->reply_time;
248 	cb_expiry = ktime_add(cb_expiry, xdr_to_u64(x->expiration_time) * 100);
249 	cb->expires_at	= ktime_divns(cb_expiry, NSEC_PER_SEC);
250 	scb->have_cb	= true;
251 	*_bp += xdr_size(x);
252 }
253 
254 /*
255  * Decode a YFSVolSync block
256  */
257 static void xdr_decode_YFSVolSync(const __be32 **_bp,
258 				  struct afs_volsync *volsync)
259 {
260 	struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
261 	u64 creation;
262 
263 	if (volsync) {
264 		creation = xdr_to_u64(x->vol_creation_date);
265 		do_div(creation, 10 * 1000 * 1000);
266 		volsync->creation = creation;
267 	}
268 
269 	*_bp += xdr_size(x);
270 }
271 
272 /*
273  * Encode the requested attributes into a YFSStoreStatus block
274  */
275 static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
276 {
277 	struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
278 	s64 mtime = 0, owner = 0, group = 0;
279 	u32 mask = 0, mode = 0;
280 
281 	mask = 0;
282 	if (attr->ia_valid & ATTR_MTIME) {
283 		mask |= AFS_SET_MTIME;
284 		mtime = linux_to_yfs_time(&attr->ia_mtime);
285 	}
286 
287 	if (attr->ia_valid & ATTR_UID) {
288 		mask |= AFS_SET_OWNER;
289 		owner = from_kuid(&init_user_ns, attr->ia_uid);
290 	}
291 
292 	if (attr->ia_valid & ATTR_GID) {
293 		mask |= AFS_SET_GROUP;
294 		group = from_kgid(&init_user_ns, attr->ia_gid);
295 	}
296 
297 	if (attr->ia_valid & ATTR_MODE) {
298 		mask |= AFS_SET_MODE;
299 		mode = attr->ia_mode & S_IALLUGO;
300 	}
301 
302 	x->mask		= htonl(mask);
303 	x->mode		= htonl(mode);
304 	x->mtime_client	= u64_to_xdr(mtime);
305 	x->owner	= u64_to_xdr(owner);
306 	x->group	= u64_to_xdr(group);
307 	return bp + xdr_size(x);
308 }
309 
310 /*
311  * Decode a YFSFetchVolumeStatus block.
312  */
313 static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
314 					    struct afs_volume_status *vs)
315 {
316 	const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
317 	u32 flags;
318 
319 	vs->vid			= xdr_to_u64(x->vid);
320 	vs->parent_id		= xdr_to_u64(x->parent_id);
321 	flags			= ntohl(x->flags);
322 	vs->online		= flags & yfs_FVSOnline;
323 	vs->in_service		= flags & yfs_FVSInservice;
324 	vs->blessed		= flags & yfs_FVSBlessed;
325 	vs->needs_salvage	= flags & yfs_FVSNeedsSalvage;
326 	vs->type		= ntohl(x->type);
327 	vs->min_quota		= 0;
328 	vs->max_quota		= xdr_to_u64(x->max_quota);
329 	vs->blocks_in_use	= xdr_to_u64(x->blocks_in_use);
330 	vs->part_blocks_avail	= xdr_to_u64(x->part_blocks_avail);
331 	vs->part_max_blocks	= xdr_to_u64(x->part_max_blocks);
332 	vs->vol_copy_date	= xdr_to_u64(x->vol_copy_date);
333 	vs->vol_backup_date	= xdr_to_u64(x->vol_backup_date);
334 	*_bp += sizeof(*x) / sizeof(__be32);
335 }
336 
337 /*
338  * Deliver a reply that's a status, callback and volsync.
339  */
340 static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call)
341 {
342 	const __be32 *bp;
343 	int ret;
344 
345 	ret = afs_transfer_reply(call);
346 	if (ret < 0)
347 		return ret;
348 
349 	/* unmarshall the reply once we've received all of it */
350 	bp = call->buffer;
351 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
352 	if (ret < 0)
353 		return ret;
354 	xdr_decode_YFSCallBack(&bp, call, call->out_scb);
355 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
356 
357 	_leave(" = 0 [done]");
358 	return 0;
359 }
360 
361 /*
362  * Deliver reply data to operations that just return a file status and a volume
363  * sync record.
364  */
365 static int yfs_deliver_status_and_volsync(struct afs_call *call)
366 {
367 	const __be32 *bp;
368 	int ret;
369 
370 	ret = afs_transfer_reply(call);
371 	if (ret < 0)
372 		return ret;
373 
374 	bp = call->buffer;
375 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
376 	if (ret < 0)
377 		return ret;
378 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
379 
380 	_leave(" = 0 [done]");
381 	return 0;
382 }
383 
384 /*
385  * YFS.FetchStatus operation type
386  */
387 static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = {
388 	.name		= "YFS.FetchStatus(vnode)",
389 	.op		= yfs_FS_FetchStatus,
390 	.deliver	= yfs_deliver_fs_status_cb_and_volsync,
391 	.destructor	= afs_flat_call_destructor,
392 };
393 
394 /*
395  * Fetch the status information for a file.
396  */
397 int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
398 			     struct afs_volsync *volsync)
399 {
400 	struct afs_vnode *vnode = fc->vnode;
401 	struct afs_call *call;
402 	struct afs_net *net = afs_v2net(vnode);
403 	__be32 *bp;
404 
405 	_enter(",%x,{%llx:%llu},,",
406 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
407 
408 	call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode,
409 				   sizeof(__be32) * 2 +
410 				   sizeof(struct yfs_xdr_YFSFid),
411 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
412 				   sizeof(struct yfs_xdr_YFSCallBack) +
413 				   sizeof(struct yfs_xdr_YFSVolSync));
414 	if (!call) {
415 		fc->ac.error = -ENOMEM;
416 		return -ENOMEM;
417 	}
418 
419 	call->key = fc->key;
420 	call->out_scb = scb;
421 	call->out_volsync = volsync;
422 
423 	/* marshall the parameters */
424 	bp = call->request;
425 	bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
426 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
427 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
428 	yfs_check_req(call, bp);
429 
430 	afs_use_fs_server(call, fc->cbi);
431 	trace_afs_make_fs_call(call, &vnode->fid);
432 	afs_set_fc_call(call, fc);
433 	afs_make_call(&fc->ac, call, GFP_NOFS);
434 	return afs_wait_for_call_to_complete(call, &fc->ac);
435 }
436 
437 /*
438  * Deliver reply data to an YFS.FetchData64.
439  */
440 static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
441 {
442 	struct afs_read *req = call->read_request;
443 	const __be32 *bp;
444 	unsigned int size;
445 	int ret;
446 
447 	_enter("{%u,%zu/%llu}",
448 	       call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
449 
450 	switch (call->unmarshall) {
451 	case 0:
452 		req->actual_len = 0;
453 		req->index = 0;
454 		req->offset = req->pos & (PAGE_SIZE - 1);
455 		afs_extract_to_tmp64(call);
456 		call->unmarshall++;
457 
458 		/* Fall through - and extract the returned data length */
459 	case 1:
460 		_debug("extract data length");
461 		ret = afs_extract_data(call, true);
462 		if (ret < 0)
463 			return ret;
464 
465 		req->actual_len = be64_to_cpu(call->tmp64);
466 		_debug("DATA length: %llu", req->actual_len);
467 		req->remain = min(req->len, req->actual_len);
468 		if (req->remain == 0)
469 			goto no_more_data;
470 
471 		call->unmarshall++;
472 
473 	begin_page:
474 		ASSERTCMP(req->index, <, req->nr_pages);
475 		if (req->remain > PAGE_SIZE - req->offset)
476 			size = PAGE_SIZE - req->offset;
477 		else
478 			size = req->remain;
479 		call->bvec[0].bv_len = size;
480 		call->bvec[0].bv_offset = req->offset;
481 		call->bvec[0].bv_page = req->pages[req->index];
482 		iov_iter_bvec(&call->iter, READ, call->bvec, 1, size);
483 		ASSERTCMP(size, <=, PAGE_SIZE);
484 
485 		/* Fall through - and extract the returned data */
486 	case 2:
487 		_debug("extract data %zu/%llu",
488 		       iov_iter_count(&call->iter), req->remain);
489 
490 		ret = afs_extract_data(call, true);
491 		if (ret < 0)
492 			return ret;
493 		req->remain -= call->bvec[0].bv_len;
494 		req->offset += call->bvec[0].bv_len;
495 		ASSERTCMP(req->offset, <=, PAGE_SIZE);
496 		if (req->offset == PAGE_SIZE) {
497 			req->offset = 0;
498 			if (req->page_done)
499 				req->page_done(req);
500 			req->index++;
501 			if (req->remain > 0)
502 				goto begin_page;
503 		}
504 
505 		ASSERTCMP(req->remain, ==, 0);
506 		if (req->actual_len <= req->len)
507 			goto no_more_data;
508 
509 		/* Discard any excess data the server gave us */
510 		iov_iter_discard(&call->iter, READ, req->actual_len - req->len);
511 		call->unmarshall = 3;
512 
513 		/* Fall through */
514 	case 3:
515 		_debug("extract discard %zu/%llu",
516 		       iov_iter_count(&call->iter), req->actual_len - req->len);
517 
518 		ret = afs_extract_data(call, true);
519 		if (ret < 0)
520 			return ret;
521 
522 	no_more_data:
523 		call->unmarshall = 4;
524 		afs_extract_to_buf(call,
525 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
526 				   sizeof(struct yfs_xdr_YFSCallBack) +
527 				   sizeof(struct yfs_xdr_YFSVolSync));
528 
529 		/* Fall through - and extract the metadata */
530 	case 4:
531 		ret = afs_extract_data(call, false);
532 		if (ret < 0)
533 			return ret;
534 
535 		bp = call->buffer;
536 		ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
537 		if (ret < 0)
538 			return ret;
539 		xdr_decode_YFSCallBack(&bp, call, call->out_scb);
540 		xdr_decode_YFSVolSync(&bp, call->out_volsync);
541 
542 		req->data_version = call->out_scb->status.data_version;
543 		req->file_size = call->out_scb->status.size;
544 
545 		call->unmarshall++;
546 
547 		/* Fall through */
548 	case 5:
549 		break;
550 	}
551 
552 	for (; req->index < req->nr_pages; req->index++) {
553 		if (req->offset < PAGE_SIZE)
554 			zero_user_segment(req->pages[req->index],
555 					  req->offset, PAGE_SIZE);
556 		if (req->page_done)
557 			req->page_done(req);
558 		req->offset = 0;
559 	}
560 
561 	_leave(" = 0 [done]");
562 	return 0;
563 }
564 
565 static void yfs_fetch_data_destructor(struct afs_call *call)
566 {
567 	afs_put_read(call->read_request);
568 	afs_flat_call_destructor(call);
569 }
570 
571 /*
572  * YFS.FetchData64 operation type
573  */
574 static const struct afs_call_type yfs_RXYFSFetchData64 = {
575 	.name		= "YFS.FetchData64",
576 	.op		= yfs_FS_FetchData64,
577 	.deliver	= yfs_deliver_fs_fetch_data64,
578 	.destructor	= yfs_fetch_data_destructor,
579 };
580 
581 /*
582  * Fetch data from a file.
583  */
584 int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
585 		      struct afs_read *req)
586 {
587 	struct afs_vnode *vnode = fc->vnode;
588 	struct afs_call *call;
589 	struct afs_net *net = afs_v2net(vnode);
590 	__be32 *bp;
591 
592 	_enter(",%x,{%llx:%llu},%llx,%llx",
593 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
594 	       req->pos, req->len);
595 
596 	call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
597 				   sizeof(__be32) * 2 +
598 				   sizeof(struct yfs_xdr_YFSFid) +
599 				   sizeof(struct yfs_xdr_u64) * 2,
600 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
601 				   sizeof(struct yfs_xdr_YFSCallBack) +
602 				   sizeof(struct yfs_xdr_YFSVolSync));
603 	if (!call)
604 		return -ENOMEM;
605 
606 	call->key = fc->key;
607 	call->out_scb = scb;
608 	call->out_volsync = NULL;
609 	call->read_request = req;
610 
611 	/* marshall the parameters */
612 	bp = call->request;
613 	bp = xdr_encode_u32(bp, YFSFETCHDATA64);
614 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
615 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
616 	bp = xdr_encode_u64(bp, req->pos);
617 	bp = xdr_encode_u64(bp, req->len);
618 	yfs_check_req(call, bp);
619 
620 	refcount_inc(&req->usage);
621 	afs_use_fs_server(call, fc->cbi);
622 	trace_afs_make_fs_call(call, &vnode->fid);
623 	afs_set_fc_call(call, fc);
624 	afs_make_call(&fc->ac, call, GFP_NOFS);
625 	return afs_wait_for_call_to_complete(call, &fc->ac);
626 }
627 
628 /*
629  * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
630  */
631 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
632 {
633 	const __be32 *bp;
634 	int ret;
635 
636 	_enter("{%u}", call->unmarshall);
637 
638 	ret = afs_transfer_reply(call);
639 	if (ret < 0)
640 		return ret;
641 
642 	/* unmarshall the reply once we've received all of it */
643 	bp = call->buffer;
644 	xdr_decode_YFSFid(&bp, call->out_fid);
645 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
646 	if (ret < 0)
647 		return ret;
648 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
649 	if (ret < 0)
650 		return ret;
651 	xdr_decode_YFSCallBack(&bp, call, call->out_scb);
652 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
653 
654 	_leave(" = 0 [done]");
655 	return 0;
656 }
657 
658 /*
659  * FS.CreateFile and FS.MakeDir operation type
660  */
661 static const struct afs_call_type afs_RXFSCreateFile = {
662 	.name		= "YFS.CreateFile",
663 	.op		= yfs_FS_CreateFile,
664 	.deliver	= yfs_deliver_fs_create_vnode,
665 	.destructor	= afs_flat_call_destructor,
666 };
667 
668 /*
669  * Create a file.
670  */
671 int yfs_fs_create_file(struct afs_fs_cursor *fc,
672 		       const char *name,
673 		       umode_t mode,
674 		       struct afs_status_cb *dvnode_scb,
675 		       struct afs_fid *newfid,
676 		       struct afs_status_cb *new_scb)
677 {
678 	struct afs_vnode *dvnode = fc->vnode;
679 	struct afs_call *call;
680 	struct afs_net *net = afs_v2net(dvnode);
681 	size_t namesz, reqsz, rplsz;
682 	__be32 *bp;
683 
684 	_enter("");
685 
686 	namesz = strlen(name);
687 	reqsz = (sizeof(__be32) +
688 		 sizeof(__be32) +
689 		 sizeof(struct yfs_xdr_YFSFid) +
690 		 xdr_strlen(namesz) +
691 		 sizeof(struct yfs_xdr_YFSStoreStatus) +
692 		 sizeof(__be32));
693 	rplsz = (sizeof(struct yfs_xdr_YFSFid) +
694 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
695 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
696 		 sizeof(struct yfs_xdr_YFSCallBack) +
697 		 sizeof(struct yfs_xdr_YFSVolSync));
698 
699 	call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
700 	if (!call)
701 		return -ENOMEM;
702 
703 	call->key = fc->key;
704 	call->out_dir_scb = dvnode_scb;
705 	call->out_fid = newfid;
706 	call->out_scb = new_scb;
707 
708 	/* marshall the parameters */
709 	bp = call->request;
710 	bp = xdr_encode_u32(bp, YFSCREATEFILE);
711 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
712 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
713 	bp = xdr_encode_string(bp, name, namesz);
714 	bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
715 	bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
716 	yfs_check_req(call, bp);
717 
718 	afs_use_fs_server(call, fc->cbi);
719 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
720 	afs_set_fc_call(call, fc);
721 	afs_make_call(&fc->ac, call, GFP_NOFS);
722 	return afs_wait_for_call_to_complete(call, &fc->ac);
723 }
724 
725 static const struct afs_call_type yfs_RXFSMakeDir = {
726 	.name		= "YFS.MakeDir",
727 	.op		= yfs_FS_MakeDir,
728 	.deliver	= yfs_deliver_fs_create_vnode,
729 	.destructor	= afs_flat_call_destructor,
730 };
731 
732 /*
733  * Make a directory.
734  */
735 int yfs_fs_make_dir(struct afs_fs_cursor *fc,
736 		    const char *name,
737 		    umode_t mode,
738 		    struct afs_status_cb *dvnode_scb,
739 		    struct afs_fid *newfid,
740 		    struct afs_status_cb *new_scb)
741 {
742 	struct afs_vnode *dvnode = fc->vnode;
743 	struct afs_call *call;
744 	struct afs_net *net = afs_v2net(dvnode);
745 	size_t namesz, reqsz, rplsz;
746 	__be32 *bp;
747 
748 	_enter("");
749 
750 	namesz = strlen(name);
751 	reqsz = (sizeof(__be32) +
752 		 sizeof(struct yfs_xdr_RPCFlags) +
753 		 sizeof(struct yfs_xdr_YFSFid) +
754 		 xdr_strlen(namesz) +
755 		 sizeof(struct yfs_xdr_YFSStoreStatus));
756 	rplsz = (sizeof(struct yfs_xdr_YFSFid) +
757 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
758 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
759 		 sizeof(struct yfs_xdr_YFSCallBack) +
760 		 sizeof(struct yfs_xdr_YFSVolSync));
761 
762 	call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
763 	if (!call)
764 		return -ENOMEM;
765 
766 	call->key = fc->key;
767 	call->out_dir_scb = dvnode_scb;
768 	call->out_fid = newfid;
769 	call->out_scb = new_scb;
770 
771 	/* marshall the parameters */
772 	bp = call->request;
773 	bp = xdr_encode_u32(bp, YFSMAKEDIR);
774 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
775 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
776 	bp = xdr_encode_string(bp, name, namesz);
777 	bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
778 	yfs_check_req(call, bp);
779 
780 	afs_use_fs_server(call, fc->cbi);
781 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
782 	afs_set_fc_call(call, fc);
783 	afs_make_call(&fc->ac, call, GFP_NOFS);
784 	return afs_wait_for_call_to_complete(call, &fc->ac);
785 }
786 
787 /*
788  * Deliver reply data to a YFS.RemoveFile2 operation.
789  */
790 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
791 {
792 	struct afs_fid fid;
793 	const __be32 *bp;
794 	int ret;
795 
796 	_enter("{%u}", call->unmarshall);
797 
798 	ret = afs_transfer_reply(call);
799 	if (ret < 0)
800 		return ret;
801 
802 	bp = call->buffer;
803 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
804 	if (ret < 0)
805 		return ret;
806 
807 	xdr_decode_YFSFid(&bp, &fid);
808 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
809 	if (ret < 0)
810 		return ret;
811 	/* Was deleted if vnode->status.abort_code == VNOVNODE. */
812 
813 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
814 	return 0;
815 }
816 
817 /*
818  * YFS.RemoveFile2 operation type.
819  */
820 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
821 	.name		= "YFS.RemoveFile2",
822 	.op		= yfs_FS_RemoveFile2,
823 	.deliver	= yfs_deliver_fs_remove_file2,
824 	.destructor	= afs_flat_call_destructor,
825 };
826 
827 /*
828  * Remove a file and retrieve new file status.
829  */
830 int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
831 			const char *name, struct afs_status_cb *dvnode_scb,
832 			struct afs_status_cb *vnode_scb)
833 {
834 	struct afs_vnode *dvnode = fc->vnode;
835 	struct afs_call *call;
836 	struct afs_net *net = afs_v2net(dvnode);
837 	size_t namesz;
838 	__be32 *bp;
839 
840 	_enter("");
841 
842 	namesz = strlen(name);
843 
844 	call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
845 				   sizeof(__be32) +
846 				   sizeof(struct yfs_xdr_RPCFlags) +
847 				   sizeof(struct yfs_xdr_YFSFid) +
848 				   xdr_strlen(namesz),
849 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
850 				   sizeof(struct yfs_xdr_YFSFid) +
851 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
852 				   sizeof(struct yfs_xdr_YFSVolSync));
853 	if (!call)
854 		return -ENOMEM;
855 
856 	call->key = fc->key;
857 	call->out_dir_scb = dvnode_scb;
858 	call->out_scb = vnode_scb;
859 
860 	/* marshall the parameters */
861 	bp = call->request;
862 	bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
863 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
864 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
865 	bp = xdr_encode_string(bp, name, namesz);
866 	yfs_check_req(call, bp);
867 
868 	afs_use_fs_server(call, fc->cbi);
869 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
870 	afs_set_fc_call(call, fc);
871 	afs_make_call(&fc->ac, call, GFP_NOFS);
872 	return afs_wait_for_call_to_complete(call, &fc->ac);
873 }
874 
875 /*
876  * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
877  */
878 static int yfs_deliver_fs_remove(struct afs_call *call)
879 {
880 	const __be32 *bp;
881 	int ret;
882 
883 	_enter("{%u}", call->unmarshall);
884 
885 	ret = afs_transfer_reply(call);
886 	if (ret < 0)
887 		return ret;
888 
889 	bp = call->buffer;
890 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
891 	if (ret < 0)
892 		return ret;
893 
894 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
895 	return 0;
896 }
897 
898 /*
899  * FS.RemoveDir and FS.RemoveFile operation types.
900  */
901 static const struct afs_call_type yfs_RXYFSRemoveFile = {
902 	.name		= "YFS.RemoveFile",
903 	.op		= yfs_FS_RemoveFile,
904 	.deliver	= yfs_deliver_fs_remove,
905 	.destructor	= afs_flat_call_destructor,
906 };
907 
908 static const struct afs_call_type yfs_RXYFSRemoveDir = {
909 	.name		= "YFS.RemoveDir",
910 	.op		= yfs_FS_RemoveDir,
911 	.deliver	= yfs_deliver_fs_remove,
912 	.destructor	= afs_flat_call_destructor,
913 };
914 
915 /*
916  * remove a file or directory
917  */
918 int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
919 		  const char *name, bool isdir,
920 		  struct afs_status_cb *dvnode_scb)
921 {
922 	struct afs_vnode *dvnode = fc->vnode;
923 	struct afs_call *call;
924 	struct afs_net *net = afs_v2net(dvnode);
925 	size_t namesz;
926 	__be32 *bp;
927 
928 	_enter("");
929 
930 	namesz = strlen(name);
931 	call = afs_alloc_flat_call(
932 		net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
933 		sizeof(__be32) +
934 		sizeof(struct yfs_xdr_RPCFlags) +
935 		sizeof(struct yfs_xdr_YFSFid) +
936 		xdr_strlen(namesz),
937 		sizeof(struct yfs_xdr_YFSFetchStatus) +
938 		sizeof(struct yfs_xdr_YFSVolSync));
939 	if (!call)
940 		return -ENOMEM;
941 
942 	call->key = fc->key;
943 	call->out_dir_scb = dvnode_scb;
944 
945 	/* marshall the parameters */
946 	bp = call->request;
947 	bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
948 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
949 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
950 	bp = xdr_encode_string(bp, name, namesz);
951 	yfs_check_req(call, bp);
952 
953 	afs_use_fs_server(call, fc->cbi);
954 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
955 	afs_set_fc_call(call, fc);
956 	afs_make_call(&fc->ac, call, GFP_NOFS);
957 	return afs_wait_for_call_to_complete(call, &fc->ac);
958 }
959 
960 /*
961  * Deliver reply data to a YFS.Link operation.
962  */
963 static int yfs_deliver_fs_link(struct afs_call *call)
964 {
965 	const __be32 *bp;
966 	int ret;
967 
968 	_enter("{%u}", call->unmarshall);
969 
970 	ret = afs_transfer_reply(call);
971 	if (ret < 0)
972 		return ret;
973 
974 	bp = call->buffer;
975 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
976 	if (ret < 0)
977 		return ret;
978 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
979 	if (ret < 0)
980 		return ret;
981 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
982 	_leave(" = 0 [done]");
983 	return 0;
984 }
985 
986 /*
987  * YFS.Link operation type.
988  */
989 static const struct afs_call_type yfs_RXYFSLink = {
990 	.name		= "YFS.Link",
991 	.op		= yfs_FS_Link,
992 	.deliver	= yfs_deliver_fs_link,
993 	.destructor	= afs_flat_call_destructor,
994 };
995 
996 /*
997  * Make a hard link.
998  */
999 int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1000 		const char *name,
1001 		struct afs_status_cb *dvnode_scb,
1002 		struct afs_status_cb *vnode_scb)
1003 {
1004 	struct afs_vnode *dvnode = fc->vnode;
1005 	struct afs_call *call;
1006 	struct afs_net *net = afs_v2net(vnode);
1007 	size_t namesz;
1008 	__be32 *bp;
1009 
1010 	_enter("");
1011 
1012 	namesz = strlen(name);
1013 	call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1014 				   sizeof(__be32) +
1015 				   sizeof(struct yfs_xdr_RPCFlags) +
1016 				   sizeof(struct yfs_xdr_YFSFid) +
1017 				   xdr_strlen(namesz) +
1018 				   sizeof(struct yfs_xdr_YFSFid),
1019 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1020 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1021 				   sizeof(struct yfs_xdr_YFSVolSync));
1022 	if (!call)
1023 		return -ENOMEM;
1024 
1025 	call->key = fc->key;
1026 	call->out_dir_scb = dvnode_scb;
1027 	call->out_scb = vnode_scb;
1028 
1029 	/* marshall the parameters */
1030 	bp = call->request;
1031 	bp = xdr_encode_u32(bp, YFSLINK);
1032 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1033 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1034 	bp = xdr_encode_string(bp, name, namesz);
1035 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1036 	yfs_check_req(call, bp);
1037 
1038 	afs_use_fs_server(call, fc->cbi);
1039 	trace_afs_make_fs_call1(call, &vnode->fid, name);
1040 	afs_set_fc_call(call, fc);
1041 	afs_make_call(&fc->ac, call, GFP_NOFS);
1042 	return afs_wait_for_call_to_complete(call, &fc->ac);
1043 }
1044 
1045 /*
1046  * Deliver reply data to a YFS.Symlink operation.
1047  */
1048 static int yfs_deliver_fs_symlink(struct afs_call *call)
1049 {
1050 	const __be32 *bp;
1051 	int ret;
1052 
1053 	_enter("{%u}", call->unmarshall);
1054 
1055 	ret = afs_transfer_reply(call);
1056 	if (ret < 0)
1057 		return ret;
1058 
1059 	/* unmarshall the reply once we've received all of it */
1060 	bp = call->buffer;
1061 	xdr_decode_YFSFid(&bp, call->out_fid);
1062 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1063 	if (ret < 0)
1064 		return ret;
1065 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1066 	if (ret < 0)
1067 		return ret;
1068 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
1069 
1070 	_leave(" = 0 [done]");
1071 	return 0;
1072 }
1073 
1074 /*
1075  * YFS.Symlink operation type
1076  */
1077 static const struct afs_call_type yfs_RXYFSSymlink = {
1078 	.name		= "YFS.Symlink",
1079 	.op		= yfs_FS_Symlink,
1080 	.deliver	= yfs_deliver_fs_symlink,
1081 	.destructor	= afs_flat_call_destructor,
1082 };
1083 
1084 /*
1085  * Create a symbolic link.
1086  */
1087 int yfs_fs_symlink(struct afs_fs_cursor *fc,
1088 		   const char *name,
1089 		   const char *contents,
1090 		   struct afs_status_cb *dvnode_scb,
1091 		   struct afs_fid *newfid,
1092 		   struct afs_status_cb *vnode_scb)
1093 {
1094 	struct afs_vnode *dvnode = fc->vnode;
1095 	struct afs_call *call;
1096 	struct afs_net *net = afs_v2net(dvnode);
1097 	size_t namesz, contents_sz;
1098 	__be32 *bp;
1099 
1100 	_enter("");
1101 
1102 	namesz = strlen(name);
1103 	contents_sz = strlen(contents);
1104 	call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1105 				   sizeof(__be32) +
1106 				   sizeof(struct yfs_xdr_RPCFlags) +
1107 				   sizeof(struct yfs_xdr_YFSFid) +
1108 				   xdr_strlen(namesz) +
1109 				   xdr_strlen(contents_sz) +
1110 				   sizeof(struct yfs_xdr_YFSStoreStatus),
1111 				   sizeof(struct yfs_xdr_YFSFid) +
1112 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1113 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1114 				   sizeof(struct yfs_xdr_YFSVolSync));
1115 	if (!call)
1116 		return -ENOMEM;
1117 
1118 	call->key = fc->key;
1119 	call->out_dir_scb = dvnode_scb;
1120 	call->out_fid = newfid;
1121 	call->out_scb = vnode_scb;
1122 
1123 	/* marshall the parameters */
1124 	bp = call->request;
1125 	bp = xdr_encode_u32(bp, YFSSYMLINK);
1126 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1127 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1128 	bp = xdr_encode_string(bp, name, namesz);
1129 	bp = xdr_encode_string(bp, contents, contents_sz);
1130 	bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1131 	yfs_check_req(call, bp);
1132 
1133 	afs_use_fs_server(call, fc->cbi);
1134 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
1135 	afs_set_fc_call(call, fc);
1136 	afs_make_call(&fc->ac, call, GFP_NOFS);
1137 	return afs_wait_for_call_to_complete(call, &fc->ac);
1138 }
1139 
1140 /*
1141  * Deliver reply data to a YFS.Rename operation.
1142  */
1143 static int yfs_deliver_fs_rename(struct afs_call *call)
1144 {
1145 	const __be32 *bp;
1146 	int ret;
1147 
1148 	_enter("{%u}", call->unmarshall);
1149 
1150 	ret = afs_transfer_reply(call);
1151 	if (ret < 0)
1152 		return ret;
1153 
1154 	bp = call->buffer;
1155 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1156 	if (ret < 0)
1157 		return ret;
1158 	if (call->out_dir_scb != call->out_scb) {
1159 		ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1160 		if (ret < 0)
1161 			return ret;
1162 	}
1163 
1164 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
1165 	_leave(" = 0 [done]");
1166 	return 0;
1167 }
1168 
1169 /*
1170  * YFS.Rename operation type
1171  */
1172 static const struct afs_call_type yfs_RXYFSRename = {
1173 	.name		= "FS.Rename",
1174 	.op		= yfs_FS_Rename,
1175 	.deliver	= yfs_deliver_fs_rename,
1176 	.destructor	= afs_flat_call_destructor,
1177 };
1178 
1179 /*
1180  * Rename a file or directory.
1181  */
1182 int yfs_fs_rename(struct afs_fs_cursor *fc,
1183 		  const char *orig_name,
1184 		  struct afs_vnode *new_dvnode,
1185 		  const char *new_name,
1186 		  struct afs_status_cb *orig_dvnode_scb,
1187 		  struct afs_status_cb *new_dvnode_scb)
1188 {
1189 	struct afs_vnode *orig_dvnode = fc->vnode;
1190 	struct afs_call *call;
1191 	struct afs_net *net = afs_v2net(orig_dvnode);
1192 	size_t o_namesz, n_namesz;
1193 	__be32 *bp;
1194 
1195 	_enter("");
1196 
1197 	o_namesz = strlen(orig_name);
1198 	n_namesz = strlen(new_name);
1199 	call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1200 				   sizeof(__be32) +
1201 				   sizeof(struct yfs_xdr_RPCFlags) +
1202 				   sizeof(struct yfs_xdr_YFSFid) +
1203 				   xdr_strlen(o_namesz) +
1204 				   sizeof(struct yfs_xdr_YFSFid) +
1205 				   xdr_strlen(n_namesz),
1206 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1207 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1208 				   sizeof(struct yfs_xdr_YFSVolSync));
1209 	if (!call)
1210 		return -ENOMEM;
1211 
1212 	call->key = fc->key;
1213 	call->out_dir_scb = orig_dvnode_scb;
1214 	call->out_scb = new_dvnode_scb;
1215 
1216 	/* marshall the parameters */
1217 	bp = call->request;
1218 	bp = xdr_encode_u32(bp, YFSRENAME);
1219 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1220 	bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1221 	bp = xdr_encode_string(bp, orig_name, o_namesz);
1222 	bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1223 	bp = xdr_encode_string(bp, new_name, n_namesz);
1224 	yfs_check_req(call, bp);
1225 
1226 	afs_use_fs_server(call, fc->cbi);
1227 	trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
1228 	afs_set_fc_call(call, fc);
1229 	afs_make_call(&fc->ac, call, GFP_NOFS);
1230 	return afs_wait_for_call_to_complete(call, &fc->ac);
1231 }
1232 
1233 /*
1234  * YFS.StoreData64 operation type.
1235  */
1236 static const struct afs_call_type yfs_RXYFSStoreData64 = {
1237 	.name		= "YFS.StoreData64",
1238 	.op		= yfs_FS_StoreData64,
1239 	.deliver	= yfs_deliver_status_and_volsync,
1240 	.destructor	= afs_flat_call_destructor,
1241 };
1242 
1243 /*
1244  * Store a set of pages to a large file.
1245  */
1246 int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1247 		      pgoff_t first, pgoff_t last,
1248 		      unsigned offset, unsigned to,
1249 		      struct afs_status_cb *scb)
1250 {
1251 	struct afs_vnode *vnode = fc->vnode;
1252 	struct afs_call *call;
1253 	struct afs_net *net = afs_v2net(vnode);
1254 	loff_t size, pos, i_size;
1255 	__be32 *bp;
1256 
1257 	_enter(",%x,{%llx:%llu},,",
1258 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1259 
1260 	size = (loff_t)to - (loff_t)offset;
1261 	if (first != last)
1262 		size += (loff_t)(last - first) << PAGE_SHIFT;
1263 	pos = (loff_t)first << PAGE_SHIFT;
1264 	pos += offset;
1265 
1266 	i_size = i_size_read(&vnode->vfs_inode);
1267 	if (pos + size > i_size)
1268 		i_size = size + pos;
1269 
1270 	_debug("size %llx, at %llx, i_size %llx",
1271 	       (unsigned long long)size, (unsigned long long)pos,
1272 	       (unsigned long long)i_size);
1273 
1274 	call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1275 				   sizeof(__be32) +
1276 				   sizeof(__be32) +
1277 				   sizeof(struct yfs_xdr_YFSFid) +
1278 				   sizeof(struct yfs_xdr_YFSStoreStatus) +
1279 				   sizeof(struct yfs_xdr_u64) * 3,
1280 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1281 				   sizeof(struct yfs_xdr_YFSVolSync));
1282 	if (!call)
1283 		return -ENOMEM;
1284 
1285 	call->key = fc->key;
1286 	call->mapping = mapping;
1287 	call->first = first;
1288 	call->last = last;
1289 	call->first_offset = offset;
1290 	call->last_to = to;
1291 	call->send_pages = true;
1292 	call->out_scb = scb;
1293 
1294 	/* marshall the parameters */
1295 	bp = call->request;
1296 	bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1297 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1298 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1299 	bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1300 	bp = xdr_encode_u64(bp, pos);
1301 	bp = xdr_encode_u64(bp, size);
1302 	bp = xdr_encode_u64(bp, i_size);
1303 	yfs_check_req(call, bp);
1304 
1305 	afs_use_fs_server(call, fc->cbi);
1306 	trace_afs_make_fs_call(call, &vnode->fid);
1307 	afs_set_fc_call(call, fc);
1308 	afs_make_call(&fc->ac, call, GFP_NOFS);
1309 	return afs_wait_for_call_to_complete(call, &fc->ac);
1310 }
1311 
1312 /*
1313  * YFS.StoreStatus operation type
1314  */
1315 static const struct afs_call_type yfs_RXYFSStoreStatus = {
1316 	.name		= "YFS.StoreStatus",
1317 	.op		= yfs_FS_StoreStatus,
1318 	.deliver	= yfs_deliver_status_and_volsync,
1319 	.destructor	= afs_flat_call_destructor,
1320 };
1321 
1322 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1323 	.name		= "YFS.StoreData64",
1324 	.op		= yfs_FS_StoreData64,
1325 	.deliver	= yfs_deliver_status_and_volsync,
1326 	.destructor	= afs_flat_call_destructor,
1327 };
1328 
1329 /*
1330  * Set the attributes on a file, using YFS.StoreData64 rather than
1331  * YFS.StoreStatus so as to alter the file size also.
1332  */
1333 static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr,
1334 			       struct afs_status_cb *scb)
1335 {
1336 	struct afs_vnode *vnode = fc->vnode;
1337 	struct afs_call *call;
1338 	struct afs_net *net = afs_v2net(vnode);
1339 	__be32 *bp;
1340 
1341 	_enter(",%x,{%llx:%llu},,",
1342 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1343 
1344 	call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1345 				   sizeof(__be32) * 2 +
1346 				   sizeof(struct yfs_xdr_YFSFid) +
1347 				   sizeof(struct yfs_xdr_YFSStoreStatus) +
1348 				   sizeof(struct yfs_xdr_u64) * 3,
1349 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1350 				   sizeof(struct yfs_xdr_YFSVolSync));
1351 	if (!call)
1352 		return -ENOMEM;
1353 
1354 	call->key = fc->key;
1355 	call->out_scb = scb;
1356 
1357 	/* marshall the parameters */
1358 	bp = call->request;
1359 	bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1360 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1361 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1362 	bp = xdr_encode_YFS_StoreStatus(bp, attr);
1363 	bp = xdr_encode_u64(bp, attr->ia_size);	/* position of start of write */
1364 	bp = xdr_encode_u64(bp, 0);		/* size of write */
1365 	bp = xdr_encode_u64(bp, attr->ia_size);	/* new file length */
1366 	yfs_check_req(call, bp);
1367 
1368 	afs_use_fs_server(call, fc->cbi);
1369 	trace_afs_make_fs_call(call, &vnode->fid);
1370 	afs_set_fc_call(call, fc);
1371 	afs_make_call(&fc->ac, call, GFP_NOFS);
1372 	return afs_wait_for_call_to_complete(call, &fc->ac);
1373 }
1374 
1375 /*
1376  * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1377  * file size, and YFS.StoreStatus otherwise.
1378  */
1379 int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr,
1380 		   struct afs_status_cb *scb)
1381 {
1382 	struct afs_vnode *vnode = fc->vnode;
1383 	struct afs_call *call;
1384 	struct afs_net *net = afs_v2net(vnode);
1385 	__be32 *bp;
1386 
1387 	if (attr->ia_valid & ATTR_SIZE)
1388 		return yfs_fs_setattr_size(fc, attr, scb);
1389 
1390 	_enter(",%x,{%llx:%llu},,",
1391 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1392 
1393 	call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1394 				   sizeof(__be32) * 2 +
1395 				   sizeof(struct yfs_xdr_YFSFid) +
1396 				   sizeof(struct yfs_xdr_YFSStoreStatus),
1397 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1398 				   sizeof(struct yfs_xdr_YFSVolSync));
1399 	if (!call)
1400 		return -ENOMEM;
1401 
1402 	call->key = fc->key;
1403 	call->out_scb = scb;
1404 
1405 	/* marshall the parameters */
1406 	bp = call->request;
1407 	bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1408 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1409 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1410 	bp = xdr_encode_YFS_StoreStatus(bp, attr);
1411 	yfs_check_req(call, bp);
1412 
1413 	afs_use_fs_server(call, fc->cbi);
1414 	trace_afs_make_fs_call(call, &vnode->fid);
1415 	afs_set_fc_call(call, fc);
1416 	afs_make_call(&fc->ac, call, GFP_NOFS);
1417 	return afs_wait_for_call_to_complete(call, &fc->ac);
1418 }
1419 
1420 /*
1421  * Deliver reply data to a YFS.GetVolumeStatus operation.
1422  */
1423 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1424 {
1425 	const __be32 *bp;
1426 	char *p;
1427 	u32 size;
1428 	int ret;
1429 
1430 	_enter("{%u}", call->unmarshall);
1431 
1432 	switch (call->unmarshall) {
1433 	case 0:
1434 		call->unmarshall++;
1435 		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1436 
1437 		/* Fall through - and extract the returned status record */
1438 	case 1:
1439 		_debug("extract status");
1440 		ret = afs_extract_data(call, true);
1441 		if (ret < 0)
1442 			return ret;
1443 
1444 		bp = call->buffer;
1445 		xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus);
1446 		call->unmarshall++;
1447 		afs_extract_to_tmp(call);
1448 
1449 		/* Fall through - and extract the volume name length */
1450 	case 2:
1451 		ret = afs_extract_data(call, true);
1452 		if (ret < 0)
1453 			return ret;
1454 
1455 		call->count = ntohl(call->tmp);
1456 		_debug("volname length: %u", call->count);
1457 		if (call->count >= AFSNAMEMAX)
1458 			return afs_protocol_error(call, -EBADMSG,
1459 						  afs_eproto_volname_len);
1460 		size = (call->count + 3) & ~3; /* It's padded */
1461 		afs_extract_to_buf(call, size);
1462 		call->unmarshall++;
1463 
1464 		/* Fall through - and extract the volume name */
1465 	case 3:
1466 		_debug("extract volname");
1467 		ret = afs_extract_data(call, true);
1468 		if (ret < 0)
1469 			return ret;
1470 
1471 		p = call->buffer;
1472 		p[call->count] = 0;
1473 		_debug("volname '%s'", p);
1474 		afs_extract_to_tmp(call);
1475 		call->unmarshall++;
1476 
1477 		/* Fall through - and extract the offline message length */
1478 	case 4:
1479 		ret = afs_extract_data(call, true);
1480 		if (ret < 0)
1481 			return ret;
1482 
1483 		call->count = ntohl(call->tmp);
1484 		_debug("offline msg length: %u", call->count);
1485 		if (call->count >= AFSNAMEMAX)
1486 			return afs_protocol_error(call, -EBADMSG,
1487 						  afs_eproto_offline_msg_len);
1488 		size = (call->count + 3) & ~3; /* It's padded */
1489 		afs_extract_to_buf(call, size);
1490 		call->unmarshall++;
1491 
1492 		/* Fall through - and extract the offline message */
1493 	case 5:
1494 		_debug("extract offline");
1495 		ret = afs_extract_data(call, true);
1496 		if (ret < 0)
1497 			return ret;
1498 
1499 		p = call->buffer;
1500 		p[call->count] = 0;
1501 		_debug("offline '%s'", p);
1502 
1503 		afs_extract_to_tmp(call);
1504 		call->unmarshall++;
1505 
1506 		/* Fall through - and extract the message of the day length */
1507 	case 6:
1508 		ret = afs_extract_data(call, true);
1509 		if (ret < 0)
1510 			return ret;
1511 
1512 		call->count = ntohl(call->tmp);
1513 		_debug("motd length: %u", call->count);
1514 		if (call->count >= AFSNAMEMAX)
1515 			return afs_protocol_error(call, -EBADMSG,
1516 						  afs_eproto_motd_len);
1517 		size = (call->count + 3) & ~3; /* It's padded */
1518 		afs_extract_to_buf(call, size);
1519 		call->unmarshall++;
1520 
1521 		/* Fall through - and extract the message of the day */
1522 	case 7:
1523 		_debug("extract motd");
1524 		ret = afs_extract_data(call, false);
1525 		if (ret < 0)
1526 			return ret;
1527 
1528 		p = call->buffer;
1529 		p[call->count] = 0;
1530 		_debug("motd '%s'", p);
1531 
1532 		call->unmarshall++;
1533 
1534 		/* Fall through */
1535 	case 8:
1536 		break;
1537 	}
1538 
1539 	_leave(" = 0 [done]");
1540 	return 0;
1541 }
1542 
1543 /*
1544  * YFS.GetVolumeStatus operation type
1545  */
1546 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1547 	.name		= "YFS.GetVolumeStatus",
1548 	.op		= yfs_FS_GetVolumeStatus,
1549 	.deliver	= yfs_deliver_fs_get_volume_status,
1550 	.destructor	= afs_flat_call_destructor,
1551 };
1552 
1553 /*
1554  * fetch the status of a volume
1555  */
1556 int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1557 			     struct afs_volume_status *vs)
1558 {
1559 	struct afs_vnode *vnode = fc->vnode;
1560 	struct afs_call *call;
1561 	struct afs_net *net = afs_v2net(vnode);
1562 	__be32 *bp;
1563 
1564 	_enter("");
1565 
1566 	call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1567 				   sizeof(__be32) * 2 +
1568 				   sizeof(struct yfs_xdr_u64),
1569 				   max_t(size_t,
1570 					 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1571 					 sizeof(__be32),
1572 					 AFSOPAQUEMAX + 1));
1573 	if (!call)
1574 		return -ENOMEM;
1575 
1576 	call->key = fc->key;
1577 	call->out_volstatus = vs;
1578 
1579 	/* marshall the parameters */
1580 	bp = call->request;
1581 	bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1582 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1583 	bp = xdr_encode_u64(bp, vnode->fid.vid);
1584 	yfs_check_req(call, bp);
1585 
1586 	afs_use_fs_server(call, fc->cbi);
1587 	trace_afs_make_fs_call(call, &vnode->fid);
1588 	afs_set_fc_call(call, fc);
1589 	afs_make_call(&fc->ac, call, GFP_NOFS);
1590 	return afs_wait_for_call_to_complete(call, &fc->ac);
1591 }
1592 
1593 /*
1594  * YFS.SetLock operation type
1595  */
1596 static const struct afs_call_type yfs_RXYFSSetLock = {
1597 	.name		= "YFS.SetLock",
1598 	.op		= yfs_FS_SetLock,
1599 	.deliver	= yfs_deliver_status_and_volsync,
1600 	.done		= afs_lock_op_done,
1601 	.destructor	= afs_flat_call_destructor,
1602 };
1603 
1604 /*
1605  * YFS.ExtendLock operation type
1606  */
1607 static const struct afs_call_type yfs_RXYFSExtendLock = {
1608 	.name		= "YFS.ExtendLock",
1609 	.op		= yfs_FS_ExtendLock,
1610 	.deliver	= yfs_deliver_status_and_volsync,
1611 	.done		= afs_lock_op_done,
1612 	.destructor	= afs_flat_call_destructor,
1613 };
1614 
1615 /*
1616  * YFS.ReleaseLock operation type
1617  */
1618 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1619 	.name		= "YFS.ReleaseLock",
1620 	.op		= yfs_FS_ReleaseLock,
1621 	.deliver	= yfs_deliver_status_and_volsync,
1622 	.destructor	= afs_flat_call_destructor,
1623 };
1624 
1625 /*
1626  * Set a lock on a file
1627  */
1628 int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,
1629 		    struct afs_status_cb *scb)
1630 {
1631 	struct afs_vnode *vnode = fc->vnode;
1632 	struct afs_call *call;
1633 	struct afs_net *net = afs_v2net(vnode);
1634 	__be32 *bp;
1635 
1636 	_enter("");
1637 
1638 	call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1639 				   sizeof(__be32) * 2 +
1640 				   sizeof(struct yfs_xdr_YFSFid) +
1641 				   sizeof(__be32),
1642 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1643 				   sizeof(struct yfs_xdr_YFSVolSync));
1644 	if (!call)
1645 		return -ENOMEM;
1646 
1647 	call->key = fc->key;
1648 	call->lvnode = vnode;
1649 	call->out_scb = scb;
1650 
1651 	/* marshall the parameters */
1652 	bp = call->request;
1653 	bp = xdr_encode_u32(bp, YFSSETLOCK);
1654 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1655 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1656 	bp = xdr_encode_u32(bp, type);
1657 	yfs_check_req(call, bp);
1658 
1659 	afs_use_fs_server(call, fc->cbi);
1660 	trace_afs_make_fs_calli(call, &vnode->fid, type);
1661 	afs_set_fc_call(call, fc);
1662 	afs_make_call(&fc->ac, call, GFP_NOFS);
1663 	return afs_wait_for_call_to_complete(call, &fc->ac);
1664 }
1665 
1666 /*
1667  * extend a lock on a file
1668  */
1669 int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1670 {
1671 	struct afs_vnode *vnode = fc->vnode;
1672 	struct afs_call *call;
1673 	struct afs_net *net = afs_v2net(vnode);
1674 	__be32 *bp;
1675 
1676 	_enter("");
1677 
1678 	call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1679 				   sizeof(__be32) * 2 +
1680 				   sizeof(struct yfs_xdr_YFSFid),
1681 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1682 				   sizeof(struct yfs_xdr_YFSVolSync));
1683 	if (!call)
1684 		return -ENOMEM;
1685 
1686 	call->key = fc->key;
1687 	call->lvnode = vnode;
1688 	call->out_scb = scb;
1689 
1690 	/* marshall the parameters */
1691 	bp = call->request;
1692 	bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1693 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1694 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1695 	yfs_check_req(call, bp);
1696 
1697 	afs_use_fs_server(call, fc->cbi);
1698 	trace_afs_make_fs_call(call, &vnode->fid);
1699 	afs_set_fc_call(call, fc);
1700 	afs_make_call(&fc->ac, call, GFP_NOFS);
1701 	return afs_wait_for_call_to_complete(call, &fc->ac);
1702 }
1703 
1704 /*
1705  * release a lock on a file
1706  */
1707 int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1708 {
1709 	struct afs_vnode *vnode = fc->vnode;
1710 	struct afs_call *call;
1711 	struct afs_net *net = afs_v2net(vnode);
1712 	__be32 *bp;
1713 
1714 	_enter("");
1715 
1716 	call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1717 				   sizeof(__be32) * 2 +
1718 				   sizeof(struct yfs_xdr_YFSFid),
1719 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1720 				   sizeof(struct yfs_xdr_YFSVolSync));
1721 	if (!call)
1722 		return -ENOMEM;
1723 
1724 	call->key = fc->key;
1725 	call->lvnode = vnode;
1726 	call->out_scb = scb;
1727 
1728 	/* marshall the parameters */
1729 	bp = call->request;
1730 	bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1731 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1732 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1733 	yfs_check_req(call, bp);
1734 
1735 	afs_use_fs_server(call, fc->cbi);
1736 	trace_afs_make_fs_call(call, &vnode->fid);
1737 	afs_set_fc_call(call, fc);
1738 	afs_make_call(&fc->ac, call, GFP_NOFS);
1739 	return afs_wait_for_call_to_complete(call, &fc->ac);
1740 }
1741 
1742 /*
1743  * YFS.FetchStatus operation type
1744  */
1745 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1746 	.name		= "YFS.FetchStatus",
1747 	.op		= yfs_FS_FetchStatus,
1748 	.deliver	= yfs_deliver_fs_status_cb_and_volsync,
1749 	.destructor	= afs_flat_call_destructor,
1750 };
1751 
1752 /*
1753  * Fetch the status information for a fid without needing a vnode handle.
1754  */
1755 int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1756 			struct afs_net *net,
1757 			struct afs_fid *fid,
1758 			struct afs_status_cb *scb,
1759 			struct afs_volsync *volsync)
1760 {
1761 	struct afs_call *call;
1762 	__be32 *bp;
1763 
1764 	_enter(",%x,{%llx:%llu},,",
1765 	       key_serial(fc->key), fid->vid, fid->vnode);
1766 
1767 	call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1768 				   sizeof(__be32) * 2 +
1769 				   sizeof(struct yfs_xdr_YFSFid),
1770 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1771 				   sizeof(struct yfs_xdr_YFSCallBack) +
1772 				   sizeof(struct yfs_xdr_YFSVolSync));
1773 	if (!call) {
1774 		fc->ac.error = -ENOMEM;
1775 		return -ENOMEM;
1776 	}
1777 
1778 	call->key = fc->key;
1779 	call->out_scb = scb;
1780 	call->out_volsync = volsync;
1781 
1782 	/* marshall the parameters */
1783 	bp = call->request;
1784 	bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1785 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1786 	bp = xdr_encode_YFSFid(bp, fid);
1787 	yfs_check_req(call, bp);
1788 
1789 	afs_use_fs_server(call, fc->cbi);
1790 	trace_afs_make_fs_call(call, fid);
1791 	afs_set_fc_call(call, fc);
1792 	afs_make_call(&fc->ac, call, GFP_NOFS);
1793 	return afs_wait_for_call_to_complete(call, &fc->ac);
1794 }
1795 
1796 /*
1797  * Deliver reply data to an YFS.InlineBulkStatus call
1798  */
1799 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1800 {
1801 	struct afs_status_cb *scb;
1802 	const __be32 *bp;
1803 	u32 tmp;
1804 	int ret;
1805 
1806 	_enter("{%u}", call->unmarshall);
1807 
1808 	switch (call->unmarshall) {
1809 	case 0:
1810 		afs_extract_to_tmp(call);
1811 		call->unmarshall++;
1812 
1813 		/* Extract the file status count and array in two steps */
1814 		/* Fall through */
1815 	case 1:
1816 		_debug("extract status count");
1817 		ret = afs_extract_data(call, true);
1818 		if (ret < 0)
1819 			return ret;
1820 
1821 		tmp = ntohl(call->tmp);
1822 		_debug("status count: %u/%u", tmp, call->count2);
1823 		if (tmp != call->count2)
1824 			return afs_protocol_error(call, -EBADMSG,
1825 						  afs_eproto_ibulkst_count);
1826 
1827 		call->count = 0;
1828 		call->unmarshall++;
1829 	more_counts:
1830 		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1831 
1832 		/* Fall through */
1833 	case 2:
1834 		_debug("extract status array %u", call->count);
1835 		ret = afs_extract_data(call, true);
1836 		if (ret < 0)
1837 			return ret;
1838 
1839 		bp = call->buffer;
1840 		scb = &call->out_scb[call->count];
1841 		ret = xdr_decode_YFSFetchStatus(&bp, call, scb);
1842 		if (ret < 0)
1843 			return ret;
1844 
1845 		call->count++;
1846 		if (call->count < call->count2)
1847 			goto more_counts;
1848 
1849 		call->count = 0;
1850 		call->unmarshall++;
1851 		afs_extract_to_tmp(call);
1852 
1853 		/* Extract the callback count and array in two steps */
1854 		/* Fall through */
1855 	case 3:
1856 		_debug("extract CB count");
1857 		ret = afs_extract_data(call, true);
1858 		if (ret < 0)
1859 			return ret;
1860 
1861 		tmp = ntohl(call->tmp);
1862 		_debug("CB count: %u", tmp);
1863 		if (tmp != call->count2)
1864 			return afs_protocol_error(call, -EBADMSG,
1865 						  afs_eproto_ibulkst_cb_count);
1866 		call->count = 0;
1867 		call->unmarshall++;
1868 	more_cbs:
1869 		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1870 
1871 		/* Fall through */
1872 	case 4:
1873 		_debug("extract CB array");
1874 		ret = afs_extract_data(call, true);
1875 		if (ret < 0)
1876 			return ret;
1877 
1878 		_debug("unmarshall CB array");
1879 		bp = call->buffer;
1880 		scb = &call->out_scb[call->count];
1881 		xdr_decode_YFSCallBack(&bp, call, scb);
1882 		call->count++;
1883 		if (call->count < call->count2)
1884 			goto more_cbs;
1885 
1886 		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1887 		call->unmarshall++;
1888 
1889 		/* Fall through */
1890 	case 5:
1891 		ret = afs_extract_data(call, false);
1892 		if (ret < 0)
1893 			return ret;
1894 
1895 		bp = call->buffer;
1896 		xdr_decode_YFSVolSync(&bp, call->out_volsync);
1897 
1898 		call->unmarshall++;
1899 
1900 		/* Fall through */
1901 	case 6:
1902 		break;
1903 	}
1904 
1905 	_leave(" = 0 [done]");
1906 	return 0;
1907 }
1908 
1909 /*
1910  * FS.InlineBulkStatus operation type
1911  */
1912 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1913 	.name		= "YFS.InlineBulkStatus",
1914 	.op		= yfs_FS_InlineBulkStatus,
1915 	.deliver	= yfs_deliver_fs_inline_bulk_status,
1916 	.destructor	= afs_flat_call_destructor,
1917 };
1918 
1919 /*
1920  * Fetch the status information for up to 1024 files
1921  */
1922 int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
1923 			      struct afs_net *net,
1924 			      struct afs_fid *fids,
1925 			      struct afs_status_cb *statuses,
1926 			      unsigned int nr_fids,
1927 			      struct afs_volsync *volsync)
1928 {
1929 	struct afs_call *call;
1930 	__be32 *bp;
1931 	int i;
1932 
1933 	_enter(",%x,{%llx:%llu},%u",
1934 	       key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
1935 
1936 	call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
1937 				   sizeof(__be32) +
1938 				   sizeof(__be32) +
1939 				   sizeof(__be32) +
1940 				   sizeof(struct yfs_xdr_YFSFid) * nr_fids,
1941 				   sizeof(struct yfs_xdr_YFSFetchStatus));
1942 	if (!call) {
1943 		fc->ac.error = -ENOMEM;
1944 		return -ENOMEM;
1945 	}
1946 
1947 	call->key = fc->key;
1948 	call->out_scb = statuses;
1949 	call->out_volsync = volsync;
1950 	call->count2 = nr_fids;
1951 
1952 	/* marshall the parameters */
1953 	bp = call->request;
1954 	bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1955 	bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1956 	bp = xdr_encode_u32(bp, nr_fids);
1957 	for (i = 0; i < nr_fids; i++)
1958 		bp = xdr_encode_YFSFid(bp, &fids[i]);
1959 	yfs_check_req(call, bp);
1960 
1961 	afs_use_fs_server(call, fc->cbi);
1962 	trace_afs_make_fs_call(call, &fids[0]);
1963 	afs_set_fc_call(call, fc);
1964 	afs_make_call(&fc->ac, call, GFP_NOFS);
1965 	return afs_wait_for_call_to_complete(call, &fc->ac);
1966 }
1967 
1968 /*
1969  * Deliver reply data to an YFS.FetchOpaqueACL.
1970  */
1971 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1972 {
1973 	struct yfs_acl *yacl = call->out_yacl;
1974 	struct afs_acl *acl;
1975 	const __be32 *bp;
1976 	unsigned int size;
1977 	int ret;
1978 
1979 	_enter("{%u}", call->unmarshall);
1980 
1981 	switch (call->unmarshall) {
1982 	case 0:
1983 		afs_extract_to_tmp(call);
1984 		call->unmarshall++;
1985 
1986 		/* Extract the file ACL length */
1987 	case 1:
1988 		ret = afs_extract_data(call, true);
1989 		if (ret < 0)
1990 			return ret;
1991 
1992 		size = call->count2 = ntohl(call->tmp);
1993 		size = round_up(size, 4);
1994 
1995 		if (yacl->flags & YFS_ACL_WANT_ACL) {
1996 			acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1997 			if (!acl)
1998 				return -ENOMEM;
1999 			yacl->acl = acl;
2000 			acl->size = call->count2;
2001 			afs_extract_begin(call, acl->data, size);
2002 		} else {
2003 			iov_iter_discard(&call->iter, READ, size);
2004 		}
2005 		call->unmarshall++;
2006 
2007 		/* Extract the file ACL */
2008 	case 2:
2009 		ret = afs_extract_data(call, true);
2010 		if (ret < 0)
2011 			return ret;
2012 
2013 		afs_extract_to_tmp(call);
2014 		call->unmarshall++;
2015 
2016 		/* Extract the volume ACL length */
2017 	case 3:
2018 		ret = afs_extract_data(call, true);
2019 		if (ret < 0)
2020 			return ret;
2021 
2022 		size = call->count2 = ntohl(call->tmp);
2023 		size = round_up(size, 4);
2024 
2025 		if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2026 			acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2027 			if (!acl)
2028 				return -ENOMEM;
2029 			yacl->vol_acl = acl;
2030 			acl->size = call->count2;
2031 			afs_extract_begin(call, acl->data, size);
2032 		} else {
2033 			iov_iter_discard(&call->iter, READ, size);
2034 		}
2035 		call->unmarshall++;
2036 
2037 		/* Extract the volume ACL */
2038 	case 4:
2039 		ret = afs_extract_data(call, true);
2040 		if (ret < 0)
2041 			return ret;
2042 
2043 		afs_extract_to_buf(call,
2044 				   sizeof(__be32) * 2 +
2045 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2046 				   sizeof(struct yfs_xdr_YFSVolSync));
2047 		call->unmarshall++;
2048 
2049 		/* extract the metadata */
2050 	case 5:
2051 		ret = afs_extract_data(call, false);
2052 		if (ret < 0)
2053 			return ret;
2054 
2055 		bp = call->buffer;
2056 		yacl->inherit_flag = ntohl(*bp++);
2057 		yacl->num_cleaned = ntohl(*bp++);
2058 		ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
2059 		if (ret < 0)
2060 			return ret;
2061 		xdr_decode_YFSVolSync(&bp, call->out_volsync);
2062 
2063 		call->unmarshall++;
2064 
2065 	case 6:
2066 		break;
2067 	}
2068 
2069 	_leave(" = 0 [done]");
2070 	return 0;
2071 }
2072 
2073 void yfs_free_opaque_acl(struct yfs_acl *yacl)
2074 {
2075 	if (yacl) {
2076 		kfree(yacl->acl);
2077 		kfree(yacl->vol_acl);
2078 		kfree(yacl);
2079 	}
2080 }
2081 
2082 /*
2083  * YFS.FetchOpaqueACL operation type
2084  */
2085 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2086 	.name		= "YFS.FetchOpaqueACL",
2087 	.op		= yfs_FS_FetchOpaqueACL,
2088 	.deliver	= yfs_deliver_fs_fetch_opaque_acl,
2089 	.destructor	= afs_flat_call_destructor,
2090 };
2091 
2092 /*
2093  * Fetch the YFS advanced ACLs for a file.
2094  */
2095 struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
2096 					struct yfs_acl *yacl,
2097 					struct afs_status_cb *scb)
2098 {
2099 	struct afs_vnode *vnode = fc->vnode;
2100 	struct afs_call *call;
2101 	struct afs_net *net = afs_v2net(vnode);
2102 	__be32 *bp;
2103 
2104 	_enter(",%x,{%llx:%llu},,",
2105 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2106 
2107 	call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,
2108 				   sizeof(__be32) * 2 +
2109 				   sizeof(struct yfs_xdr_YFSFid),
2110 				   sizeof(__be32) * 2 +
2111 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2112 				   sizeof(struct yfs_xdr_YFSVolSync));
2113 	if (!call) {
2114 		fc->ac.error = -ENOMEM;
2115 		return ERR_PTR(-ENOMEM);
2116 	}
2117 
2118 	call->key = fc->key;
2119 	call->out_yacl = yacl;
2120 	call->out_scb = scb;
2121 	call->out_volsync = NULL;
2122 
2123 	/* marshall the parameters */
2124 	bp = call->request;
2125 	bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2126 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
2127 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
2128 	yfs_check_req(call, bp);
2129 
2130 	afs_use_fs_server(call, fc->cbi);
2131 	trace_afs_make_fs_call(call, &vnode->fid);
2132 	afs_make_call(&fc->ac, call, GFP_KERNEL);
2133 	return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2134 }
2135 
2136 /*
2137  * YFS.StoreOpaqueACL2 operation type
2138  */
2139 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2140 	.name		= "YFS.StoreOpaqueACL2",
2141 	.op		= yfs_FS_StoreOpaqueACL2,
2142 	.deliver	= yfs_deliver_status_and_volsync,
2143 	.destructor	= afs_flat_call_destructor,
2144 };
2145 
2146 /*
2147  * Fetch the YFS ACL for a file.
2148  */
2149 int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl,
2150 			     struct afs_status_cb *scb)
2151 {
2152 	struct afs_vnode *vnode = fc->vnode;
2153 	struct afs_call *call;
2154 	struct afs_net *net = afs_v2net(vnode);
2155 	size_t size;
2156 	__be32 *bp;
2157 
2158 	_enter(",%x,{%llx:%llu},,",
2159 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2160 
2161 	size = round_up(acl->size, 4);
2162 	call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
2163 				   sizeof(__be32) * 2 +
2164 				   sizeof(struct yfs_xdr_YFSFid) +
2165 				   sizeof(__be32) + size,
2166 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2167 				   sizeof(struct yfs_xdr_YFSVolSync));
2168 	if (!call) {
2169 		fc->ac.error = -ENOMEM;
2170 		return -ENOMEM;
2171 	}
2172 
2173 	call->key = fc->key;
2174 	call->out_scb = scb;
2175 	call->out_volsync = NULL;
2176 
2177 	/* marshall the parameters */
2178 	bp = call->request;
2179 	bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2180 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
2181 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
2182 	bp = xdr_encode_u32(bp, acl->size);
2183 	memcpy(bp, acl->data, acl->size);
2184 	if (acl->size != size)
2185 		memset((void *)bp + acl->size, 0, size - acl->size);
2186 	yfs_check_req(call, bp);
2187 
2188 	trace_afs_make_fs_call(call, &vnode->fid);
2189 	afs_make_call(&fc->ac, call, GFP_KERNEL);
2190 	return afs_wait_for_call_to_complete(call, &fc->ac);
2191 }
2192