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