xref: /openbmc/linux/fs/afs/yfsclient.c (revision 5c2d0de5)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* YFS File Server client stubs
3  *
4  * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7 
8 #include <linux/init.h>
9 #include <linux/slab.h>
10 #include <linux/sched.h>
11 #include <linux/circ_buf.h>
12 #include <linux/iversion.h>
13 #include "internal.h"
14 #include "afs_fs.h"
15 #include "xdr_fs.h"
16 #include "protocol_yfs.h"
17 
18 static const struct afs_fid afs_zero_fid;
19 
20 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
21 {
22 	call->cbi = afs_get_cb_interest(cbi);
23 }
24 
25 #define xdr_size(x) (sizeof(*x) / sizeof(__be32))
26 
27 static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
28 {
29 	const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
30 
31 	fid->vid	= xdr_to_u64(x->volume);
32 	fid->vnode	= xdr_to_u64(x->vnode.lo);
33 	fid->vnode_hi	= ntohl(x->vnode.hi);
34 	fid->unique	= ntohl(x->vnode.unique);
35 	*_bp += xdr_size(x);
36 }
37 
38 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
39 {
40 	*bp++ = htonl(n);
41 	return bp;
42 }
43 
44 static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
45 {
46 	struct yfs_xdr_u64 *x = (void *)bp;
47 
48 	*x = u64_to_xdr(n);
49 	return bp + xdr_size(x);
50 }
51 
52 static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
53 {
54 	struct yfs_xdr_YFSFid *x = (void *)bp;
55 
56 	x->volume	= u64_to_xdr(fid->vid);
57 	x->vnode.lo	= u64_to_xdr(fid->vnode);
58 	x->vnode.hi	= htonl(fid->vnode_hi);
59 	x->vnode.unique	= htonl(fid->unique);
60 	return bp + xdr_size(x);
61 }
62 
63 static size_t xdr_strlen(unsigned int len)
64 {
65 	return sizeof(__be32) + round_up(len, sizeof(__be32));
66 }
67 
68 static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
69 {
70 	bp = xdr_encode_u32(bp, len);
71 	bp = memcpy(bp, p, len);
72 	if (len & 3) {
73 		unsigned int pad = 4 - (len & 3);
74 
75 		memset((u8 *)bp + len, 0, pad);
76 		len += pad;
77 	}
78 
79 	return bp + len / sizeof(__be32);
80 }
81 
82 static s64 linux_to_yfs_time(const struct timespec64 *t)
83 {
84 	/* Convert to 100ns intervals. */
85 	return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
86 }
87 
88 static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
89 {
90 	struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
91 
92 	x->mask		= htonl(AFS_SET_MODE);
93 	x->mode		= htonl(mode & S_IALLUGO);
94 	x->mtime_client	= u64_to_xdr(0);
95 	x->owner	= u64_to_xdr(0);
96 	x->group	= u64_to_xdr(0);
97 	return bp + xdr_size(x);
98 }
99 
100 static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
101 {
102 	struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
103 	s64 mtime = linux_to_yfs_time(t);
104 
105 	x->mask		= htonl(AFS_SET_MTIME);
106 	x->mode		= htonl(0);
107 	x->mtime_client	= u64_to_xdr(mtime);
108 	x->owner	= u64_to_xdr(0);
109 	x->group	= u64_to_xdr(0);
110 	return bp + xdr_size(x);
111 }
112 
113 /*
114  * Convert a signed 100ns-resolution 64-bit time into a timespec.
115  */
116 static struct timespec64 yfs_time_to_linux(s64 t)
117 {
118 	struct timespec64 ts;
119 	u64 abs_t;
120 
121 	/*
122 	 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
123 	 * the alternative, do_div, does not work with negative numbers so have
124 	 * to special case them
125 	 */
126 	if (t < 0) {
127 		abs_t = -t;
128 		ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
129 		ts.tv_nsec = -ts.tv_nsec;
130 		ts.tv_sec = -abs_t;
131 	} else {
132 		abs_t = t;
133 		ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
134 		ts.tv_sec = abs_t;
135 	}
136 
137 	return ts;
138 }
139 
140 static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
141 {
142 	s64 t = xdr_to_u64(xdr);
143 
144 	return yfs_time_to_linux(t);
145 }
146 
147 static void yfs_check_req(struct afs_call *call, __be32 *bp)
148 {
149 	size_t len = (void *)bp - call->request;
150 
151 	if (len > call->request_size)
152 		pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
153 		       call->type->name, len, call->request_size);
154 	else if (len < call->request_size)
155 		pr_warn("kAFS: %s: Request buffer underflow (%zu<%u)\n",
156 			call->type->name, len, call->request_size);
157 }
158 
159 /*
160  * Dump a bad file status record.
161  */
162 static void xdr_dump_bad(const __be32 *bp)
163 {
164 	__be32 x[4];
165 	int i;
166 
167 	pr_notice("YFS XDR: Bad status record\n");
168 	for (i = 0; i < 6 * 4 * 4; i += 16) {
169 		memcpy(x, bp, 16);
170 		bp += 4;
171 		pr_notice("%03x: %08x %08x %08x %08x\n",
172 			  i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
173 	}
174 
175 	memcpy(x, bp, 8);
176 	pr_notice("0x60: %08x %08x\n", ntohl(x[0]), ntohl(x[1]));
177 }
178 
179 /*
180  * Decode a YFSFetchStatus block
181  */
182 static int xdr_decode_YFSFetchStatus(const __be32 **_bp,
183 				     struct afs_call *call,
184 				     struct afs_status_cb *scb)
185 {
186 	const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
187 	struct afs_file_status *status = &scb->status;
188 	u32 type;
189 	int ret;
190 
191 	status->abort_code = ntohl(xdr->abort_code);
192 	if (status->abort_code != 0) {
193 		if (status->abort_code == VNOVNODE)
194 			status->nlink = 0;
195 		scb->have_error = true;
196 		goto good;
197 	}
198 
199 	type = ntohl(xdr->type);
200 	switch (type) {
201 	case AFS_FTYPE_FILE:
202 	case AFS_FTYPE_DIR:
203 	case AFS_FTYPE_SYMLINK:
204 		status->type = type;
205 		break;
206 	default:
207 		goto bad;
208 	}
209 
210 	status->nlink		= ntohl(xdr->nlink);
211 	status->author		= xdr_to_u64(xdr->author);
212 	status->owner		= xdr_to_u64(xdr->owner);
213 	status->caller_access	= ntohl(xdr->caller_access); /* Ticket dependent */
214 	status->anon_access	= ntohl(xdr->anon_access);
215 	status->mode		= ntohl(xdr->mode) & S_IALLUGO;
216 	status->group		= xdr_to_u64(xdr->group);
217 	status->lock_count	= ntohl(xdr->lock_count);
218 
219 	status->mtime_client	= xdr_to_time(xdr->mtime_client);
220 	status->mtime_server	= xdr_to_time(xdr->mtime_server);
221 	status->size		= xdr_to_u64(xdr->size);
222 	status->data_version	= xdr_to_u64(xdr->data_version);
223 	scb->have_status	= true;
224 good:
225 	ret = 0;
226 advance:
227 	*_bp += xdr_size(xdr);
228 	return ret;
229 
230 bad:
231 	xdr_dump_bad(*_bp);
232 	ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
233 	goto advance;
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 		/* Fall through */
458 
459 		/* extract the returned data length */
460 	case 1:
461 		_debug("extract data length");
462 		ret = afs_extract_data(call, true);
463 		if (ret < 0)
464 			return ret;
465 
466 		req->actual_len = be64_to_cpu(call->tmp64);
467 		_debug("DATA length: %llu", req->actual_len);
468 		req->remain = min(req->len, req->actual_len);
469 		if (req->remain == 0)
470 			goto no_more_data;
471 
472 		call->unmarshall++;
473 
474 	begin_page:
475 		ASSERTCMP(req->index, <, req->nr_pages);
476 		if (req->remain > PAGE_SIZE - req->offset)
477 			size = PAGE_SIZE - req->offset;
478 		else
479 			size = req->remain;
480 		call->bvec[0].bv_len = size;
481 		call->bvec[0].bv_offset = req->offset;
482 		call->bvec[0].bv_page = req->pages[req->index];
483 		iov_iter_bvec(&call->def_iter, READ, call->bvec, 1, size);
484 		ASSERTCMP(size, <=, PAGE_SIZE);
485 		/* Fall through */
486 
487 		/* extract the returned data */
488 	case 2:
489 		_debug("extract data %zu/%llu",
490 		       iov_iter_count(call->iter), req->remain);
491 
492 		ret = afs_extract_data(call, true);
493 		if (ret < 0)
494 			return ret;
495 		req->remain -= call->bvec[0].bv_len;
496 		req->offset += call->bvec[0].bv_len;
497 		ASSERTCMP(req->offset, <=, PAGE_SIZE);
498 		if (req->offset == PAGE_SIZE) {
499 			req->offset = 0;
500 			if (req->page_done)
501 				req->page_done(req);
502 			req->index++;
503 			if (req->remain > 0)
504 				goto begin_page;
505 		}
506 
507 		ASSERTCMP(req->remain, ==, 0);
508 		if (req->actual_len <= req->len)
509 			goto no_more_data;
510 
511 		/* Discard any excess data the server gave us */
512 		afs_extract_discard(call, req->actual_len - req->len);
513 		call->unmarshall = 3;
514 		/* Fall through */
515 
516 	case 3:
517 		_debug("extract discard %zu/%llu",
518 		       iov_iter_count(call->iter), req->actual_len - req->len);
519 
520 		ret = afs_extract_data(call, true);
521 		if (ret < 0)
522 			return ret;
523 
524 	no_more_data:
525 		call->unmarshall = 4;
526 		afs_extract_to_buf(call,
527 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
528 				   sizeof(struct yfs_xdr_YFSCallBack) +
529 				   sizeof(struct yfs_xdr_YFSVolSync));
530 		/* Fall through */
531 
532 		/* extract the metadata */
533 	case 4:
534 		ret = afs_extract_data(call, false);
535 		if (ret < 0)
536 			return ret;
537 
538 		bp = call->buffer;
539 		ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
540 		if (ret < 0)
541 			return ret;
542 		xdr_decode_YFSCallBack(&bp, call, call->out_scb);
543 		xdr_decode_YFSVolSync(&bp, call->out_volsync);
544 
545 		req->data_version = call->out_scb->status.data_version;
546 		req->file_size = call->out_scb->status.size;
547 
548 		call->unmarshall++;
549 		/* Fall through */
550 
551 	case 5:
552 		break;
553 	}
554 
555 	for (; req->index < req->nr_pages; req->index++) {
556 		if (req->offset < PAGE_SIZE)
557 			zero_user_segment(req->pages[req->index],
558 					  req->offset, PAGE_SIZE);
559 		if (req->page_done)
560 			req->page_done(req);
561 		req->offset = 0;
562 	}
563 
564 	_leave(" = 0 [done]");
565 	return 0;
566 }
567 
568 static void yfs_fetch_data_destructor(struct afs_call *call)
569 {
570 	afs_put_read(call->read_request);
571 	afs_flat_call_destructor(call);
572 }
573 
574 /*
575  * YFS.FetchData64 operation type
576  */
577 static const struct afs_call_type yfs_RXYFSFetchData64 = {
578 	.name		= "YFS.FetchData64",
579 	.op		= yfs_FS_FetchData64,
580 	.deliver	= yfs_deliver_fs_fetch_data64,
581 	.destructor	= yfs_fetch_data_destructor,
582 };
583 
584 /*
585  * Fetch data from a file.
586  */
587 int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
588 		      struct afs_read *req)
589 {
590 	struct afs_vnode *vnode = fc->vnode;
591 	struct afs_call *call;
592 	struct afs_net *net = afs_v2net(vnode);
593 	__be32 *bp;
594 
595 	_enter(",%x,{%llx:%llu},%llx,%llx",
596 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
597 	       req->pos, req->len);
598 
599 	call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
600 				   sizeof(__be32) * 2 +
601 				   sizeof(struct yfs_xdr_YFSFid) +
602 				   sizeof(struct yfs_xdr_u64) * 2,
603 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
604 				   sizeof(struct yfs_xdr_YFSCallBack) +
605 				   sizeof(struct yfs_xdr_YFSVolSync));
606 	if (!call)
607 		return -ENOMEM;
608 
609 	call->key = fc->key;
610 	call->out_scb = scb;
611 	call->out_volsync = NULL;
612 	call->read_request = afs_get_read(req);
613 
614 	/* marshall the parameters */
615 	bp = call->request;
616 	bp = xdr_encode_u32(bp, YFSFETCHDATA64);
617 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
618 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
619 	bp = xdr_encode_u64(bp, req->pos);
620 	bp = xdr_encode_u64(bp, req->len);
621 	yfs_check_req(call, bp);
622 
623 	afs_use_fs_server(call, fc->cbi);
624 	trace_afs_make_fs_call(call, &vnode->fid);
625 	afs_set_fc_call(call, fc);
626 	afs_make_call(&fc->ac, call, GFP_NOFS);
627 	return afs_wait_for_call_to_complete(call, &fc->ac);
628 }
629 
630 /*
631  * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
632  */
633 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
634 {
635 	const __be32 *bp;
636 	int ret;
637 
638 	_enter("{%u}", call->unmarshall);
639 
640 	ret = afs_transfer_reply(call);
641 	if (ret < 0)
642 		return ret;
643 
644 	/* unmarshall the reply once we've received all of it */
645 	bp = call->buffer;
646 	xdr_decode_YFSFid(&bp, call->out_fid);
647 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
648 	if (ret < 0)
649 		return ret;
650 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
651 	if (ret < 0)
652 		return ret;
653 	xdr_decode_YFSCallBack(&bp, call, call->out_scb);
654 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
655 
656 	_leave(" = 0 [done]");
657 	return 0;
658 }
659 
660 /*
661  * FS.CreateFile and FS.MakeDir operation type
662  */
663 static const struct afs_call_type afs_RXFSCreateFile = {
664 	.name		= "YFS.CreateFile",
665 	.op		= yfs_FS_CreateFile,
666 	.deliver	= yfs_deliver_fs_create_vnode,
667 	.destructor	= afs_flat_call_destructor,
668 };
669 
670 /*
671  * Create a file.
672  */
673 int yfs_fs_create_file(struct afs_fs_cursor *fc,
674 		       const char *name,
675 		       umode_t mode,
676 		       struct afs_status_cb *dvnode_scb,
677 		       struct afs_fid *newfid,
678 		       struct afs_status_cb *new_scb)
679 {
680 	struct afs_vnode *dvnode = fc->vnode;
681 	struct afs_call *call;
682 	struct afs_net *net = afs_v2net(dvnode);
683 	size_t namesz, reqsz, rplsz;
684 	__be32 *bp;
685 
686 	_enter("");
687 
688 	namesz = strlen(name);
689 	reqsz = (sizeof(__be32) +
690 		 sizeof(__be32) +
691 		 sizeof(struct yfs_xdr_YFSFid) +
692 		 xdr_strlen(namesz) +
693 		 sizeof(struct yfs_xdr_YFSStoreStatus) +
694 		 sizeof(__be32));
695 	rplsz = (sizeof(struct yfs_xdr_YFSFid) +
696 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
697 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
698 		 sizeof(struct yfs_xdr_YFSCallBack) +
699 		 sizeof(struct yfs_xdr_YFSVolSync));
700 
701 	call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
702 	if (!call)
703 		return -ENOMEM;
704 
705 	call->key = fc->key;
706 	call->out_dir_scb = dvnode_scb;
707 	call->out_fid = newfid;
708 	call->out_scb = new_scb;
709 
710 	/* marshall the parameters */
711 	bp = call->request;
712 	bp = xdr_encode_u32(bp, YFSCREATEFILE);
713 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
714 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
715 	bp = xdr_encode_string(bp, name, namesz);
716 	bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
717 	bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
718 	yfs_check_req(call, bp);
719 
720 	afs_use_fs_server(call, fc->cbi);
721 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
722 	afs_set_fc_call(call, fc);
723 	afs_make_call(&fc->ac, call, GFP_NOFS);
724 	return afs_wait_for_call_to_complete(call, &fc->ac);
725 }
726 
727 static const struct afs_call_type yfs_RXFSMakeDir = {
728 	.name		= "YFS.MakeDir",
729 	.op		= yfs_FS_MakeDir,
730 	.deliver	= yfs_deliver_fs_create_vnode,
731 	.destructor	= afs_flat_call_destructor,
732 };
733 
734 /*
735  * Make a directory.
736  */
737 int yfs_fs_make_dir(struct afs_fs_cursor *fc,
738 		    const char *name,
739 		    umode_t mode,
740 		    struct afs_status_cb *dvnode_scb,
741 		    struct afs_fid *newfid,
742 		    struct afs_status_cb *new_scb)
743 {
744 	struct afs_vnode *dvnode = fc->vnode;
745 	struct afs_call *call;
746 	struct afs_net *net = afs_v2net(dvnode);
747 	size_t namesz, reqsz, rplsz;
748 	__be32 *bp;
749 
750 	_enter("");
751 
752 	namesz = strlen(name);
753 	reqsz = (sizeof(__be32) +
754 		 sizeof(struct yfs_xdr_RPCFlags) +
755 		 sizeof(struct yfs_xdr_YFSFid) +
756 		 xdr_strlen(namesz) +
757 		 sizeof(struct yfs_xdr_YFSStoreStatus));
758 	rplsz = (sizeof(struct yfs_xdr_YFSFid) +
759 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
760 		 sizeof(struct yfs_xdr_YFSFetchStatus) +
761 		 sizeof(struct yfs_xdr_YFSCallBack) +
762 		 sizeof(struct yfs_xdr_YFSVolSync));
763 
764 	call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
765 	if (!call)
766 		return -ENOMEM;
767 
768 	call->key = fc->key;
769 	call->out_dir_scb = dvnode_scb;
770 	call->out_fid = newfid;
771 	call->out_scb = new_scb;
772 
773 	/* marshall the parameters */
774 	bp = call->request;
775 	bp = xdr_encode_u32(bp, YFSMAKEDIR);
776 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
777 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
778 	bp = xdr_encode_string(bp, name, namesz);
779 	bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
780 	yfs_check_req(call, bp);
781 
782 	afs_use_fs_server(call, fc->cbi);
783 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
784 	afs_set_fc_call(call, fc);
785 	afs_make_call(&fc->ac, call, GFP_NOFS);
786 	return afs_wait_for_call_to_complete(call, &fc->ac);
787 }
788 
789 /*
790  * Deliver reply data to a YFS.RemoveFile2 operation.
791  */
792 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
793 {
794 	struct afs_fid fid;
795 	const __be32 *bp;
796 	int ret;
797 
798 	_enter("{%u}", call->unmarshall);
799 
800 	ret = afs_transfer_reply(call);
801 	if (ret < 0)
802 		return ret;
803 
804 	bp = call->buffer;
805 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
806 	if (ret < 0)
807 		return ret;
808 
809 	xdr_decode_YFSFid(&bp, &fid);
810 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
811 	if (ret < 0)
812 		return ret;
813 	/* Was deleted if vnode->status.abort_code == VNOVNODE. */
814 
815 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
816 	return 0;
817 }
818 
819 /*
820  * YFS.RemoveFile2 operation type.
821  */
822 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
823 	.name		= "YFS.RemoveFile2",
824 	.op		= yfs_FS_RemoveFile2,
825 	.deliver	= yfs_deliver_fs_remove_file2,
826 	.destructor	= afs_flat_call_destructor,
827 };
828 
829 /*
830  * Remove a file and retrieve new file status.
831  */
832 int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
833 			const char *name, struct afs_status_cb *dvnode_scb,
834 			struct afs_status_cb *vnode_scb)
835 {
836 	struct afs_vnode *dvnode = fc->vnode;
837 	struct afs_call *call;
838 	struct afs_net *net = afs_v2net(dvnode);
839 	size_t namesz;
840 	__be32 *bp;
841 
842 	_enter("");
843 
844 	namesz = strlen(name);
845 
846 	call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
847 				   sizeof(__be32) +
848 				   sizeof(struct yfs_xdr_RPCFlags) +
849 				   sizeof(struct yfs_xdr_YFSFid) +
850 				   xdr_strlen(namesz),
851 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
852 				   sizeof(struct yfs_xdr_YFSFid) +
853 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
854 				   sizeof(struct yfs_xdr_YFSVolSync));
855 	if (!call)
856 		return -ENOMEM;
857 
858 	call->key = fc->key;
859 	call->out_dir_scb = dvnode_scb;
860 	call->out_scb = vnode_scb;
861 
862 	/* marshall the parameters */
863 	bp = call->request;
864 	bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
865 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
866 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
867 	bp = xdr_encode_string(bp, name, namesz);
868 	yfs_check_req(call, bp);
869 
870 	afs_use_fs_server(call, fc->cbi);
871 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
872 	afs_set_fc_call(call, fc);
873 	afs_make_call(&fc->ac, call, GFP_NOFS);
874 	return afs_wait_for_call_to_complete(call, &fc->ac);
875 }
876 
877 /*
878  * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
879  */
880 static int yfs_deliver_fs_remove(struct afs_call *call)
881 {
882 	const __be32 *bp;
883 	int ret;
884 
885 	_enter("{%u}", call->unmarshall);
886 
887 	ret = afs_transfer_reply(call);
888 	if (ret < 0)
889 		return ret;
890 
891 	bp = call->buffer;
892 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
893 	if (ret < 0)
894 		return ret;
895 
896 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
897 	return 0;
898 }
899 
900 /*
901  * FS.RemoveDir and FS.RemoveFile operation types.
902  */
903 static const struct afs_call_type yfs_RXYFSRemoveFile = {
904 	.name		= "YFS.RemoveFile",
905 	.op		= yfs_FS_RemoveFile,
906 	.deliver	= yfs_deliver_fs_remove,
907 	.destructor	= afs_flat_call_destructor,
908 };
909 
910 static const struct afs_call_type yfs_RXYFSRemoveDir = {
911 	.name		= "YFS.RemoveDir",
912 	.op		= yfs_FS_RemoveDir,
913 	.deliver	= yfs_deliver_fs_remove,
914 	.destructor	= afs_flat_call_destructor,
915 };
916 
917 /*
918  * remove a file or directory
919  */
920 int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
921 		  const char *name, bool isdir,
922 		  struct afs_status_cb *dvnode_scb)
923 {
924 	struct afs_vnode *dvnode = fc->vnode;
925 	struct afs_call *call;
926 	struct afs_net *net = afs_v2net(dvnode);
927 	size_t namesz;
928 	__be32 *bp;
929 
930 	_enter("");
931 
932 	namesz = strlen(name);
933 	call = afs_alloc_flat_call(
934 		net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
935 		sizeof(__be32) +
936 		sizeof(struct yfs_xdr_RPCFlags) +
937 		sizeof(struct yfs_xdr_YFSFid) +
938 		xdr_strlen(namesz),
939 		sizeof(struct yfs_xdr_YFSFetchStatus) +
940 		sizeof(struct yfs_xdr_YFSVolSync));
941 	if (!call)
942 		return -ENOMEM;
943 
944 	call->key = fc->key;
945 	call->out_dir_scb = dvnode_scb;
946 
947 	/* marshall the parameters */
948 	bp = call->request;
949 	bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
950 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
951 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
952 	bp = xdr_encode_string(bp, name, namesz);
953 	yfs_check_req(call, bp);
954 
955 	afs_use_fs_server(call, fc->cbi);
956 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
957 	afs_set_fc_call(call, fc);
958 	afs_make_call(&fc->ac, call, GFP_NOFS);
959 	return afs_wait_for_call_to_complete(call, &fc->ac);
960 }
961 
962 /*
963  * Deliver reply data to a YFS.Link operation.
964  */
965 static int yfs_deliver_fs_link(struct afs_call *call)
966 {
967 	const __be32 *bp;
968 	int ret;
969 
970 	_enter("{%u}", call->unmarshall);
971 
972 	ret = afs_transfer_reply(call);
973 	if (ret < 0)
974 		return ret;
975 
976 	bp = call->buffer;
977 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
978 	if (ret < 0)
979 		return ret;
980 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
981 	if (ret < 0)
982 		return ret;
983 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
984 	_leave(" = 0 [done]");
985 	return 0;
986 }
987 
988 /*
989  * YFS.Link operation type.
990  */
991 static const struct afs_call_type yfs_RXYFSLink = {
992 	.name		= "YFS.Link",
993 	.op		= yfs_FS_Link,
994 	.deliver	= yfs_deliver_fs_link,
995 	.destructor	= afs_flat_call_destructor,
996 };
997 
998 /*
999  * Make a hard link.
1000  */
1001 int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1002 		const char *name,
1003 		struct afs_status_cb *dvnode_scb,
1004 		struct afs_status_cb *vnode_scb)
1005 {
1006 	struct afs_vnode *dvnode = fc->vnode;
1007 	struct afs_call *call;
1008 	struct afs_net *net = afs_v2net(vnode);
1009 	size_t namesz;
1010 	__be32 *bp;
1011 
1012 	_enter("");
1013 
1014 	namesz = strlen(name);
1015 	call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1016 				   sizeof(__be32) +
1017 				   sizeof(struct yfs_xdr_RPCFlags) +
1018 				   sizeof(struct yfs_xdr_YFSFid) +
1019 				   xdr_strlen(namesz) +
1020 				   sizeof(struct yfs_xdr_YFSFid),
1021 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1022 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1023 				   sizeof(struct yfs_xdr_YFSVolSync));
1024 	if (!call)
1025 		return -ENOMEM;
1026 
1027 	call->key = fc->key;
1028 	call->out_dir_scb = dvnode_scb;
1029 	call->out_scb = vnode_scb;
1030 
1031 	/* marshall the parameters */
1032 	bp = call->request;
1033 	bp = xdr_encode_u32(bp, YFSLINK);
1034 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1035 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1036 	bp = xdr_encode_string(bp, name, namesz);
1037 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1038 	yfs_check_req(call, bp);
1039 
1040 	afs_use_fs_server(call, fc->cbi);
1041 	trace_afs_make_fs_call1(call, &vnode->fid, name);
1042 	afs_set_fc_call(call, fc);
1043 	afs_make_call(&fc->ac, call, GFP_NOFS);
1044 	return afs_wait_for_call_to_complete(call, &fc->ac);
1045 }
1046 
1047 /*
1048  * Deliver reply data to a YFS.Symlink operation.
1049  */
1050 static int yfs_deliver_fs_symlink(struct afs_call *call)
1051 {
1052 	const __be32 *bp;
1053 	int ret;
1054 
1055 	_enter("{%u}", call->unmarshall);
1056 
1057 	ret = afs_transfer_reply(call);
1058 	if (ret < 0)
1059 		return ret;
1060 
1061 	/* unmarshall the reply once we've received all of it */
1062 	bp = call->buffer;
1063 	xdr_decode_YFSFid(&bp, call->out_fid);
1064 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1065 	if (ret < 0)
1066 		return ret;
1067 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1068 	if (ret < 0)
1069 		return ret;
1070 	xdr_decode_YFSVolSync(&bp, call->out_volsync);
1071 
1072 	_leave(" = 0 [done]");
1073 	return 0;
1074 }
1075 
1076 /*
1077  * YFS.Symlink operation type
1078  */
1079 static const struct afs_call_type yfs_RXYFSSymlink = {
1080 	.name		= "YFS.Symlink",
1081 	.op		= yfs_FS_Symlink,
1082 	.deliver	= yfs_deliver_fs_symlink,
1083 	.destructor	= afs_flat_call_destructor,
1084 };
1085 
1086 /*
1087  * Create a symbolic link.
1088  */
1089 int yfs_fs_symlink(struct afs_fs_cursor *fc,
1090 		   const char *name,
1091 		   const char *contents,
1092 		   struct afs_status_cb *dvnode_scb,
1093 		   struct afs_fid *newfid,
1094 		   struct afs_status_cb *vnode_scb)
1095 {
1096 	struct afs_vnode *dvnode = fc->vnode;
1097 	struct afs_call *call;
1098 	struct afs_net *net = afs_v2net(dvnode);
1099 	size_t namesz, contents_sz;
1100 	__be32 *bp;
1101 
1102 	_enter("");
1103 
1104 	namesz = strlen(name);
1105 	contents_sz = strlen(contents);
1106 	call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1107 				   sizeof(__be32) +
1108 				   sizeof(struct yfs_xdr_RPCFlags) +
1109 				   sizeof(struct yfs_xdr_YFSFid) +
1110 				   xdr_strlen(namesz) +
1111 				   xdr_strlen(contents_sz) +
1112 				   sizeof(struct yfs_xdr_YFSStoreStatus),
1113 				   sizeof(struct yfs_xdr_YFSFid) +
1114 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1115 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1116 				   sizeof(struct yfs_xdr_YFSVolSync));
1117 	if (!call)
1118 		return -ENOMEM;
1119 
1120 	call->key = fc->key;
1121 	call->out_dir_scb = dvnode_scb;
1122 	call->out_fid = newfid;
1123 	call->out_scb = vnode_scb;
1124 
1125 	/* marshall the parameters */
1126 	bp = call->request;
1127 	bp = xdr_encode_u32(bp, YFSSYMLINK);
1128 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1129 	bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1130 	bp = xdr_encode_string(bp, name, namesz);
1131 	bp = xdr_encode_string(bp, contents, contents_sz);
1132 	bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1133 	yfs_check_req(call, bp);
1134 
1135 	afs_use_fs_server(call, fc->cbi);
1136 	trace_afs_make_fs_call1(call, &dvnode->fid, name);
1137 	afs_set_fc_call(call, fc);
1138 	afs_make_call(&fc->ac, call, GFP_NOFS);
1139 	return afs_wait_for_call_to_complete(call, &fc->ac);
1140 }
1141 
1142 /*
1143  * Deliver reply data to a YFS.Rename operation.
1144  */
1145 static int yfs_deliver_fs_rename(struct afs_call *call)
1146 {
1147 	const __be32 *bp;
1148 	int ret;
1149 
1150 	_enter("{%u}", call->unmarshall);
1151 
1152 	ret = afs_transfer_reply(call);
1153 	if (ret < 0)
1154 		return ret;
1155 
1156 	bp = call->buffer;
1157 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1158 	if (ret < 0)
1159 		return ret;
1160 	ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1161 	if (ret < 0)
1162 		return ret;
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 		/* Fall through */
1437 
1438 		/* extract the returned status record */
1439 	case 1:
1440 		_debug("extract status");
1441 		ret = afs_extract_data(call, true);
1442 		if (ret < 0)
1443 			return ret;
1444 
1445 		bp = call->buffer;
1446 		xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus);
1447 		call->unmarshall++;
1448 		afs_extract_to_tmp(call);
1449 		/* Fall through */
1450 
1451 		/* extract the volume name length */
1452 	case 2:
1453 		ret = afs_extract_data(call, true);
1454 		if (ret < 0)
1455 			return ret;
1456 
1457 		call->count = ntohl(call->tmp);
1458 		_debug("volname length: %u", call->count);
1459 		if (call->count >= AFSNAMEMAX)
1460 			return afs_protocol_error(call, -EBADMSG,
1461 						  afs_eproto_volname_len);
1462 		size = (call->count + 3) & ~3; /* It's padded */
1463 		afs_extract_to_buf(call, size);
1464 		call->unmarshall++;
1465 		/* Fall through */
1466 
1467 		/* extract the volume name */
1468 	case 3:
1469 		_debug("extract volname");
1470 		ret = afs_extract_data(call, true);
1471 		if (ret < 0)
1472 			return ret;
1473 
1474 		p = call->buffer;
1475 		p[call->count] = 0;
1476 		_debug("volname '%s'", p);
1477 		afs_extract_to_tmp(call);
1478 		call->unmarshall++;
1479 		/* Fall through */
1480 
1481 		/* extract the offline message length */
1482 	case 4:
1483 		ret = afs_extract_data(call, true);
1484 		if (ret < 0)
1485 			return ret;
1486 
1487 		call->count = ntohl(call->tmp);
1488 		_debug("offline msg length: %u", call->count);
1489 		if (call->count >= AFSNAMEMAX)
1490 			return afs_protocol_error(call, -EBADMSG,
1491 						  afs_eproto_offline_msg_len);
1492 		size = (call->count + 3) & ~3; /* It's padded */
1493 		afs_extract_to_buf(call, size);
1494 		call->unmarshall++;
1495 		/* Fall through */
1496 
1497 		/* extract the offline message */
1498 	case 5:
1499 		_debug("extract offline");
1500 		ret = afs_extract_data(call, true);
1501 		if (ret < 0)
1502 			return ret;
1503 
1504 		p = call->buffer;
1505 		p[call->count] = 0;
1506 		_debug("offline '%s'", p);
1507 
1508 		afs_extract_to_tmp(call);
1509 		call->unmarshall++;
1510 		/* Fall through */
1511 
1512 		/* extract the message of the day length */
1513 	case 6:
1514 		ret = afs_extract_data(call, true);
1515 		if (ret < 0)
1516 			return ret;
1517 
1518 		call->count = ntohl(call->tmp);
1519 		_debug("motd length: %u", call->count);
1520 		if (call->count >= AFSNAMEMAX)
1521 			return afs_protocol_error(call, -EBADMSG,
1522 						  afs_eproto_motd_len);
1523 		size = (call->count + 3) & ~3; /* It's padded */
1524 		afs_extract_to_buf(call, size);
1525 		call->unmarshall++;
1526 		/* Fall through */
1527 
1528 		/* extract the message of the day */
1529 	case 7:
1530 		_debug("extract motd");
1531 		ret = afs_extract_data(call, false);
1532 		if (ret < 0)
1533 			return ret;
1534 
1535 		p = call->buffer;
1536 		p[call->count] = 0;
1537 		_debug("motd '%s'", p);
1538 
1539 		call->unmarshall++;
1540 		/* Fall through */
1541 
1542 	case 8:
1543 		break;
1544 	}
1545 
1546 	_leave(" = 0 [done]");
1547 	return 0;
1548 }
1549 
1550 /*
1551  * YFS.GetVolumeStatus operation type
1552  */
1553 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1554 	.name		= "YFS.GetVolumeStatus",
1555 	.op		= yfs_FS_GetVolumeStatus,
1556 	.deliver	= yfs_deliver_fs_get_volume_status,
1557 	.destructor	= afs_flat_call_destructor,
1558 };
1559 
1560 /*
1561  * fetch the status of a volume
1562  */
1563 int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1564 			     struct afs_volume_status *vs)
1565 {
1566 	struct afs_vnode *vnode = fc->vnode;
1567 	struct afs_call *call;
1568 	struct afs_net *net = afs_v2net(vnode);
1569 	__be32 *bp;
1570 
1571 	_enter("");
1572 
1573 	call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1574 				   sizeof(__be32) * 2 +
1575 				   sizeof(struct yfs_xdr_u64),
1576 				   max_t(size_t,
1577 					 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1578 					 sizeof(__be32),
1579 					 AFSOPAQUEMAX + 1));
1580 	if (!call)
1581 		return -ENOMEM;
1582 
1583 	call->key = fc->key;
1584 	call->out_volstatus = vs;
1585 
1586 	/* marshall the parameters */
1587 	bp = call->request;
1588 	bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1589 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1590 	bp = xdr_encode_u64(bp, vnode->fid.vid);
1591 	yfs_check_req(call, bp);
1592 
1593 	afs_use_fs_server(call, fc->cbi);
1594 	trace_afs_make_fs_call(call, &vnode->fid);
1595 	afs_set_fc_call(call, fc);
1596 	afs_make_call(&fc->ac, call, GFP_NOFS);
1597 	return afs_wait_for_call_to_complete(call, &fc->ac);
1598 }
1599 
1600 /*
1601  * YFS.SetLock operation type
1602  */
1603 static const struct afs_call_type yfs_RXYFSSetLock = {
1604 	.name		= "YFS.SetLock",
1605 	.op		= yfs_FS_SetLock,
1606 	.deliver	= yfs_deliver_status_and_volsync,
1607 	.done		= afs_lock_op_done,
1608 	.destructor	= afs_flat_call_destructor,
1609 };
1610 
1611 /*
1612  * YFS.ExtendLock operation type
1613  */
1614 static const struct afs_call_type yfs_RXYFSExtendLock = {
1615 	.name		= "YFS.ExtendLock",
1616 	.op		= yfs_FS_ExtendLock,
1617 	.deliver	= yfs_deliver_status_and_volsync,
1618 	.done		= afs_lock_op_done,
1619 	.destructor	= afs_flat_call_destructor,
1620 };
1621 
1622 /*
1623  * YFS.ReleaseLock operation type
1624  */
1625 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1626 	.name		= "YFS.ReleaseLock",
1627 	.op		= yfs_FS_ReleaseLock,
1628 	.deliver	= yfs_deliver_status_and_volsync,
1629 	.destructor	= afs_flat_call_destructor,
1630 };
1631 
1632 /*
1633  * Set a lock on a file
1634  */
1635 int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,
1636 		    struct afs_status_cb *scb)
1637 {
1638 	struct afs_vnode *vnode = fc->vnode;
1639 	struct afs_call *call;
1640 	struct afs_net *net = afs_v2net(vnode);
1641 	__be32 *bp;
1642 
1643 	_enter("");
1644 
1645 	call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1646 				   sizeof(__be32) * 2 +
1647 				   sizeof(struct yfs_xdr_YFSFid) +
1648 				   sizeof(__be32),
1649 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1650 				   sizeof(struct yfs_xdr_YFSVolSync));
1651 	if (!call)
1652 		return -ENOMEM;
1653 
1654 	call->key = fc->key;
1655 	call->lvnode = vnode;
1656 	call->out_scb = scb;
1657 
1658 	/* marshall the parameters */
1659 	bp = call->request;
1660 	bp = xdr_encode_u32(bp, YFSSETLOCK);
1661 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1662 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1663 	bp = xdr_encode_u32(bp, type);
1664 	yfs_check_req(call, bp);
1665 
1666 	afs_use_fs_server(call, fc->cbi);
1667 	trace_afs_make_fs_calli(call, &vnode->fid, type);
1668 	afs_set_fc_call(call, fc);
1669 	afs_make_call(&fc->ac, call, GFP_NOFS);
1670 	return afs_wait_for_call_to_complete(call, &fc->ac);
1671 }
1672 
1673 /*
1674  * extend a lock on a file
1675  */
1676 int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1677 {
1678 	struct afs_vnode *vnode = fc->vnode;
1679 	struct afs_call *call;
1680 	struct afs_net *net = afs_v2net(vnode);
1681 	__be32 *bp;
1682 
1683 	_enter("");
1684 
1685 	call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1686 				   sizeof(__be32) * 2 +
1687 				   sizeof(struct yfs_xdr_YFSFid),
1688 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1689 				   sizeof(struct yfs_xdr_YFSVolSync));
1690 	if (!call)
1691 		return -ENOMEM;
1692 
1693 	call->key = fc->key;
1694 	call->lvnode = vnode;
1695 	call->out_scb = scb;
1696 
1697 	/* marshall the parameters */
1698 	bp = call->request;
1699 	bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1700 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1701 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1702 	yfs_check_req(call, bp);
1703 
1704 	afs_use_fs_server(call, fc->cbi);
1705 	trace_afs_make_fs_call(call, &vnode->fid);
1706 	afs_set_fc_call(call, fc);
1707 	afs_make_call(&fc->ac, call, GFP_NOFS);
1708 	return afs_wait_for_call_to_complete(call, &fc->ac);
1709 }
1710 
1711 /*
1712  * release a lock on a file
1713  */
1714 int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1715 {
1716 	struct afs_vnode *vnode = fc->vnode;
1717 	struct afs_call *call;
1718 	struct afs_net *net = afs_v2net(vnode);
1719 	__be32 *bp;
1720 
1721 	_enter("");
1722 
1723 	call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1724 				   sizeof(__be32) * 2 +
1725 				   sizeof(struct yfs_xdr_YFSFid),
1726 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1727 				   sizeof(struct yfs_xdr_YFSVolSync));
1728 	if (!call)
1729 		return -ENOMEM;
1730 
1731 	call->key = fc->key;
1732 	call->lvnode = vnode;
1733 	call->out_scb = scb;
1734 
1735 	/* marshall the parameters */
1736 	bp = call->request;
1737 	bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1738 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1739 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
1740 	yfs_check_req(call, bp);
1741 
1742 	afs_use_fs_server(call, fc->cbi);
1743 	trace_afs_make_fs_call(call, &vnode->fid);
1744 	afs_set_fc_call(call, fc);
1745 	afs_make_call(&fc->ac, call, GFP_NOFS);
1746 	return afs_wait_for_call_to_complete(call, &fc->ac);
1747 }
1748 
1749 /*
1750  * YFS.FetchStatus operation type
1751  */
1752 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1753 	.name		= "YFS.FetchStatus",
1754 	.op		= yfs_FS_FetchStatus,
1755 	.deliver	= yfs_deliver_fs_status_cb_and_volsync,
1756 	.destructor	= afs_flat_call_destructor,
1757 };
1758 
1759 /*
1760  * Fetch the status information for a fid without needing a vnode handle.
1761  */
1762 int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1763 			struct afs_net *net,
1764 			struct afs_fid *fid,
1765 			struct afs_status_cb *scb,
1766 			struct afs_volsync *volsync)
1767 {
1768 	struct afs_call *call;
1769 	__be32 *bp;
1770 
1771 	_enter(",%x,{%llx:%llu},,",
1772 	       key_serial(fc->key), fid->vid, fid->vnode);
1773 
1774 	call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1775 				   sizeof(__be32) * 2 +
1776 				   sizeof(struct yfs_xdr_YFSFid),
1777 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1778 				   sizeof(struct yfs_xdr_YFSCallBack) +
1779 				   sizeof(struct yfs_xdr_YFSVolSync));
1780 	if (!call) {
1781 		fc->ac.error = -ENOMEM;
1782 		return -ENOMEM;
1783 	}
1784 
1785 	call->key = fc->key;
1786 	call->out_scb = scb;
1787 	call->out_volsync = volsync;
1788 
1789 	/* marshall the parameters */
1790 	bp = call->request;
1791 	bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1792 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1793 	bp = xdr_encode_YFSFid(bp, fid);
1794 	yfs_check_req(call, bp);
1795 
1796 	afs_use_fs_server(call, fc->cbi);
1797 	trace_afs_make_fs_call(call, fid);
1798 	afs_set_fc_call(call, fc);
1799 	afs_make_call(&fc->ac, call, GFP_NOFS);
1800 	return afs_wait_for_call_to_complete(call, &fc->ac);
1801 }
1802 
1803 /*
1804  * Deliver reply data to an YFS.InlineBulkStatus call
1805  */
1806 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1807 {
1808 	struct afs_status_cb *scb;
1809 	const __be32 *bp;
1810 	u32 tmp;
1811 	int ret;
1812 
1813 	_enter("{%u}", call->unmarshall);
1814 
1815 	switch (call->unmarshall) {
1816 	case 0:
1817 		afs_extract_to_tmp(call);
1818 		call->unmarshall++;
1819 		/* Fall through */
1820 
1821 		/* Extract the file status count and array in two steps */
1822 	case 1:
1823 		_debug("extract status count");
1824 		ret = afs_extract_data(call, true);
1825 		if (ret < 0)
1826 			return ret;
1827 
1828 		tmp = ntohl(call->tmp);
1829 		_debug("status count: %u/%u", tmp, call->count2);
1830 		if (tmp != call->count2)
1831 			return afs_protocol_error(call, -EBADMSG,
1832 						  afs_eproto_ibulkst_count);
1833 
1834 		call->count = 0;
1835 		call->unmarshall++;
1836 	more_counts:
1837 		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1838 		/* Fall through */
1839 
1840 	case 2:
1841 		_debug("extract status array %u", call->count);
1842 		ret = afs_extract_data(call, true);
1843 		if (ret < 0)
1844 			return ret;
1845 
1846 		bp = call->buffer;
1847 		scb = &call->out_scb[call->count];
1848 		ret = xdr_decode_YFSFetchStatus(&bp, call, scb);
1849 		if (ret < 0)
1850 			return ret;
1851 
1852 		call->count++;
1853 		if (call->count < call->count2)
1854 			goto more_counts;
1855 
1856 		call->count = 0;
1857 		call->unmarshall++;
1858 		afs_extract_to_tmp(call);
1859 		/* Fall through */
1860 
1861 		/* Extract the callback count and array in two steps */
1862 	case 3:
1863 		_debug("extract CB count");
1864 		ret = afs_extract_data(call, true);
1865 		if (ret < 0)
1866 			return ret;
1867 
1868 		tmp = ntohl(call->tmp);
1869 		_debug("CB count: %u", tmp);
1870 		if (tmp != call->count2)
1871 			return afs_protocol_error(call, -EBADMSG,
1872 						  afs_eproto_ibulkst_cb_count);
1873 		call->count = 0;
1874 		call->unmarshall++;
1875 	more_cbs:
1876 		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1877 		/* Fall through */
1878 
1879 	case 4:
1880 		_debug("extract CB array");
1881 		ret = afs_extract_data(call, true);
1882 		if (ret < 0)
1883 			return ret;
1884 
1885 		_debug("unmarshall CB array");
1886 		bp = call->buffer;
1887 		scb = &call->out_scb[call->count];
1888 		xdr_decode_YFSCallBack(&bp, call, scb);
1889 		call->count++;
1890 		if (call->count < call->count2)
1891 			goto more_cbs;
1892 
1893 		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1894 		call->unmarshall++;
1895 		/* Fall through */
1896 
1897 	case 5:
1898 		ret = afs_extract_data(call, false);
1899 		if (ret < 0)
1900 			return ret;
1901 
1902 		bp = call->buffer;
1903 		xdr_decode_YFSVolSync(&bp, call->out_volsync);
1904 
1905 		call->unmarshall++;
1906 		/* Fall through */
1907 
1908 	case 6:
1909 		break;
1910 	}
1911 
1912 	_leave(" = 0 [done]");
1913 	return 0;
1914 }
1915 
1916 /*
1917  * FS.InlineBulkStatus operation type
1918  */
1919 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1920 	.name		= "YFS.InlineBulkStatus",
1921 	.op		= yfs_FS_InlineBulkStatus,
1922 	.deliver	= yfs_deliver_fs_inline_bulk_status,
1923 	.destructor	= afs_flat_call_destructor,
1924 };
1925 
1926 /*
1927  * Fetch the status information for up to 1024 files
1928  */
1929 int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
1930 			      struct afs_net *net,
1931 			      struct afs_fid *fids,
1932 			      struct afs_status_cb *statuses,
1933 			      unsigned int nr_fids,
1934 			      struct afs_volsync *volsync)
1935 {
1936 	struct afs_call *call;
1937 	__be32 *bp;
1938 	int i;
1939 
1940 	_enter(",%x,{%llx:%llu},%u",
1941 	       key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
1942 
1943 	call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
1944 				   sizeof(__be32) +
1945 				   sizeof(__be32) +
1946 				   sizeof(__be32) +
1947 				   sizeof(struct yfs_xdr_YFSFid) * nr_fids,
1948 				   sizeof(struct yfs_xdr_YFSFetchStatus));
1949 	if (!call) {
1950 		fc->ac.error = -ENOMEM;
1951 		return -ENOMEM;
1952 	}
1953 
1954 	call->key = fc->key;
1955 	call->out_scb = statuses;
1956 	call->out_volsync = volsync;
1957 	call->count2 = nr_fids;
1958 
1959 	/* marshall the parameters */
1960 	bp = call->request;
1961 	bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1962 	bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1963 	bp = xdr_encode_u32(bp, nr_fids);
1964 	for (i = 0; i < nr_fids; i++)
1965 		bp = xdr_encode_YFSFid(bp, &fids[i]);
1966 	yfs_check_req(call, bp);
1967 
1968 	afs_use_fs_server(call, fc->cbi);
1969 	trace_afs_make_fs_call(call, &fids[0]);
1970 	afs_set_fc_call(call, fc);
1971 	afs_make_call(&fc->ac, call, GFP_NOFS);
1972 	return afs_wait_for_call_to_complete(call, &fc->ac);
1973 }
1974 
1975 /*
1976  * Deliver reply data to an YFS.FetchOpaqueACL.
1977  */
1978 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1979 {
1980 	struct yfs_acl *yacl = call->out_yacl;
1981 	struct afs_acl *acl;
1982 	const __be32 *bp;
1983 	unsigned int size;
1984 	int ret;
1985 
1986 	_enter("{%u}", call->unmarshall);
1987 
1988 	switch (call->unmarshall) {
1989 	case 0:
1990 		afs_extract_to_tmp(call);
1991 		call->unmarshall++;
1992 		/* Fall through */
1993 
1994 		/* Extract the file ACL length */
1995 	case 1:
1996 		ret = afs_extract_data(call, true);
1997 		if (ret < 0)
1998 			return ret;
1999 
2000 		size = call->count2 = ntohl(call->tmp);
2001 		size = round_up(size, 4);
2002 
2003 		if (yacl->flags & YFS_ACL_WANT_ACL) {
2004 			acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2005 			if (!acl)
2006 				return -ENOMEM;
2007 			yacl->acl = acl;
2008 			acl->size = call->count2;
2009 			afs_extract_begin(call, acl->data, size);
2010 		} else {
2011 			afs_extract_discard(call, size);
2012 		}
2013 		call->unmarshall++;
2014 		/* Fall through */
2015 
2016 		/* Extract the file ACL */
2017 	case 2:
2018 		ret = afs_extract_data(call, true);
2019 		if (ret < 0)
2020 			return ret;
2021 
2022 		afs_extract_to_tmp(call);
2023 		call->unmarshall++;
2024 		/* Fall through */
2025 
2026 		/* Extract the volume ACL length */
2027 	case 3:
2028 		ret = afs_extract_data(call, true);
2029 		if (ret < 0)
2030 			return ret;
2031 
2032 		size = call->count2 = ntohl(call->tmp);
2033 		size = round_up(size, 4);
2034 
2035 		if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2036 			acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2037 			if (!acl)
2038 				return -ENOMEM;
2039 			yacl->vol_acl = acl;
2040 			acl->size = call->count2;
2041 			afs_extract_begin(call, acl->data, size);
2042 		} else {
2043 			afs_extract_discard(call, size);
2044 		}
2045 		call->unmarshall++;
2046 		/* Fall through */
2047 
2048 		/* Extract the volume ACL */
2049 	case 4:
2050 		ret = afs_extract_data(call, true);
2051 		if (ret < 0)
2052 			return ret;
2053 
2054 		afs_extract_to_buf(call,
2055 				   sizeof(__be32) * 2 +
2056 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2057 				   sizeof(struct yfs_xdr_YFSVolSync));
2058 		call->unmarshall++;
2059 		/* Fall through */
2060 
2061 		/* extract the metadata */
2062 	case 5:
2063 		ret = afs_extract_data(call, false);
2064 		if (ret < 0)
2065 			return ret;
2066 
2067 		bp = call->buffer;
2068 		yacl->inherit_flag = ntohl(*bp++);
2069 		yacl->num_cleaned = ntohl(*bp++);
2070 		ret = xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
2071 		if (ret < 0)
2072 			return ret;
2073 		xdr_decode_YFSVolSync(&bp, call->out_volsync);
2074 
2075 		call->unmarshall++;
2076 		/* Fall through */
2077 
2078 	case 6:
2079 		break;
2080 	}
2081 
2082 	_leave(" = 0 [done]");
2083 	return 0;
2084 }
2085 
2086 void yfs_free_opaque_acl(struct yfs_acl *yacl)
2087 {
2088 	if (yacl) {
2089 		kfree(yacl->acl);
2090 		kfree(yacl->vol_acl);
2091 		kfree(yacl);
2092 	}
2093 }
2094 
2095 /*
2096  * YFS.FetchOpaqueACL operation type
2097  */
2098 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2099 	.name		= "YFS.FetchOpaqueACL",
2100 	.op		= yfs_FS_FetchOpaqueACL,
2101 	.deliver	= yfs_deliver_fs_fetch_opaque_acl,
2102 	.destructor	= afs_flat_call_destructor,
2103 };
2104 
2105 /*
2106  * Fetch the YFS advanced ACLs for a file.
2107  */
2108 struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
2109 					struct yfs_acl *yacl,
2110 					struct afs_status_cb *scb)
2111 {
2112 	struct afs_vnode *vnode = fc->vnode;
2113 	struct afs_call *call;
2114 	struct afs_net *net = afs_v2net(vnode);
2115 	__be32 *bp;
2116 
2117 	_enter(",%x,{%llx:%llu},,",
2118 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2119 
2120 	call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,
2121 				   sizeof(__be32) * 2 +
2122 				   sizeof(struct yfs_xdr_YFSFid),
2123 				   sizeof(__be32) * 2 +
2124 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2125 				   sizeof(struct yfs_xdr_YFSVolSync));
2126 	if (!call) {
2127 		fc->ac.error = -ENOMEM;
2128 		return ERR_PTR(-ENOMEM);
2129 	}
2130 
2131 	call->key = fc->key;
2132 	call->out_yacl = yacl;
2133 	call->out_scb = scb;
2134 	call->out_volsync = NULL;
2135 
2136 	/* marshall the parameters */
2137 	bp = call->request;
2138 	bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2139 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
2140 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
2141 	yfs_check_req(call, bp);
2142 
2143 	afs_use_fs_server(call, fc->cbi);
2144 	trace_afs_make_fs_call(call, &vnode->fid);
2145 	afs_make_call(&fc->ac, call, GFP_KERNEL);
2146 	return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2147 }
2148 
2149 /*
2150  * YFS.StoreOpaqueACL2 operation type
2151  */
2152 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2153 	.name		= "YFS.StoreOpaqueACL2",
2154 	.op		= yfs_FS_StoreOpaqueACL2,
2155 	.deliver	= yfs_deliver_status_and_volsync,
2156 	.destructor	= afs_flat_call_destructor,
2157 };
2158 
2159 /*
2160  * Fetch the YFS ACL for a file.
2161  */
2162 int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl,
2163 			     struct afs_status_cb *scb)
2164 {
2165 	struct afs_vnode *vnode = fc->vnode;
2166 	struct afs_call *call;
2167 	struct afs_net *net = afs_v2net(vnode);
2168 	size_t size;
2169 	__be32 *bp;
2170 
2171 	_enter(",%x,{%llx:%llu},,",
2172 	       key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2173 
2174 	size = round_up(acl->size, 4);
2175 	call = afs_alloc_flat_call(net, &yfs_RXYFSStoreOpaqueACL2,
2176 				   sizeof(__be32) * 2 +
2177 				   sizeof(struct yfs_xdr_YFSFid) +
2178 				   sizeof(__be32) + size,
2179 				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2180 				   sizeof(struct yfs_xdr_YFSVolSync));
2181 	if (!call) {
2182 		fc->ac.error = -ENOMEM;
2183 		return -ENOMEM;
2184 	}
2185 
2186 	call->key = fc->key;
2187 	call->out_scb = scb;
2188 	call->out_volsync = NULL;
2189 
2190 	/* marshall the parameters */
2191 	bp = call->request;
2192 	bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2193 	bp = xdr_encode_u32(bp, 0); /* RPC flags */
2194 	bp = xdr_encode_YFSFid(bp, &vnode->fid);
2195 	bp = xdr_encode_u32(bp, acl->size);
2196 	memcpy(bp, acl->data, acl->size);
2197 	if (acl->size != size)
2198 		memset((void *)bp + acl->size, 0, size - acl->size);
2199 	yfs_check_req(call, bp);
2200 
2201 	trace_afs_make_fs_call(call, &vnode->fid);
2202 	afs_make_call(&fc->ac, call, GFP_KERNEL);
2203 	return afs_wait_for_call_to_complete(call, &fc->ac);
2204 }
2205