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