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