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