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