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