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