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