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