1/* AFS File Server client stubs
2 *
3 * Copyright (C) 2002, 2007 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 License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/sched.h>
14#include <linux/circ_buf.h>
15#include "internal.h"
16#include "afs_fs.h"
17
18/*
19 * decode an AFSFid block
20 */
21static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
22{
23	const __be32 *bp = *_bp;
24
25	fid->vid		= ntohl(*bp++);
26	fid->vnode		= ntohl(*bp++);
27	fid->unique		= ntohl(*bp++);
28	*_bp = bp;
29}
30
31/*
32 * decode an AFSFetchStatus block
33 */
34static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
35				      struct afs_file_status *status,
36				      struct afs_vnode *vnode,
37				      afs_dataversion_t *store_version)
38{
39	afs_dataversion_t expected_version;
40	const __be32 *bp = *_bp;
41	umode_t mode;
42	u64 data_version, size;
43	u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
44
45#define EXTRACT(DST)				\
46	do {					\
47		u32 x = ntohl(*bp++);		\
48		changed |= DST - x;		\
49		DST = x;			\
50	} while (0)
51
52	status->if_version = ntohl(*bp++);
53	EXTRACT(status->type);
54	EXTRACT(status->nlink);
55	size = ntohl(*bp++);
56	data_version = ntohl(*bp++);
57	EXTRACT(status->author);
58	EXTRACT(status->owner);
59	EXTRACT(status->caller_access); /* call ticket dependent */
60	EXTRACT(status->anon_access);
61	EXTRACT(status->mode);
62	EXTRACT(status->parent.vnode);
63	EXTRACT(status->parent.unique);
64	bp++; /* seg size */
65	status->mtime_client = ntohl(*bp++);
66	status->mtime_server = ntohl(*bp++);
67	EXTRACT(status->group);
68	bp++; /* sync counter */
69	data_version |= (u64) ntohl(*bp++) << 32;
70	bp++; /* lock count */
71	size |= (u64) ntohl(*bp++) << 32;
72	bp++; /* spare 4 */
73	*_bp = bp;
74
75	if (size != status->size) {
76		status->size = size;
77		changed |= true;
78	}
79	status->mode &= S_IALLUGO;
80
81	_debug("vnode time %lx, %lx",
82	       status->mtime_client, status->mtime_server);
83
84	if (vnode) {
85		status->parent.vid = vnode->fid.vid;
86		if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
87			_debug("vnode changed");
88			i_size_write(&vnode->vfs_inode, size);
89			vnode->vfs_inode.i_uid = status->owner;
90			vnode->vfs_inode.i_gid = status->group;
91			vnode->vfs_inode.i_version = vnode->fid.unique;
92			vnode->vfs_inode.i_nlink = status->nlink;
93
94			mode = vnode->vfs_inode.i_mode;
95			mode &= ~S_IALLUGO;
96			mode |= status->mode;
97			barrier();
98			vnode->vfs_inode.i_mode = mode;
99		}
100
101		vnode->vfs_inode.i_ctime.tv_sec	= status->mtime_server;
102		vnode->vfs_inode.i_mtime	= vnode->vfs_inode.i_ctime;
103		vnode->vfs_inode.i_atime	= vnode->vfs_inode.i_ctime;
104	}
105
106	expected_version = status->data_version;
107	if (store_version)
108		expected_version = *store_version;
109
110	if (expected_version != data_version) {
111		status->data_version = data_version;
112		if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
113			_debug("vnode modified %llx on {%x:%u}",
114			       (unsigned long long) data_version,
115			       vnode->fid.vid, vnode->fid.vnode);
116			set_bit(AFS_VNODE_MODIFIED, &vnode->flags);
117			set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
118		}
119	} else if (store_version) {
120		status->data_version = data_version;
121	}
122}
123
124/*
125 * decode an AFSCallBack block
126 */
127static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode)
128{
129	const __be32 *bp = *_bp;
130
131	vnode->cb_version	= ntohl(*bp++);
132	vnode->cb_expiry	= ntohl(*bp++);
133	vnode->cb_type		= ntohl(*bp++);
134	vnode->cb_expires	= vnode->cb_expiry + get_seconds();
135	*_bp = bp;
136}
137
138static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
139				       struct afs_callback *cb)
140{
141	const __be32 *bp = *_bp;
142
143	cb->version	= ntohl(*bp++);
144	cb->expiry	= ntohl(*bp++);
145	cb->type	= ntohl(*bp++);
146	*_bp = bp;
147}
148
149/*
150 * decode an AFSVolSync block
151 */
152static void xdr_decode_AFSVolSync(const __be32 **_bp,
153				  struct afs_volsync *volsync)
154{
155	const __be32 *bp = *_bp;
156
157	volsync->creation = ntohl(*bp++);
158	bp++; /* spare2 */
159	bp++; /* spare3 */
160	bp++; /* spare4 */
161	bp++; /* spare5 */
162	bp++; /* spare6 */
163	*_bp = bp;
164}
165
166/*
167 * encode the requested attributes into an AFSStoreStatus block
168 */
169static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
170{
171	__be32 *bp = *_bp;
172	u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
173
174	mask = 0;
175	if (attr->ia_valid & ATTR_MTIME) {
176		mask |= AFS_SET_MTIME;
177		mtime = attr->ia_mtime.tv_sec;
178	}
179
180	if (attr->ia_valid & ATTR_UID) {
181		mask |= AFS_SET_OWNER;
182		owner = attr->ia_uid;
183	}
184
185	if (attr->ia_valid & ATTR_GID) {
186		mask |= AFS_SET_GROUP;
187		group = attr->ia_gid;
188	}
189
190	if (attr->ia_valid & ATTR_MODE) {
191		mask |= AFS_SET_MODE;
192		mode = attr->ia_mode & S_IALLUGO;
193	}
194
195	*bp++ = htonl(mask);
196	*bp++ = htonl(mtime);
197	*bp++ = htonl(owner);
198	*bp++ = htonl(group);
199	*bp++ = htonl(mode);
200	*bp++ = 0;		/* segment size */
201	*_bp = bp;
202}
203
204/*
205 * decode an AFSFetchVolumeStatus block
206 */
207static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
208					    struct afs_volume_status *vs)
209{
210	const __be32 *bp = *_bp;
211
212	vs->vid			= ntohl(*bp++);
213	vs->parent_id		= ntohl(*bp++);
214	vs->online		= ntohl(*bp++);
215	vs->in_service		= ntohl(*bp++);
216	vs->blessed		= ntohl(*bp++);
217	vs->needs_salvage	= ntohl(*bp++);
218	vs->type		= ntohl(*bp++);
219	vs->min_quota		= ntohl(*bp++);
220	vs->max_quota		= ntohl(*bp++);
221	vs->blocks_in_use	= ntohl(*bp++);
222	vs->part_blocks_avail	= ntohl(*bp++);
223	vs->part_max_blocks	= ntohl(*bp++);
224	*_bp = bp;
225}
226
227/*
228 * deliver reply data to an FS.FetchStatus
229 */
230static int afs_deliver_fs_fetch_status(struct afs_call *call,
231				       struct sk_buff *skb, bool last)
232{
233	struct afs_vnode *vnode = call->reply;
234	const __be32 *bp;
235
236	_enter(",,%u", last);
237
238	afs_transfer_reply(call, skb);
239	if (!last)
240		return 0;
241
242	if (call->reply_size != call->reply_max)
243		return -EBADMSG;
244
245	/* unmarshall the reply once we've received all of it */
246	bp = call->buffer;
247	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
248	xdr_decode_AFSCallBack(&bp, vnode);
249	if (call->reply2)
250		xdr_decode_AFSVolSync(&bp, call->reply2);
251
252	_leave(" = 0 [done]");
253	return 0;
254}
255
256/*
257 * FS.FetchStatus operation type
258 */
259static const struct afs_call_type afs_RXFSFetchStatus = {
260	.name		= "FS.FetchStatus",
261	.deliver	= afs_deliver_fs_fetch_status,
262	.abort_to_error	= afs_abort_to_error,
263	.destructor	= afs_flat_call_destructor,
264};
265
266/*
267 * fetch the status information for a file
268 */
269int afs_fs_fetch_file_status(struct afs_server *server,
270			     struct key *key,
271			     struct afs_vnode *vnode,
272			     struct afs_volsync *volsync,
273			     const struct afs_wait_mode *wait_mode)
274{
275	struct afs_call *call;
276	__be32 *bp;
277
278	_enter(",%x,{%x:%u},,",
279	       key_serial(key), vnode->fid.vid, vnode->fid.vnode);
280
281	call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
282	if (!call)
283		return -ENOMEM;
284
285	call->key = key;
286	call->reply = vnode;
287	call->reply2 = volsync;
288	call->service_id = FS_SERVICE;
289	call->port = htons(AFS_FS_PORT);
290
291	/* marshall the parameters */
292	bp = call->request;
293	bp[0] = htonl(FSFETCHSTATUS);
294	bp[1] = htonl(vnode->fid.vid);
295	bp[2] = htonl(vnode->fid.vnode);
296	bp[3] = htonl(vnode->fid.unique);
297
298	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
299}
300
301/*
302 * deliver reply data to an FS.FetchData
303 */
304static int afs_deliver_fs_fetch_data(struct afs_call *call,
305				     struct sk_buff *skb, bool last)
306{
307	struct afs_vnode *vnode = call->reply;
308	const __be32 *bp;
309	struct page *page;
310	void *buffer;
311	int ret;
312
313	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
314
315	switch (call->unmarshall) {
316	case 0:
317		call->offset = 0;
318		call->unmarshall++;
319		if (call->operation_ID != FSFETCHDATA64) {
320			call->unmarshall++;
321			goto no_msw;
322		}
323
324		/* extract the upper part of the returned data length of an
325		 * FSFETCHDATA64 op (which should always be 0 using this
326		 * client) */
327	case 1:
328		_debug("extract data length (MSW)");
329		ret = afs_extract_data(call, skb, last, &call->tmp, 4);
330		switch (ret) {
331		case 0:		break;
332		case -EAGAIN:	return 0;
333		default:	return ret;
334		}
335
336		call->count = ntohl(call->tmp);
337		_debug("DATA length MSW: %u", call->count);
338		if (call->count > 0)
339			return -EBADMSG;
340		call->offset = 0;
341		call->unmarshall++;
342
343	no_msw:
344		/* extract the returned data length */
345	case 2:
346		_debug("extract data length");
347		ret = afs_extract_data(call, skb, last, &call->tmp, 4);
348		switch (ret) {
349		case 0:		break;
350		case -EAGAIN:	return 0;
351		default:	return ret;
352		}
353
354		call->count = ntohl(call->tmp);
355		_debug("DATA length: %u", call->count);
356		if (call->count > PAGE_SIZE)
357			return -EBADMSG;
358		call->offset = 0;
359		call->unmarshall++;
360
361		/* extract the returned data */
362	case 3:
363		_debug("extract data");
364		if (call->count > 0) {
365			page = call->reply3;
366			buffer = kmap_atomic(page, KM_USER0);
367			ret = afs_extract_data(call, skb, last, buffer,
368					       call->count);
369			kunmap_atomic(buffer, KM_USER0);
370			switch (ret) {
371			case 0:		break;
372			case -EAGAIN:	return 0;
373			default:	return ret;
374			}
375		}
376
377		call->offset = 0;
378		call->unmarshall++;
379
380		/* extract the metadata */
381	case 4:
382		ret = afs_extract_data(call, skb, last, call->buffer,
383				       (21 + 3 + 6) * 4);
384		switch (ret) {
385		case 0:		break;
386		case -EAGAIN:	return 0;
387		default:	return ret;
388		}
389
390		bp = call->buffer;
391		xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
392		xdr_decode_AFSCallBack(&bp, vnode);
393		if (call->reply2)
394			xdr_decode_AFSVolSync(&bp, call->reply2);
395
396		call->offset = 0;
397		call->unmarshall++;
398
399	case 5:
400		_debug("trailer");
401		if (skb->len != 0)
402			return -EBADMSG;
403		break;
404	}
405
406	if (!last)
407		return 0;
408
409	if (call->count < PAGE_SIZE) {
410		_debug("clear");
411		page = call->reply3;
412		buffer = kmap_atomic(page, KM_USER0);
413		memset(buffer + call->count, 0, PAGE_SIZE - call->count);
414		kunmap_atomic(buffer, KM_USER0);
415	}
416
417	_leave(" = 0 [done]");
418	return 0;
419}
420
421/*
422 * FS.FetchData operation type
423 */
424static const struct afs_call_type afs_RXFSFetchData = {
425	.name		= "FS.FetchData",
426	.deliver	= afs_deliver_fs_fetch_data,
427	.abort_to_error	= afs_abort_to_error,
428	.destructor	= afs_flat_call_destructor,
429};
430
431static const struct afs_call_type afs_RXFSFetchData64 = {
432	.name		= "FS.FetchData64",
433	.deliver	= afs_deliver_fs_fetch_data,
434	.abort_to_error	= afs_abort_to_error,
435	.destructor	= afs_flat_call_destructor,
436};
437
438/*
439 * fetch data from a very large file
440 */
441static int afs_fs_fetch_data64(struct afs_server *server,
442			       struct key *key,
443			       struct afs_vnode *vnode,
444			       off_t offset, size_t length,
445			       struct page *buffer,
446			       const struct afs_wait_mode *wait_mode)
447{
448	struct afs_call *call;
449	__be32 *bp;
450
451	_enter("");
452
453	ASSERTCMP(length, <, ULONG_MAX);
454
455	call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
456	if (!call)
457		return -ENOMEM;
458
459	call->key = key;
460	call->reply = vnode;
461	call->reply2 = NULL; /* volsync */
462	call->reply3 = buffer;
463	call->service_id = FS_SERVICE;
464	call->port = htons(AFS_FS_PORT);
465	call->operation_ID = FSFETCHDATA64;
466
467	/* marshall the parameters */
468	bp = call->request;
469	bp[0] = htonl(FSFETCHDATA64);
470	bp[1] = htonl(vnode->fid.vid);
471	bp[2] = htonl(vnode->fid.vnode);
472	bp[3] = htonl(vnode->fid.unique);
473	bp[4] = htonl(upper_32_bits(offset));
474	bp[5] = htonl((u32) offset);
475	bp[6] = 0;
476	bp[7] = htonl((u32) length);
477
478	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
479}
480
481/*
482 * fetch data from a file
483 */
484int afs_fs_fetch_data(struct afs_server *server,
485		      struct key *key,
486		      struct afs_vnode *vnode,
487		      off_t offset, size_t length,
488		      struct page *buffer,
489		      const struct afs_wait_mode *wait_mode)
490{
491	struct afs_call *call;
492	__be32 *bp;
493
494	if (upper_32_bits(offset) || upper_32_bits(offset + length))
495		return afs_fs_fetch_data64(server, key, vnode, offset, length,
496					   buffer, wait_mode);
497
498	_enter("");
499
500	call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
501	if (!call)
502		return -ENOMEM;
503
504	call->key = key;
505	call->reply = vnode;
506	call->reply2 = NULL; /* volsync */
507	call->reply3 = buffer;
508	call->service_id = FS_SERVICE;
509	call->port = htons(AFS_FS_PORT);
510	call->operation_ID = FSFETCHDATA;
511
512	/* marshall the parameters */
513	bp = call->request;
514	bp[0] = htonl(FSFETCHDATA);
515	bp[1] = htonl(vnode->fid.vid);
516	bp[2] = htonl(vnode->fid.vnode);
517	bp[3] = htonl(vnode->fid.unique);
518	bp[4] = htonl(offset);
519	bp[5] = htonl(length);
520
521	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
522}
523
524/*
525 * deliver reply data to an FS.GiveUpCallBacks
526 */
527static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
528					    struct sk_buff *skb, bool last)
529{
530	_enter(",{%u},%d", skb->len, last);
531
532	if (skb->len > 0)
533		return -EBADMSG; /* shouldn't be any reply data */
534	return 0;
535}
536
537/*
538 * FS.GiveUpCallBacks operation type
539 */
540static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
541	.name		= "FS.GiveUpCallBacks",
542	.deliver	= afs_deliver_fs_give_up_callbacks,
543	.abort_to_error	= afs_abort_to_error,
544	.destructor	= afs_flat_call_destructor,
545};
546
547/*
548 * give up a set of callbacks
549 * - the callbacks are held in the server->cb_break ring
550 */
551int afs_fs_give_up_callbacks(struct afs_server *server,
552			     const struct afs_wait_mode *wait_mode)
553{
554	struct afs_call *call;
555	size_t ncallbacks;
556	__be32 *bp, *tp;
557	int loop;
558
559	ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
560			      ARRAY_SIZE(server->cb_break));
561
562	_enter("{%zu},", ncallbacks);
563
564	if (ncallbacks == 0)
565		return 0;
566	if (ncallbacks > AFSCBMAX)
567		ncallbacks = AFSCBMAX;
568
569	_debug("break %zu callbacks", ncallbacks);
570
571	call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
572				   12 + ncallbacks * 6 * 4, 0);
573	if (!call)
574		return -ENOMEM;
575
576	call->service_id = FS_SERVICE;
577	call->port = htons(AFS_FS_PORT);
578
579	/* marshall the parameters */
580	bp = call->request;
581	tp = bp + 2 + ncallbacks * 3;
582	*bp++ = htonl(FSGIVEUPCALLBACKS);
583	*bp++ = htonl(ncallbacks);
584	*tp++ = htonl(ncallbacks);
585
586	atomic_sub(ncallbacks, &server->cb_break_n);
587	for (loop = ncallbacks; loop > 0; loop--) {
588		struct afs_callback *cb =
589			&server->cb_break[server->cb_break_tail];
590
591		*bp++ = htonl(cb->fid.vid);
592		*bp++ = htonl(cb->fid.vnode);
593		*bp++ = htonl(cb->fid.unique);
594		*tp++ = htonl(cb->version);
595		*tp++ = htonl(cb->expiry);
596		*tp++ = htonl(cb->type);
597		smp_mb();
598		server->cb_break_tail =
599			(server->cb_break_tail + 1) &
600			(ARRAY_SIZE(server->cb_break) - 1);
601	}
602
603	ASSERT(ncallbacks > 0);
604	wake_up_nr(&server->cb_break_waitq, ncallbacks);
605
606	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
607}
608
609/*
610 * deliver reply data to an FS.CreateFile or an FS.MakeDir
611 */
612static int afs_deliver_fs_create_vnode(struct afs_call *call,
613				       struct sk_buff *skb, bool last)
614{
615	struct afs_vnode *vnode = call->reply;
616	const __be32 *bp;
617
618	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
619
620	afs_transfer_reply(call, skb);
621	if (!last)
622		return 0;
623
624	if (call->reply_size != call->reply_max)
625		return -EBADMSG;
626
627	/* unmarshall the reply once we've received all of it */
628	bp = call->buffer;
629	xdr_decode_AFSFid(&bp, call->reply2);
630	xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
631	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
632	xdr_decode_AFSCallBack_raw(&bp, call->reply4);
633	/* xdr_decode_AFSVolSync(&bp, call->replyX); */
634
635	_leave(" = 0 [done]");
636	return 0;
637}
638
639/*
640 * FS.CreateFile and FS.MakeDir operation type
641 */
642static const struct afs_call_type afs_RXFSCreateXXXX = {
643	.name		= "FS.CreateXXXX",
644	.deliver	= afs_deliver_fs_create_vnode,
645	.abort_to_error	= afs_abort_to_error,
646	.destructor	= afs_flat_call_destructor,
647};
648
649/*
650 * create a file or make a directory
651 */
652int afs_fs_create(struct afs_server *server,
653		  struct key *key,
654		  struct afs_vnode *vnode,
655		  const char *name,
656		  umode_t mode,
657		  struct afs_fid *newfid,
658		  struct afs_file_status *newstatus,
659		  struct afs_callback *newcb,
660		  const struct afs_wait_mode *wait_mode)
661{
662	struct afs_call *call;
663	size_t namesz, reqsz, padsz;
664	__be32 *bp;
665
666	_enter("");
667
668	namesz = strlen(name);
669	padsz = (4 - (namesz & 3)) & 3;
670	reqsz = (5 * 4) + namesz + padsz + (6 * 4);
671
672	call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
673				   (3 + 21 + 21 + 3 + 6) * 4);
674	if (!call)
675		return -ENOMEM;
676
677	call->key = key;
678	call->reply = vnode;
679	call->reply2 = newfid;
680	call->reply3 = newstatus;
681	call->reply4 = newcb;
682	call->service_id = FS_SERVICE;
683	call->port = htons(AFS_FS_PORT);
684
685	/* marshall the parameters */
686	bp = call->request;
687	*bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
688	*bp++ = htonl(vnode->fid.vid);
689	*bp++ = htonl(vnode->fid.vnode);
690	*bp++ = htonl(vnode->fid.unique);
691	*bp++ = htonl(namesz);
692	memcpy(bp, name, namesz);
693	bp = (void *) bp + namesz;
694	if (padsz > 0) {
695		memset(bp, 0, padsz);
696		bp = (void *) bp + padsz;
697	}
698	*bp++ = htonl(AFS_SET_MODE);
699	*bp++ = 0; /* mtime */
700	*bp++ = 0; /* owner */
701	*bp++ = 0; /* group */
702	*bp++ = htonl(mode & S_IALLUGO); /* unix mode */
703	*bp++ = 0; /* segment size */
704
705	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
706}
707
708/*
709 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
710 */
711static int afs_deliver_fs_remove(struct afs_call *call,
712				 struct sk_buff *skb, bool last)
713{
714	struct afs_vnode *vnode = call->reply;
715	const __be32 *bp;
716
717	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
718
719	afs_transfer_reply(call, skb);
720	if (!last)
721		return 0;
722
723	if (call->reply_size != call->reply_max)
724		return -EBADMSG;
725
726	/* unmarshall the reply once we've received all of it */
727	bp = call->buffer;
728	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
729	/* xdr_decode_AFSVolSync(&bp, call->replyX); */
730
731	_leave(" = 0 [done]");
732	return 0;
733}
734
735/*
736 * FS.RemoveDir/FS.RemoveFile operation type
737 */
738static const struct afs_call_type afs_RXFSRemoveXXXX = {
739	.name		= "FS.RemoveXXXX",
740	.deliver	= afs_deliver_fs_remove,
741	.abort_to_error	= afs_abort_to_error,
742	.destructor	= afs_flat_call_destructor,
743};
744
745/*
746 * remove a file or directory
747 */
748int afs_fs_remove(struct afs_server *server,
749		  struct key *key,
750		  struct afs_vnode *vnode,
751		  const char *name,
752		  bool isdir,
753		  const struct afs_wait_mode *wait_mode)
754{
755	struct afs_call *call;
756	size_t namesz, reqsz, padsz;
757	__be32 *bp;
758
759	_enter("");
760
761	namesz = strlen(name);
762	padsz = (4 - (namesz & 3)) & 3;
763	reqsz = (5 * 4) + namesz + padsz;
764
765	call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
766	if (!call)
767		return -ENOMEM;
768
769	call->key = key;
770	call->reply = vnode;
771	call->service_id = FS_SERVICE;
772	call->port = htons(AFS_FS_PORT);
773
774	/* marshall the parameters */
775	bp = call->request;
776	*bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
777	*bp++ = htonl(vnode->fid.vid);
778	*bp++ = htonl(vnode->fid.vnode);
779	*bp++ = htonl(vnode->fid.unique);
780	*bp++ = htonl(namesz);
781	memcpy(bp, name, namesz);
782	bp = (void *) bp + namesz;
783	if (padsz > 0) {
784		memset(bp, 0, padsz);
785		bp = (void *) bp + padsz;
786	}
787
788	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
789}
790
791/*
792 * deliver reply data to an FS.Link
793 */
794static int afs_deliver_fs_link(struct afs_call *call,
795			       struct sk_buff *skb, bool last)
796{
797	struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
798	const __be32 *bp;
799
800	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
801
802	afs_transfer_reply(call, skb);
803	if (!last)
804		return 0;
805
806	if (call->reply_size != call->reply_max)
807		return -EBADMSG;
808
809	/* unmarshall the reply once we've received all of it */
810	bp = call->buffer;
811	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
812	xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
813	/* xdr_decode_AFSVolSync(&bp, call->replyX); */
814
815	_leave(" = 0 [done]");
816	return 0;
817}
818
819/*
820 * FS.Link operation type
821 */
822static const struct afs_call_type afs_RXFSLink = {
823	.name		= "FS.Link",
824	.deliver	= afs_deliver_fs_link,
825	.abort_to_error	= afs_abort_to_error,
826	.destructor	= afs_flat_call_destructor,
827};
828
829/*
830 * make a hard link
831 */
832int afs_fs_link(struct afs_server *server,
833		struct key *key,
834		struct afs_vnode *dvnode,
835		struct afs_vnode *vnode,
836		const char *name,
837		const struct afs_wait_mode *wait_mode)
838{
839	struct afs_call *call;
840	size_t namesz, reqsz, padsz;
841	__be32 *bp;
842
843	_enter("");
844
845	namesz = strlen(name);
846	padsz = (4 - (namesz & 3)) & 3;
847	reqsz = (5 * 4) + namesz + padsz + (3 * 4);
848
849	call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
850	if (!call)
851		return -ENOMEM;
852
853	call->key = key;
854	call->reply = dvnode;
855	call->reply2 = vnode;
856	call->service_id = FS_SERVICE;
857	call->port = htons(AFS_FS_PORT);
858
859	/* marshall the parameters */
860	bp = call->request;
861	*bp++ = htonl(FSLINK);
862	*bp++ = htonl(dvnode->fid.vid);
863	*bp++ = htonl(dvnode->fid.vnode);
864	*bp++ = htonl(dvnode->fid.unique);
865	*bp++ = htonl(namesz);
866	memcpy(bp, name, namesz);
867	bp = (void *) bp + namesz;
868	if (padsz > 0) {
869		memset(bp, 0, padsz);
870		bp = (void *) bp + padsz;
871	}
872	*bp++ = htonl(vnode->fid.vid);
873	*bp++ = htonl(vnode->fid.vnode);
874	*bp++ = htonl(vnode->fid.unique);
875
876	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
877}
878
879/*
880 * deliver reply data to an FS.Symlink
881 */
882static int afs_deliver_fs_symlink(struct afs_call *call,
883				  struct sk_buff *skb, bool last)
884{
885	struct afs_vnode *vnode = call->reply;
886	const __be32 *bp;
887
888	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
889
890	afs_transfer_reply(call, skb);
891	if (!last)
892		return 0;
893
894	if (call->reply_size != call->reply_max)
895		return -EBADMSG;
896
897	/* unmarshall the reply once we've received all of it */
898	bp = call->buffer;
899	xdr_decode_AFSFid(&bp, call->reply2);
900	xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
901	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
902	/* xdr_decode_AFSVolSync(&bp, call->replyX); */
903
904	_leave(" = 0 [done]");
905	return 0;
906}
907
908/*
909 * FS.Symlink operation type
910 */
911static const struct afs_call_type afs_RXFSSymlink = {
912	.name		= "FS.Symlink",
913	.deliver	= afs_deliver_fs_symlink,
914	.abort_to_error	= afs_abort_to_error,
915	.destructor	= afs_flat_call_destructor,
916};
917
918/*
919 * create a symbolic link
920 */
921int afs_fs_symlink(struct afs_server *server,
922		   struct key *key,
923		   struct afs_vnode *vnode,
924		   const char *name,
925		   const char *contents,
926		   struct afs_fid *newfid,
927		   struct afs_file_status *newstatus,
928		   const struct afs_wait_mode *wait_mode)
929{
930	struct afs_call *call;
931	size_t namesz, reqsz, padsz, c_namesz, c_padsz;
932	__be32 *bp;
933
934	_enter("");
935
936	namesz = strlen(name);
937	padsz = (4 - (namesz & 3)) & 3;
938
939	c_namesz = strlen(contents);
940	c_padsz = (4 - (c_namesz & 3)) & 3;
941
942	reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
943
944	call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
945				   (3 + 21 + 21 + 6) * 4);
946	if (!call)
947		return -ENOMEM;
948
949	call->key = key;
950	call->reply = vnode;
951	call->reply2 = newfid;
952	call->reply3 = newstatus;
953	call->service_id = FS_SERVICE;
954	call->port = htons(AFS_FS_PORT);
955
956	/* marshall the parameters */
957	bp = call->request;
958	*bp++ = htonl(FSSYMLINK);
959	*bp++ = htonl(vnode->fid.vid);
960	*bp++ = htonl(vnode->fid.vnode);
961	*bp++ = htonl(vnode->fid.unique);
962	*bp++ = htonl(namesz);
963	memcpy(bp, name, namesz);
964	bp = (void *) bp + namesz;
965	if (padsz > 0) {
966		memset(bp, 0, padsz);
967		bp = (void *) bp + padsz;
968	}
969	*bp++ = htonl(c_namesz);
970	memcpy(bp, contents, c_namesz);
971	bp = (void *) bp + c_namesz;
972	if (c_padsz > 0) {
973		memset(bp, 0, c_padsz);
974		bp = (void *) bp + c_padsz;
975	}
976	*bp++ = htonl(AFS_SET_MODE);
977	*bp++ = 0; /* mtime */
978	*bp++ = 0; /* owner */
979	*bp++ = 0; /* group */
980	*bp++ = htonl(S_IRWXUGO); /* unix mode */
981	*bp++ = 0; /* segment size */
982
983	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
984}
985
986/*
987 * deliver reply data to an FS.Rename
988 */
989static int afs_deliver_fs_rename(struct afs_call *call,
990				  struct sk_buff *skb, bool last)
991{
992	struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
993	const __be32 *bp;
994
995	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
996
997	afs_transfer_reply(call, skb);
998	if (!last)
999		return 0;
1000
1001	if (call->reply_size != call->reply_max)
1002		return -EBADMSG;
1003
1004	/* unmarshall the reply once we've received all of it */
1005	bp = call->buffer;
1006	xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
1007	if (new_dvnode != orig_dvnode)
1008		xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
1009					  NULL);
1010	/* xdr_decode_AFSVolSync(&bp, call->replyX); */
1011
1012	_leave(" = 0 [done]");
1013	return 0;
1014}
1015
1016/*
1017 * FS.Rename operation type
1018 */
1019static const struct afs_call_type afs_RXFSRename = {
1020	.name		= "FS.Rename",
1021	.deliver	= afs_deliver_fs_rename,
1022	.abort_to_error	= afs_abort_to_error,
1023	.destructor	= afs_flat_call_destructor,
1024};
1025
1026/*
1027 * create a symbolic link
1028 */
1029int afs_fs_rename(struct afs_server *server,
1030		  struct key *key,
1031		  struct afs_vnode *orig_dvnode,
1032		  const char *orig_name,
1033		  struct afs_vnode *new_dvnode,
1034		  const char *new_name,
1035		  const struct afs_wait_mode *wait_mode)
1036{
1037	struct afs_call *call;
1038	size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1039	__be32 *bp;
1040
1041	_enter("");
1042
1043	o_namesz = strlen(orig_name);
1044	o_padsz = (4 - (o_namesz & 3)) & 3;
1045
1046	n_namesz = strlen(new_name);
1047	n_padsz = (4 - (n_namesz & 3)) & 3;
1048
1049	reqsz = (4 * 4) +
1050		4 + o_namesz + o_padsz +
1051		(3 * 4) +
1052		4 + n_namesz + n_padsz;
1053
1054	call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1055	if (!call)
1056		return -ENOMEM;
1057
1058	call->key = key;
1059	call->reply = orig_dvnode;
1060	call->reply2 = new_dvnode;
1061	call->service_id = FS_SERVICE;
1062	call->port = htons(AFS_FS_PORT);
1063
1064	/* marshall the parameters */
1065	bp = call->request;
1066	*bp++ = htonl(FSRENAME);
1067	*bp++ = htonl(orig_dvnode->fid.vid);
1068	*bp++ = htonl(orig_dvnode->fid.vnode);
1069	*bp++ = htonl(orig_dvnode->fid.unique);
1070	*bp++ = htonl(o_namesz);
1071	memcpy(bp, orig_name, o_namesz);
1072	bp = (void *) bp + o_namesz;
1073	if (o_padsz > 0) {
1074		memset(bp, 0, o_padsz);
1075		bp = (void *) bp + o_padsz;
1076	}
1077
1078	*bp++ = htonl(new_dvnode->fid.vid);
1079	*bp++ = htonl(new_dvnode->fid.vnode);
1080	*bp++ = htonl(new_dvnode->fid.unique);
1081	*bp++ = htonl(n_namesz);
1082	memcpy(bp, new_name, n_namesz);
1083	bp = (void *) bp + n_namesz;
1084	if (n_padsz > 0) {
1085		memset(bp, 0, n_padsz);
1086		bp = (void *) bp + n_padsz;
1087	}
1088
1089	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1090}
1091
1092/*
1093 * deliver reply data to an FS.StoreData
1094 */
1095static int afs_deliver_fs_store_data(struct afs_call *call,
1096				     struct sk_buff *skb, bool last)
1097{
1098	struct afs_vnode *vnode = call->reply;
1099	const __be32 *bp;
1100
1101	_enter(",,%u", last);
1102
1103	afs_transfer_reply(call, skb);
1104	if (!last) {
1105		_leave(" = 0 [more]");
1106		return 0;
1107	}
1108
1109	if (call->reply_size != call->reply_max) {
1110		_leave(" = -EBADMSG [%u != %u]",
1111		       call->reply_size, call->reply_max);
1112		return -EBADMSG;
1113	}
1114
1115	/* unmarshall the reply once we've received all of it */
1116	bp = call->buffer;
1117	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1118				  &call->store_version);
1119	/* xdr_decode_AFSVolSync(&bp, call->replyX); */
1120
1121	afs_pages_written_back(vnode, call);
1122
1123	_leave(" = 0 [done]");
1124	return 0;
1125}
1126
1127/*
1128 * FS.StoreData operation type
1129 */
1130static const struct afs_call_type afs_RXFSStoreData = {
1131	.name		= "FS.StoreData",
1132	.deliver	= afs_deliver_fs_store_data,
1133	.abort_to_error	= afs_abort_to_error,
1134	.destructor	= afs_flat_call_destructor,
1135};
1136
1137static const struct afs_call_type afs_RXFSStoreData64 = {
1138	.name		= "FS.StoreData64",
1139	.deliver	= afs_deliver_fs_store_data,
1140	.abort_to_error	= afs_abort_to_error,
1141	.destructor	= afs_flat_call_destructor,
1142};
1143
1144/*
1145 * store a set of pages to a very large file
1146 */
1147static int afs_fs_store_data64(struct afs_server *server,
1148			       struct afs_writeback *wb,
1149			       pgoff_t first, pgoff_t last,
1150			       unsigned offset, unsigned to,
1151			       loff_t size, loff_t pos, loff_t i_size,
1152			       const struct afs_wait_mode *wait_mode)
1153{
1154	struct afs_vnode *vnode = wb->vnode;
1155	struct afs_call *call;
1156	__be32 *bp;
1157
1158	_enter(",%x,{%x:%u},,",
1159	       key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1160
1161	call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1162				   (4 + 6 + 3 * 2) * 4,
1163				   (21 + 6) * 4);
1164	if (!call)
1165		return -ENOMEM;
1166
1167	call->wb = wb;
1168	call->key = wb->key;
1169	call->reply = vnode;
1170	call->service_id = FS_SERVICE;
1171	call->port = htons(AFS_FS_PORT);
1172	call->mapping = vnode->vfs_inode.i_mapping;
1173	call->first = first;
1174	call->last = last;
1175	call->first_offset = offset;
1176	call->last_to = to;
1177	call->send_pages = true;
1178	call->store_version = vnode->status.data_version + 1;
1179
1180	/* marshall the parameters */
1181	bp = call->request;
1182	*bp++ = htonl(FSSTOREDATA64);
1183	*bp++ = htonl(vnode->fid.vid);
1184	*bp++ = htonl(vnode->fid.vnode);
1185	*bp++ = htonl(vnode->fid.unique);
1186
1187	*bp++ = 0; /* mask */
1188	*bp++ = 0; /* mtime */
1189	*bp++ = 0; /* owner */
1190	*bp++ = 0; /* group */
1191	*bp++ = 0; /* unix mode */
1192	*bp++ = 0; /* segment size */
1193
1194	*bp++ = htonl(pos >> 32);
1195	*bp++ = htonl((u32) pos);
1196	*bp++ = htonl(size >> 32);
1197	*bp++ = htonl((u32) size);
1198	*bp++ = htonl(i_size >> 32);
1199	*bp++ = htonl((u32) i_size);
1200
1201	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1202}
1203
1204/*
1205 * store a set of pages
1206 */
1207int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1208		      pgoff_t first, pgoff_t last,
1209		      unsigned offset, unsigned to,
1210		      const struct afs_wait_mode *wait_mode)
1211{
1212	struct afs_vnode *vnode = wb->vnode;
1213	struct afs_call *call;
1214	loff_t size, pos, i_size;
1215	__be32 *bp;
1216
1217	_enter(",%x,{%x:%u},,",
1218	       key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1219
1220	size = to - offset;
1221	if (first != last)
1222		size += (loff_t)(last - first) << PAGE_SHIFT;
1223	pos = (loff_t)first << PAGE_SHIFT;
1224	pos += offset;
1225
1226	i_size = i_size_read(&vnode->vfs_inode);
1227	if (pos + size > i_size)
1228		i_size = size + pos;
1229
1230	_debug("size %llx, at %llx, i_size %llx",
1231	       (unsigned long long) size, (unsigned long long) pos,
1232	       (unsigned long long) i_size);
1233
1234	if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1235		return afs_fs_store_data64(server, wb, first, last, offset, to,
1236					   size, pos, i_size, wait_mode);
1237
1238	call = afs_alloc_flat_call(&afs_RXFSStoreData,
1239				   (4 + 6 + 3) * 4,
1240				   (21 + 6) * 4);
1241	if (!call)
1242		return -ENOMEM;
1243
1244	call->wb = wb;
1245	call->key = wb->key;
1246	call->reply = vnode;
1247	call->service_id = FS_SERVICE;
1248	call->port = htons(AFS_FS_PORT);
1249	call->mapping = vnode->vfs_inode.i_mapping;
1250	call->first = first;
1251	call->last = last;
1252	call->first_offset = offset;
1253	call->last_to = to;
1254	call->send_pages = true;
1255	call->store_version = vnode->status.data_version + 1;
1256
1257	/* marshall the parameters */
1258	bp = call->request;
1259	*bp++ = htonl(FSSTOREDATA);
1260	*bp++ = htonl(vnode->fid.vid);
1261	*bp++ = htonl(vnode->fid.vnode);
1262	*bp++ = htonl(vnode->fid.unique);
1263
1264	*bp++ = 0; /* mask */
1265	*bp++ = 0; /* mtime */
1266	*bp++ = 0; /* owner */
1267	*bp++ = 0; /* group */
1268	*bp++ = 0; /* unix mode */
1269	*bp++ = 0; /* segment size */
1270
1271	*bp++ = htonl(pos);
1272	*bp++ = htonl(size);
1273	*bp++ = htonl(i_size);
1274
1275	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1276}
1277
1278/*
1279 * deliver reply data to an FS.StoreStatus
1280 */
1281static int afs_deliver_fs_store_status(struct afs_call *call,
1282				       struct sk_buff *skb, bool last)
1283{
1284	afs_dataversion_t *store_version;
1285	struct afs_vnode *vnode = call->reply;
1286	const __be32 *bp;
1287
1288	_enter(",,%u", last);
1289
1290	afs_transfer_reply(call, skb);
1291	if (!last) {
1292		_leave(" = 0 [more]");
1293		return 0;
1294	}
1295
1296	if (call->reply_size != call->reply_max) {
1297		_leave(" = -EBADMSG [%u != %u]",
1298		       call->reply_size, call->reply_max);
1299		return -EBADMSG;
1300	}
1301
1302	/* unmarshall the reply once we've received all of it */
1303	store_version = NULL;
1304	if (call->operation_ID == FSSTOREDATA)
1305		store_version = &call->store_version;
1306
1307	bp = call->buffer;
1308	xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1309	/* xdr_decode_AFSVolSync(&bp, call->replyX); */
1310
1311	_leave(" = 0 [done]");
1312	return 0;
1313}
1314
1315/*
1316 * FS.StoreStatus operation type
1317 */
1318static const struct afs_call_type afs_RXFSStoreStatus = {
1319	.name		= "FS.StoreStatus",
1320	.deliver	= afs_deliver_fs_store_status,
1321	.abort_to_error	= afs_abort_to_error,
1322	.destructor	= afs_flat_call_destructor,
1323};
1324
1325static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1326	.name		= "FS.StoreData",
1327	.deliver	= afs_deliver_fs_store_status,
1328	.abort_to_error	= afs_abort_to_error,
1329	.destructor	= afs_flat_call_destructor,
1330};
1331
1332static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1333	.name		= "FS.StoreData64",
1334	.deliver	= afs_deliver_fs_store_status,
1335	.abort_to_error	= afs_abort_to_error,
1336	.destructor	= afs_flat_call_destructor,
1337};
1338
1339/*
1340 * set the attributes on a very large file, using FS.StoreData rather than
1341 * FS.StoreStatus so as to alter the file size also
1342 */
1343static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,
1344				 struct afs_vnode *vnode, struct iattr *attr,
1345				 const struct afs_wait_mode *wait_mode)
1346{
1347	struct afs_call *call;
1348	__be32 *bp;
1349
1350	_enter(",%x,{%x:%u},,",
1351	       key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1352
1353	ASSERT(attr->ia_valid & ATTR_SIZE);
1354
1355	call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,
1356				   (4 + 6 + 3 * 2) * 4,
1357				   (21 + 6) * 4);
1358	if (!call)
1359		return -ENOMEM;
1360
1361	call->key = key;
1362	call->reply = vnode;
1363	call->service_id = FS_SERVICE;
1364	call->port = htons(AFS_FS_PORT);
1365	call->store_version = vnode->status.data_version + 1;
1366	call->operation_ID = FSSTOREDATA;
1367
1368	/* marshall the parameters */
1369	bp = call->request;
1370	*bp++ = htonl(FSSTOREDATA64);
1371	*bp++ = htonl(vnode->fid.vid);
1372	*bp++ = htonl(vnode->fid.vnode);
1373	*bp++ = htonl(vnode->fid.unique);
1374
1375	xdr_encode_AFS_StoreStatus(&bp, attr);
1376
1377	*bp++ = 0;				/* position of start of write */
1378	*bp++ = 0;
1379	*bp++ = 0;				/* size of write */
1380	*bp++ = 0;
1381	*bp++ = htonl(attr->ia_size >> 32);	/* new file length */
1382	*bp++ = htonl((u32) attr->ia_size);
1383
1384	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1385}
1386
1387/*
1388 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1389 * so as to alter the file size also
1390 */
1391static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1392			       struct afs_vnode *vnode, struct iattr *attr,
1393			       const struct afs_wait_mode *wait_mode)
1394{
1395	struct afs_call *call;
1396	__be32 *bp;
1397
1398	_enter(",%x,{%x:%u},,",
1399	       key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1400
1401	ASSERT(attr->ia_valid & ATTR_SIZE);
1402	if (attr->ia_size >> 32)
1403		return afs_fs_setattr_size64(server, key, vnode, attr,
1404					     wait_mode);
1405
1406	call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1407				   (4 + 6 + 3) * 4,
1408				   (21 + 6) * 4);
1409	if (!call)
1410		return -ENOMEM;
1411
1412	call->key = key;
1413	call->reply = vnode;
1414	call->service_id = FS_SERVICE;
1415	call->port = htons(AFS_FS_PORT);
1416	call->store_version = vnode->status.data_version + 1;
1417	call->operation_ID = FSSTOREDATA;
1418
1419	/* marshall the parameters */
1420	bp = call->request;
1421	*bp++ = htonl(FSSTOREDATA);
1422	*bp++ = htonl(vnode->fid.vid);
1423	*bp++ = htonl(vnode->fid.vnode);
1424	*bp++ = htonl(vnode->fid.unique);
1425
1426	xdr_encode_AFS_StoreStatus(&bp, attr);
1427
1428	*bp++ = 0;				/* position of start of write */
1429	*bp++ = 0;				/* size of write */
1430	*bp++ = htonl(attr->ia_size);		/* new file length */
1431
1432	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1433}
1434
1435/*
1436 * set the attributes on a file, using FS.StoreData if there's a change in file
1437 * size, and FS.StoreStatus otherwise
1438 */
1439int afs_fs_setattr(struct afs_server *server, struct key *key,
1440		   struct afs_vnode *vnode, struct iattr *attr,
1441		   const struct afs_wait_mode *wait_mode)
1442{
1443	struct afs_call *call;
1444	__be32 *bp;
1445
1446	if (attr->ia_valid & ATTR_SIZE)
1447		return afs_fs_setattr_size(server, key, vnode, attr,
1448					   wait_mode);
1449
1450	_enter(",%x,{%x:%u},,",
1451	       key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1452
1453	call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1454				   (4 + 6) * 4,
1455				   (21 + 6) * 4);
1456	if (!call)
1457		return -ENOMEM;
1458
1459	call->key = key;
1460	call->reply = vnode;
1461	call->service_id = FS_SERVICE;
1462	call->port = htons(AFS_FS_PORT);
1463	call->operation_ID = FSSTORESTATUS;
1464
1465	/* marshall the parameters */
1466	bp = call->request;
1467	*bp++ = htonl(FSSTORESTATUS);
1468	*bp++ = htonl(vnode->fid.vid);
1469	*bp++ = htonl(vnode->fid.vnode);
1470	*bp++ = htonl(vnode->fid.unique);
1471
1472	xdr_encode_AFS_StoreStatus(&bp, attr);
1473
1474	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1475}
1476
1477/*
1478 * deliver reply data to an FS.GetVolumeStatus
1479 */
1480static int afs_deliver_fs_get_volume_status(struct afs_call *call,
1481					    struct sk_buff *skb, bool last)
1482{
1483	const __be32 *bp;
1484	char *p;
1485	int ret;
1486
1487	_enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1488
1489	switch (call->unmarshall) {
1490	case 0:
1491		call->offset = 0;
1492		call->unmarshall++;
1493
1494		/* extract the returned status record */
1495	case 1:
1496		_debug("extract status");
1497		ret = afs_extract_data(call, skb, last, call->buffer,
1498				       12 * 4);
1499		switch (ret) {
1500		case 0:		break;
1501		case -EAGAIN:	return 0;
1502		default:	return ret;
1503		}
1504
1505		bp = call->buffer;
1506		xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
1507		call->offset = 0;
1508		call->unmarshall++;
1509
1510		/* extract the volume name length */
1511	case 2:
1512		ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1513		switch (ret) {
1514		case 0:		break;
1515		case -EAGAIN:	return 0;
1516		default:	return ret;
1517		}
1518
1519		call->count = ntohl(call->tmp);
1520		_debug("volname length: %u", call->count);
1521		if (call->count >= AFSNAMEMAX)
1522			return -EBADMSG;
1523		call->offset = 0;
1524		call->unmarshall++;
1525
1526		/* extract the volume name */
1527	case 3:
1528		_debug("extract volname");
1529		if (call->count > 0) {
1530			ret = afs_extract_data(call, skb, last, call->reply3,
1531					       call->count);
1532			switch (ret) {
1533			case 0:		break;
1534			case -EAGAIN:	return 0;
1535			default:	return ret;
1536			}
1537		}
1538
1539		p = call->reply3;
1540		p[call->count] = 0;
1541		_debug("volname '%s'", p);
1542
1543		call->offset = 0;
1544		call->unmarshall++;
1545
1546		/* extract the volume name padding */
1547		if ((call->count & 3) == 0) {
1548			call->unmarshall++;
1549			goto no_volname_padding;
1550		}
1551		call->count = 4 - (call->count & 3);
1552
1553	case 4:
1554		ret = afs_extract_data(call, skb, last, call->buffer,
1555				       call->count);
1556		switch (ret) {
1557		case 0:		break;
1558		case -EAGAIN:	return 0;
1559		default:	return ret;
1560		}
1561
1562		call->offset = 0;
1563		call->unmarshall++;
1564	no_volname_padding:
1565
1566		/* extract the offline message length */
1567	case 5:
1568		ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1569		switch (ret) {
1570		case 0:		break;
1571		case -EAGAIN:	return 0;
1572		default:	return ret;
1573		}
1574
1575		call->count = ntohl(call->tmp);
1576		_debug("offline msg length: %u", call->count);
1577		if (call->count >= AFSNAMEMAX)
1578			return -EBADMSG;
1579		call->offset = 0;
1580		call->unmarshall++;
1581
1582		/* extract the offline message */
1583	case 6:
1584		_debug("extract offline");
1585		if (call->count > 0) {
1586			ret = afs_extract_data(call, skb, last, call->reply3,
1587					       call->count);
1588			switch (ret) {
1589			case 0:		break;
1590			case -EAGAIN:	return 0;
1591			default:	return ret;
1592			}
1593		}
1594
1595		p = call->reply3;
1596		p[call->count] = 0;
1597		_debug("offline '%s'", p);
1598
1599		call->offset = 0;
1600		call->unmarshall++;
1601
1602		/* extract the offline message padding */
1603		if ((call->count & 3) == 0) {
1604			call->unmarshall++;
1605			goto no_offline_padding;
1606		}
1607		call->count = 4 - (call->count & 3);
1608
1609	case 7:
1610		ret = afs_extract_data(call, skb, last, call->buffer,
1611				       call->count);
1612		switch (ret) {
1613		case 0:		break;
1614		case -EAGAIN:	return 0;
1615		default:	return ret;
1616		}
1617
1618		call->offset = 0;
1619		call->unmarshall++;
1620	no_offline_padding:
1621
1622		/* extract the message of the day length */
1623	case 8:
1624		ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1625		switch (ret) {
1626		case 0:		break;
1627		case -EAGAIN:	return 0;
1628		default:	return ret;
1629		}
1630
1631		call->count = ntohl(call->tmp);
1632		_debug("motd length: %u", call->count);
1633		if (call->count >= AFSNAMEMAX)
1634			return -EBADMSG;
1635		call->offset = 0;
1636		call->unmarshall++;
1637
1638		/* extract the message of the day */
1639	case 9:
1640		_debug("extract motd");
1641		if (call->count > 0) {
1642			ret = afs_extract_data(call, skb, last, call->reply3,
1643					       call->count);
1644			switch (ret) {
1645			case 0:		break;
1646			case -EAGAIN:	return 0;
1647			default:	return ret;
1648			}
1649		}
1650
1651		p = call->reply3;
1652		p[call->count] = 0;
1653		_debug("motd '%s'", p);
1654
1655		call->offset = 0;
1656		call->unmarshall++;
1657
1658		/* extract the message of the day padding */
1659		if ((call->count & 3) == 0) {
1660			call->unmarshall++;
1661			goto no_motd_padding;
1662		}
1663		call->count = 4 - (call->count & 3);
1664
1665	case 10:
1666		ret = afs_extract_data(call, skb, last, call->buffer,
1667				       call->count);
1668		switch (ret) {
1669		case 0:		break;
1670		case -EAGAIN:	return 0;
1671		default:	return ret;
1672		}
1673
1674		call->offset = 0;
1675		call->unmarshall++;
1676	no_motd_padding:
1677
1678	case 11:
1679		_debug("trailer %d", skb->len);
1680		if (skb->len != 0)
1681			return -EBADMSG;
1682		break;
1683	}
1684
1685	if (!last)
1686		return 0;
1687
1688	_leave(" = 0 [done]");
1689	return 0;
1690}
1691
1692/*
1693 * destroy an FS.GetVolumeStatus call
1694 */
1695static void afs_get_volume_status_call_destructor(struct afs_call *call)
1696{
1697	kfree(call->reply3);
1698	call->reply3 = NULL;
1699	afs_flat_call_destructor(call);
1700}
1701
1702/*
1703 * FS.GetVolumeStatus operation type
1704 */
1705static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1706	.name		= "FS.GetVolumeStatus",
1707	.deliver	= afs_deliver_fs_get_volume_status,
1708	.abort_to_error	= afs_abort_to_error,
1709	.destructor	= afs_get_volume_status_call_destructor,
1710};
1711
1712/*
1713 * fetch the status of a volume
1714 */
1715int afs_fs_get_volume_status(struct afs_server *server,
1716			     struct key *key,
1717			     struct afs_vnode *vnode,
1718			     struct afs_volume_status *vs,
1719			     const struct afs_wait_mode *wait_mode)
1720{
1721	struct afs_call *call;
1722	__be32 *bp;
1723	void *tmpbuf;
1724
1725	_enter("");
1726
1727	tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1728	if (!tmpbuf)
1729		return -ENOMEM;
1730
1731	call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1732	if (!call) {
1733		kfree(tmpbuf);
1734		return -ENOMEM;
1735	}
1736
1737	call->key = key;
1738	call->reply = vnode;
1739	call->reply2 = vs;
1740	call->reply3 = tmpbuf;
1741	call->service_id = FS_SERVICE;
1742	call->port = htons(AFS_FS_PORT);
1743
1744	/* marshall the parameters */
1745	bp = call->request;
1746	bp[0] = htonl(FSGETVOLUMESTATUS);
1747	bp[1] = htonl(vnode->fid.vid);
1748
1749	return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1750}
1751