Merge branch 'v6v7' into devel
[linux/fpc-iii.git] / fs / afs / fsclient.c
blob4bd0218473a9bb407a9c86be49f0400461621f24
1 /* AFS File Server client stubs
3 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/sched.h>
15 #include <linux/circ_buf.h>
16 #include "internal.h"
17 #include "afs_fs.h"
20 * decode an AFSFid block
22 static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
24 const __be32 *bp = *_bp;
26 fid->vid = ntohl(*bp++);
27 fid->vnode = ntohl(*bp++);
28 fid->unique = ntohl(*bp++);
29 *_bp = bp;
33 * decode an AFSFetchStatus block
35 static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
36 struct afs_file_status *status,
37 struct afs_vnode *vnode,
38 afs_dataversion_t *store_version)
40 afs_dataversion_t expected_version;
41 const __be32 *bp = *_bp;
42 umode_t mode;
43 u64 data_version, size;
44 u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
46 #define EXTRACT(DST) \
47 do { \
48 u32 x = ntohl(*bp++); \
49 changed |= DST - x; \
50 DST = x; \
51 } while (0)
53 status->if_version = ntohl(*bp++);
54 EXTRACT(status->type);
55 EXTRACT(status->nlink);
56 size = ntohl(*bp++);
57 data_version = ntohl(*bp++);
58 EXTRACT(status->author);
59 EXTRACT(status->owner);
60 EXTRACT(status->caller_access); /* call ticket dependent */
61 EXTRACT(status->anon_access);
62 EXTRACT(status->mode);
63 EXTRACT(status->parent.vnode);
64 EXTRACT(status->parent.unique);
65 bp++; /* seg size */
66 status->mtime_client = ntohl(*bp++);
67 status->mtime_server = ntohl(*bp++);
68 EXTRACT(status->group);
69 bp++; /* sync counter */
70 data_version |= (u64) ntohl(*bp++) << 32;
71 EXTRACT(status->lock_count);
72 size |= (u64) ntohl(*bp++) << 32;
73 bp++; /* spare 4 */
74 *_bp = bp;
76 if (size != status->size) {
77 status->size = size;
78 changed |= true;
80 status->mode &= S_IALLUGO;
82 _debug("vnode time %lx, %lx",
83 status->mtime_client, status->mtime_server);
85 if (vnode) {
86 status->parent.vid = vnode->fid.vid;
87 if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
88 _debug("vnode changed");
89 i_size_write(&vnode->vfs_inode, size);
90 vnode->vfs_inode.i_uid = status->owner;
91 vnode->vfs_inode.i_gid = status->group;
92 vnode->vfs_inode.i_version = vnode->fid.unique;
93 vnode->vfs_inode.i_nlink = status->nlink;
95 mode = vnode->vfs_inode.i_mode;
96 mode &= ~S_IALLUGO;
97 mode |= status->mode;
98 barrier();
99 vnode->vfs_inode.i_mode = mode;
102 vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server;
103 vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime;
104 vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime;
107 expected_version = status->data_version;
108 if (store_version)
109 expected_version = *store_version;
111 if (expected_version != data_version) {
112 status->data_version = data_version;
113 if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
114 _debug("vnode modified %llx on {%x:%u}",
115 (unsigned long long) data_version,
116 vnode->fid.vid, vnode->fid.vnode);
117 set_bit(AFS_VNODE_MODIFIED, &vnode->flags);
118 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
120 } else if (store_version) {
121 status->data_version = data_version;
126 * decode an AFSCallBack block
128 static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode)
130 const __be32 *bp = *_bp;
132 vnode->cb_version = ntohl(*bp++);
133 vnode->cb_expiry = ntohl(*bp++);
134 vnode->cb_type = ntohl(*bp++);
135 vnode->cb_expires = vnode->cb_expiry + get_seconds();
136 *_bp = bp;
139 static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
140 struct afs_callback *cb)
142 const __be32 *bp = *_bp;
144 cb->version = ntohl(*bp++);
145 cb->expiry = ntohl(*bp++);
146 cb->type = ntohl(*bp++);
147 *_bp = bp;
151 * decode an AFSVolSync block
153 static void xdr_decode_AFSVolSync(const __be32 **_bp,
154 struct afs_volsync *volsync)
156 const __be32 *bp = *_bp;
158 volsync->creation = ntohl(*bp++);
159 bp++; /* spare2 */
160 bp++; /* spare3 */
161 bp++; /* spare4 */
162 bp++; /* spare5 */
163 bp++; /* spare6 */
164 *_bp = bp;
168 * encode the requested attributes into an AFSStoreStatus block
170 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
172 __be32 *bp = *_bp;
173 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
175 mask = 0;
176 if (attr->ia_valid & ATTR_MTIME) {
177 mask |= AFS_SET_MTIME;
178 mtime = attr->ia_mtime.tv_sec;
181 if (attr->ia_valid & ATTR_UID) {
182 mask |= AFS_SET_OWNER;
183 owner = attr->ia_uid;
186 if (attr->ia_valid & ATTR_GID) {
187 mask |= AFS_SET_GROUP;
188 group = attr->ia_gid;
191 if (attr->ia_valid & ATTR_MODE) {
192 mask |= AFS_SET_MODE;
193 mode = attr->ia_mode & S_IALLUGO;
196 *bp++ = htonl(mask);
197 *bp++ = htonl(mtime);
198 *bp++ = htonl(owner);
199 *bp++ = htonl(group);
200 *bp++ = htonl(mode);
201 *bp++ = 0; /* segment size */
202 *_bp = bp;
206 * decode an AFSFetchVolumeStatus block
208 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
209 struct afs_volume_status *vs)
211 const __be32 *bp = *_bp;
213 vs->vid = ntohl(*bp++);
214 vs->parent_id = ntohl(*bp++);
215 vs->online = ntohl(*bp++);
216 vs->in_service = ntohl(*bp++);
217 vs->blessed = ntohl(*bp++);
218 vs->needs_salvage = ntohl(*bp++);
219 vs->type = ntohl(*bp++);
220 vs->min_quota = ntohl(*bp++);
221 vs->max_quota = ntohl(*bp++);
222 vs->blocks_in_use = ntohl(*bp++);
223 vs->part_blocks_avail = ntohl(*bp++);
224 vs->part_max_blocks = ntohl(*bp++);
225 *_bp = bp;
229 * deliver reply data to an FS.FetchStatus
231 static int afs_deliver_fs_fetch_status(struct afs_call *call,
232 struct sk_buff *skb, bool last)
234 struct afs_vnode *vnode = call->reply;
235 const __be32 *bp;
237 _enter(",,%u", last);
239 afs_transfer_reply(call, skb);
240 if (!last)
241 return 0;
243 if (call->reply_size != call->reply_max)
244 return -EBADMSG;
246 /* unmarshall the reply once we've received all of it */
247 bp = call->buffer;
248 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
249 xdr_decode_AFSCallBack(&bp, vnode);
250 if (call->reply2)
251 xdr_decode_AFSVolSync(&bp, call->reply2);
253 _leave(" = 0 [done]");
254 return 0;
258 * FS.FetchStatus operation type
260 static const struct afs_call_type afs_RXFSFetchStatus = {
261 .name = "FS.FetchStatus",
262 .deliver = afs_deliver_fs_fetch_status,
263 .abort_to_error = afs_abort_to_error,
264 .destructor = afs_flat_call_destructor,
268 * fetch the status information for a file
270 int afs_fs_fetch_file_status(struct afs_server *server,
271 struct key *key,
272 struct afs_vnode *vnode,
273 struct afs_volsync *volsync,
274 const struct afs_wait_mode *wait_mode)
276 struct afs_call *call;
277 __be32 *bp;
279 _enter(",%x,{%x:%u},,",
280 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
282 call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
283 if (!call)
284 return -ENOMEM;
286 call->key = key;
287 call->reply = vnode;
288 call->reply2 = volsync;
289 call->service_id = FS_SERVICE;
290 call->port = htons(AFS_FS_PORT);
292 /* marshall the parameters */
293 bp = call->request;
294 bp[0] = htonl(FSFETCHSTATUS);
295 bp[1] = htonl(vnode->fid.vid);
296 bp[2] = htonl(vnode->fid.vnode);
297 bp[3] = htonl(vnode->fid.unique);
299 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
303 * deliver reply data to an FS.FetchData
305 static int afs_deliver_fs_fetch_data(struct afs_call *call,
306 struct sk_buff *skb, bool last)
308 struct afs_vnode *vnode = call->reply;
309 const __be32 *bp;
310 struct page *page;
311 void *buffer;
312 int ret;
314 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
316 switch (call->unmarshall) {
317 case 0:
318 call->offset = 0;
319 call->unmarshall++;
320 if (call->operation_ID != FSFETCHDATA64) {
321 call->unmarshall++;
322 goto no_msw;
325 /* extract the upper part of the returned data length of an
326 * FSFETCHDATA64 op (which should always be 0 using this
327 * client) */
328 case 1:
329 _debug("extract data length (MSW)");
330 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
331 switch (ret) {
332 case 0: break;
333 case -EAGAIN: return 0;
334 default: return ret;
337 call->count = ntohl(call->tmp);
338 _debug("DATA length MSW: %u", call->count);
339 if (call->count > 0)
340 return -EBADMSG;
341 call->offset = 0;
342 call->unmarshall++;
344 no_msw:
345 /* extract the returned data length */
346 case 2:
347 _debug("extract data length");
348 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
349 switch (ret) {
350 case 0: break;
351 case -EAGAIN: return 0;
352 default: return ret;
355 call->count = ntohl(call->tmp);
356 _debug("DATA length: %u", call->count);
357 if (call->count > PAGE_SIZE)
358 return -EBADMSG;
359 call->offset = 0;
360 call->unmarshall++;
362 /* extract the returned data */
363 case 3:
364 _debug("extract data");
365 if (call->count > 0) {
366 page = call->reply3;
367 buffer = kmap_atomic(page, KM_USER0);
368 ret = afs_extract_data(call, skb, last, buffer,
369 call->count);
370 kunmap_atomic(buffer, KM_USER0);
371 switch (ret) {
372 case 0: break;
373 case -EAGAIN: return 0;
374 default: return ret;
378 call->offset = 0;
379 call->unmarshall++;
381 /* extract the metadata */
382 case 4:
383 ret = afs_extract_data(call, skb, last, call->buffer,
384 (21 + 3 + 6) * 4);
385 switch (ret) {
386 case 0: break;
387 case -EAGAIN: return 0;
388 default: return ret;
391 bp = call->buffer;
392 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
393 xdr_decode_AFSCallBack(&bp, vnode);
394 if (call->reply2)
395 xdr_decode_AFSVolSync(&bp, call->reply2);
397 call->offset = 0;
398 call->unmarshall++;
400 case 5:
401 _debug("trailer");
402 if (skb->len != 0)
403 return -EBADMSG;
404 break;
407 if (!last)
408 return 0;
410 if (call->count < PAGE_SIZE) {
411 _debug("clear");
412 page = call->reply3;
413 buffer = kmap_atomic(page, KM_USER0);
414 memset(buffer + call->count, 0, PAGE_SIZE - call->count);
415 kunmap_atomic(buffer, KM_USER0);
418 _leave(" = 0 [done]");
419 return 0;
423 * FS.FetchData operation type
425 static const struct afs_call_type afs_RXFSFetchData = {
426 .name = "FS.FetchData",
427 .deliver = afs_deliver_fs_fetch_data,
428 .abort_to_error = afs_abort_to_error,
429 .destructor = afs_flat_call_destructor,
432 static const struct afs_call_type afs_RXFSFetchData64 = {
433 .name = "FS.FetchData64",
434 .deliver = afs_deliver_fs_fetch_data,
435 .abort_to_error = afs_abort_to_error,
436 .destructor = afs_flat_call_destructor,
440 * fetch data from a very large file
442 static int afs_fs_fetch_data64(struct afs_server *server,
443 struct key *key,
444 struct afs_vnode *vnode,
445 off_t offset, size_t length,
446 struct page *buffer,
447 const struct afs_wait_mode *wait_mode)
449 struct afs_call *call;
450 __be32 *bp;
452 _enter("");
454 ASSERTCMP(length, <, ULONG_MAX);
456 call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
457 if (!call)
458 return -ENOMEM;
460 call->key = key;
461 call->reply = vnode;
462 call->reply2 = NULL; /* volsync */
463 call->reply3 = buffer;
464 call->service_id = FS_SERVICE;
465 call->port = htons(AFS_FS_PORT);
466 call->operation_ID = FSFETCHDATA64;
468 /* marshall the parameters */
469 bp = call->request;
470 bp[0] = htonl(FSFETCHDATA64);
471 bp[1] = htonl(vnode->fid.vid);
472 bp[2] = htonl(vnode->fid.vnode);
473 bp[3] = htonl(vnode->fid.unique);
474 bp[4] = htonl(upper_32_bits(offset));
475 bp[5] = htonl((u32) offset);
476 bp[6] = 0;
477 bp[7] = htonl((u32) length);
479 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
483 * fetch data from a file
485 int afs_fs_fetch_data(struct afs_server *server,
486 struct key *key,
487 struct afs_vnode *vnode,
488 off_t offset, size_t length,
489 struct page *buffer,
490 const struct afs_wait_mode *wait_mode)
492 struct afs_call *call;
493 __be32 *bp;
495 if (upper_32_bits(offset) || upper_32_bits(offset + length))
496 return afs_fs_fetch_data64(server, key, vnode, offset, length,
497 buffer, wait_mode);
499 _enter("");
501 call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
502 if (!call)
503 return -ENOMEM;
505 call->key = key;
506 call->reply = vnode;
507 call->reply2 = NULL; /* volsync */
508 call->reply3 = buffer;
509 call->service_id = FS_SERVICE;
510 call->port = htons(AFS_FS_PORT);
511 call->operation_ID = FSFETCHDATA;
513 /* marshall the parameters */
514 bp = call->request;
515 bp[0] = htonl(FSFETCHDATA);
516 bp[1] = htonl(vnode->fid.vid);
517 bp[2] = htonl(vnode->fid.vnode);
518 bp[3] = htonl(vnode->fid.unique);
519 bp[4] = htonl(offset);
520 bp[5] = htonl(length);
522 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
526 * deliver reply data to an FS.GiveUpCallBacks
528 static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
529 struct sk_buff *skb, bool last)
531 _enter(",{%u},%d", skb->len, last);
533 if (skb->len > 0)
534 return -EBADMSG; /* shouldn't be any reply data */
535 return 0;
539 * FS.GiveUpCallBacks operation type
541 static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
542 .name = "FS.GiveUpCallBacks",
543 .deliver = afs_deliver_fs_give_up_callbacks,
544 .abort_to_error = afs_abort_to_error,
545 .destructor = afs_flat_call_destructor,
549 * give up a set of callbacks
550 * - the callbacks are held in the server->cb_break ring
552 int afs_fs_give_up_callbacks(struct afs_server *server,
553 const struct afs_wait_mode *wait_mode)
555 struct afs_call *call;
556 size_t ncallbacks;
557 __be32 *bp, *tp;
558 int loop;
560 ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
561 ARRAY_SIZE(server->cb_break));
563 _enter("{%zu},", ncallbacks);
565 if (ncallbacks == 0)
566 return 0;
567 if (ncallbacks > AFSCBMAX)
568 ncallbacks = AFSCBMAX;
570 _debug("break %zu callbacks", ncallbacks);
572 call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
573 12 + ncallbacks * 6 * 4, 0);
574 if (!call)
575 return -ENOMEM;
577 call->service_id = FS_SERVICE;
578 call->port = htons(AFS_FS_PORT);
580 /* marshall the parameters */
581 bp = call->request;
582 tp = bp + 2 + ncallbacks * 3;
583 *bp++ = htonl(FSGIVEUPCALLBACKS);
584 *bp++ = htonl(ncallbacks);
585 *tp++ = htonl(ncallbacks);
587 atomic_sub(ncallbacks, &server->cb_break_n);
588 for (loop = ncallbacks; loop > 0; loop--) {
589 struct afs_callback *cb =
590 &server->cb_break[server->cb_break_tail];
592 *bp++ = htonl(cb->fid.vid);
593 *bp++ = htonl(cb->fid.vnode);
594 *bp++ = htonl(cb->fid.unique);
595 *tp++ = htonl(cb->version);
596 *tp++ = htonl(cb->expiry);
597 *tp++ = htonl(cb->type);
598 smp_mb();
599 server->cb_break_tail =
600 (server->cb_break_tail + 1) &
601 (ARRAY_SIZE(server->cb_break) - 1);
604 ASSERT(ncallbacks > 0);
605 wake_up_nr(&server->cb_break_waitq, ncallbacks);
607 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
611 * deliver reply data to an FS.CreateFile or an FS.MakeDir
613 static int afs_deliver_fs_create_vnode(struct afs_call *call,
614 struct sk_buff *skb, bool last)
616 struct afs_vnode *vnode = call->reply;
617 const __be32 *bp;
619 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
621 afs_transfer_reply(call, skb);
622 if (!last)
623 return 0;
625 if (call->reply_size != call->reply_max)
626 return -EBADMSG;
628 /* unmarshall the reply once we've received all of it */
629 bp = call->buffer;
630 xdr_decode_AFSFid(&bp, call->reply2);
631 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
632 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
633 xdr_decode_AFSCallBack_raw(&bp, call->reply4);
634 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
636 _leave(" = 0 [done]");
637 return 0;
641 * FS.CreateFile and FS.MakeDir operation type
643 static const struct afs_call_type afs_RXFSCreateXXXX = {
644 .name = "FS.CreateXXXX",
645 .deliver = afs_deliver_fs_create_vnode,
646 .abort_to_error = afs_abort_to_error,
647 .destructor = afs_flat_call_destructor,
651 * create a file or make a directory
653 int afs_fs_create(struct afs_server *server,
654 struct key *key,
655 struct afs_vnode *vnode,
656 const char *name,
657 umode_t mode,
658 struct afs_fid *newfid,
659 struct afs_file_status *newstatus,
660 struct afs_callback *newcb,
661 const struct afs_wait_mode *wait_mode)
663 struct afs_call *call;
664 size_t namesz, reqsz, padsz;
665 __be32 *bp;
667 _enter("");
669 namesz = strlen(name);
670 padsz = (4 - (namesz & 3)) & 3;
671 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
673 call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
674 (3 + 21 + 21 + 3 + 6) * 4);
675 if (!call)
676 return -ENOMEM;
678 call->key = key;
679 call->reply = vnode;
680 call->reply2 = newfid;
681 call->reply3 = newstatus;
682 call->reply4 = newcb;
683 call->service_id = FS_SERVICE;
684 call->port = htons(AFS_FS_PORT);
686 /* marshall the parameters */
687 bp = call->request;
688 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
689 *bp++ = htonl(vnode->fid.vid);
690 *bp++ = htonl(vnode->fid.vnode);
691 *bp++ = htonl(vnode->fid.unique);
692 *bp++ = htonl(namesz);
693 memcpy(bp, name, namesz);
694 bp = (void *) bp + namesz;
695 if (padsz > 0) {
696 memset(bp, 0, padsz);
697 bp = (void *) bp + padsz;
699 *bp++ = htonl(AFS_SET_MODE);
700 *bp++ = 0; /* mtime */
701 *bp++ = 0; /* owner */
702 *bp++ = 0; /* group */
703 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
704 *bp++ = 0; /* segment size */
706 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
710 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
712 static int afs_deliver_fs_remove(struct afs_call *call,
713 struct sk_buff *skb, bool last)
715 struct afs_vnode *vnode = call->reply;
716 const __be32 *bp;
718 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
720 afs_transfer_reply(call, skb);
721 if (!last)
722 return 0;
724 if (call->reply_size != call->reply_max)
725 return -EBADMSG;
727 /* unmarshall the reply once we've received all of it */
728 bp = call->buffer;
729 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
730 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
732 _leave(" = 0 [done]");
733 return 0;
737 * FS.RemoveDir/FS.RemoveFile operation type
739 static const struct afs_call_type afs_RXFSRemoveXXXX = {
740 .name = "FS.RemoveXXXX",
741 .deliver = afs_deliver_fs_remove,
742 .abort_to_error = afs_abort_to_error,
743 .destructor = afs_flat_call_destructor,
747 * remove a file or directory
749 int afs_fs_remove(struct afs_server *server,
750 struct key *key,
751 struct afs_vnode *vnode,
752 const char *name,
753 bool isdir,
754 const struct afs_wait_mode *wait_mode)
756 struct afs_call *call;
757 size_t namesz, reqsz, padsz;
758 __be32 *bp;
760 _enter("");
762 namesz = strlen(name);
763 padsz = (4 - (namesz & 3)) & 3;
764 reqsz = (5 * 4) + namesz + padsz;
766 call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
767 if (!call)
768 return -ENOMEM;
770 call->key = key;
771 call->reply = vnode;
772 call->service_id = FS_SERVICE;
773 call->port = htons(AFS_FS_PORT);
775 /* marshall the parameters */
776 bp = call->request;
777 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
778 *bp++ = htonl(vnode->fid.vid);
779 *bp++ = htonl(vnode->fid.vnode);
780 *bp++ = htonl(vnode->fid.unique);
781 *bp++ = htonl(namesz);
782 memcpy(bp, name, namesz);
783 bp = (void *) bp + namesz;
784 if (padsz > 0) {
785 memset(bp, 0, padsz);
786 bp = (void *) bp + padsz;
789 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
793 * deliver reply data to an FS.Link
795 static int afs_deliver_fs_link(struct afs_call *call,
796 struct sk_buff *skb, bool last)
798 struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
799 const __be32 *bp;
801 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
803 afs_transfer_reply(call, skb);
804 if (!last)
805 return 0;
807 if (call->reply_size != call->reply_max)
808 return -EBADMSG;
810 /* unmarshall the reply once we've received all of it */
811 bp = call->buffer;
812 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
813 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
814 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
816 _leave(" = 0 [done]");
817 return 0;
821 * FS.Link operation type
823 static const struct afs_call_type afs_RXFSLink = {
824 .name = "FS.Link",
825 .deliver = afs_deliver_fs_link,
826 .abort_to_error = afs_abort_to_error,
827 .destructor = afs_flat_call_destructor,
831 * make a hard link
833 int afs_fs_link(struct afs_server *server,
834 struct key *key,
835 struct afs_vnode *dvnode,
836 struct afs_vnode *vnode,
837 const char *name,
838 const struct afs_wait_mode *wait_mode)
840 struct afs_call *call;
841 size_t namesz, reqsz, padsz;
842 __be32 *bp;
844 _enter("");
846 namesz = strlen(name);
847 padsz = (4 - (namesz & 3)) & 3;
848 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
850 call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
851 if (!call)
852 return -ENOMEM;
854 call->key = key;
855 call->reply = dvnode;
856 call->reply2 = vnode;
857 call->service_id = FS_SERVICE;
858 call->port = htons(AFS_FS_PORT);
860 /* marshall the parameters */
861 bp = call->request;
862 *bp++ = htonl(FSLINK);
863 *bp++ = htonl(dvnode->fid.vid);
864 *bp++ = htonl(dvnode->fid.vnode);
865 *bp++ = htonl(dvnode->fid.unique);
866 *bp++ = htonl(namesz);
867 memcpy(bp, name, namesz);
868 bp = (void *) bp + namesz;
869 if (padsz > 0) {
870 memset(bp, 0, padsz);
871 bp = (void *) bp + padsz;
873 *bp++ = htonl(vnode->fid.vid);
874 *bp++ = htonl(vnode->fid.vnode);
875 *bp++ = htonl(vnode->fid.unique);
877 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
881 * deliver reply data to an FS.Symlink
883 static int afs_deliver_fs_symlink(struct afs_call *call,
884 struct sk_buff *skb, bool last)
886 struct afs_vnode *vnode = call->reply;
887 const __be32 *bp;
889 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
891 afs_transfer_reply(call, skb);
892 if (!last)
893 return 0;
895 if (call->reply_size != call->reply_max)
896 return -EBADMSG;
898 /* unmarshall the reply once we've received all of it */
899 bp = call->buffer;
900 xdr_decode_AFSFid(&bp, call->reply2);
901 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
902 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
903 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
905 _leave(" = 0 [done]");
906 return 0;
910 * FS.Symlink operation type
912 static const struct afs_call_type afs_RXFSSymlink = {
913 .name = "FS.Symlink",
914 .deliver = afs_deliver_fs_symlink,
915 .abort_to_error = afs_abort_to_error,
916 .destructor = afs_flat_call_destructor,
920 * create a symbolic link
922 int afs_fs_symlink(struct afs_server *server,
923 struct key *key,
924 struct afs_vnode *vnode,
925 const char *name,
926 const char *contents,
927 struct afs_fid *newfid,
928 struct afs_file_status *newstatus,
929 const struct afs_wait_mode *wait_mode)
931 struct afs_call *call;
932 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
933 __be32 *bp;
935 _enter("");
937 namesz = strlen(name);
938 padsz = (4 - (namesz & 3)) & 3;
940 c_namesz = strlen(contents);
941 c_padsz = (4 - (c_namesz & 3)) & 3;
943 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
945 call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
946 (3 + 21 + 21 + 6) * 4);
947 if (!call)
948 return -ENOMEM;
950 call->key = key;
951 call->reply = vnode;
952 call->reply2 = newfid;
953 call->reply3 = newstatus;
954 call->service_id = FS_SERVICE;
955 call->port = htons(AFS_FS_PORT);
957 /* marshall the parameters */
958 bp = call->request;
959 *bp++ = htonl(FSSYMLINK);
960 *bp++ = htonl(vnode->fid.vid);
961 *bp++ = htonl(vnode->fid.vnode);
962 *bp++ = htonl(vnode->fid.unique);
963 *bp++ = htonl(namesz);
964 memcpy(bp, name, namesz);
965 bp = (void *) bp + namesz;
966 if (padsz > 0) {
967 memset(bp, 0, padsz);
968 bp = (void *) bp + padsz;
970 *bp++ = htonl(c_namesz);
971 memcpy(bp, contents, c_namesz);
972 bp = (void *) bp + c_namesz;
973 if (c_padsz > 0) {
974 memset(bp, 0, c_padsz);
975 bp = (void *) bp + c_padsz;
977 *bp++ = htonl(AFS_SET_MODE);
978 *bp++ = 0; /* mtime */
979 *bp++ = 0; /* owner */
980 *bp++ = 0; /* group */
981 *bp++ = htonl(S_IRWXUGO); /* unix mode */
982 *bp++ = 0; /* segment size */
984 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
988 * deliver reply data to an FS.Rename
990 static int afs_deliver_fs_rename(struct afs_call *call,
991 struct sk_buff *skb, bool last)
993 struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
994 const __be32 *bp;
996 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
998 afs_transfer_reply(call, skb);
999 if (!last)
1000 return 0;
1002 if (call->reply_size != call->reply_max)
1003 return -EBADMSG;
1005 /* unmarshall the reply once we've received all of it */
1006 bp = call->buffer;
1007 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
1008 if (new_dvnode != orig_dvnode)
1009 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
1010 NULL);
1011 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1013 _leave(" = 0 [done]");
1014 return 0;
1018 * FS.Rename operation type
1020 static const struct afs_call_type afs_RXFSRename = {
1021 .name = "FS.Rename",
1022 .deliver = afs_deliver_fs_rename,
1023 .abort_to_error = afs_abort_to_error,
1024 .destructor = afs_flat_call_destructor,
1028 * create a symbolic link
1030 int afs_fs_rename(struct afs_server *server,
1031 struct key *key,
1032 struct afs_vnode *orig_dvnode,
1033 const char *orig_name,
1034 struct afs_vnode *new_dvnode,
1035 const char *new_name,
1036 const struct afs_wait_mode *wait_mode)
1038 struct afs_call *call;
1039 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1040 __be32 *bp;
1042 _enter("");
1044 o_namesz = strlen(orig_name);
1045 o_padsz = (4 - (o_namesz & 3)) & 3;
1047 n_namesz = strlen(new_name);
1048 n_padsz = (4 - (n_namesz & 3)) & 3;
1050 reqsz = (4 * 4) +
1051 4 + o_namesz + o_padsz +
1052 (3 * 4) +
1053 4 + n_namesz + n_padsz;
1055 call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1056 if (!call)
1057 return -ENOMEM;
1059 call->key = key;
1060 call->reply = orig_dvnode;
1061 call->reply2 = new_dvnode;
1062 call->service_id = FS_SERVICE;
1063 call->port = htons(AFS_FS_PORT);
1065 /* marshall the parameters */
1066 bp = call->request;
1067 *bp++ = htonl(FSRENAME);
1068 *bp++ = htonl(orig_dvnode->fid.vid);
1069 *bp++ = htonl(orig_dvnode->fid.vnode);
1070 *bp++ = htonl(orig_dvnode->fid.unique);
1071 *bp++ = htonl(o_namesz);
1072 memcpy(bp, orig_name, o_namesz);
1073 bp = (void *) bp + o_namesz;
1074 if (o_padsz > 0) {
1075 memset(bp, 0, o_padsz);
1076 bp = (void *) bp + o_padsz;
1079 *bp++ = htonl(new_dvnode->fid.vid);
1080 *bp++ = htonl(new_dvnode->fid.vnode);
1081 *bp++ = htonl(new_dvnode->fid.unique);
1082 *bp++ = htonl(n_namesz);
1083 memcpy(bp, new_name, n_namesz);
1084 bp = (void *) bp + n_namesz;
1085 if (n_padsz > 0) {
1086 memset(bp, 0, n_padsz);
1087 bp = (void *) bp + n_padsz;
1090 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1094 * deliver reply data to an FS.StoreData
1096 static int afs_deliver_fs_store_data(struct afs_call *call,
1097 struct sk_buff *skb, bool last)
1099 struct afs_vnode *vnode = call->reply;
1100 const __be32 *bp;
1102 _enter(",,%u", last);
1104 afs_transfer_reply(call, skb);
1105 if (!last) {
1106 _leave(" = 0 [more]");
1107 return 0;
1110 if (call->reply_size != call->reply_max) {
1111 _leave(" = -EBADMSG [%u != %u]",
1112 call->reply_size, call->reply_max);
1113 return -EBADMSG;
1116 /* unmarshall the reply once we've received all of it */
1117 bp = call->buffer;
1118 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1119 &call->store_version);
1120 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1122 afs_pages_written_back(vnode, call);
1124 _leave(" = 0 [done]");
1125 return 0;
1129 * FS.StoreData operation type
1131 static const struct afs_call_type afs_RXFSStoreData = {
1132 .name = "FS.StoreData",
1133 .deliver = afs_deliver_fs_store_data,
1134 .abort_to_error = afs_abort_to_error,
1135 .destructor = afs_flat_call_destructor,
1138 static const struct afs_call_type afs_RXFSStoreData64 = {
1139 .name = "FS.StoreData64",
1140 .deliver = afs_deliver_fs_store_data,
1141 .abort_to_error = afs_abort_to_error,
1142 .destructor = afs_flat_call_destructor,
1146 * store a set of pages to a very large file
1148 static int afs_fs_store_data64(struct afs_server *server,
1149 struct afs_writeback *wb,
1150 pgoff_t first, pgoff_t last,
1151 unsigned offset, unsigned to,
1152 loff_t size, loff_t pos, loff_t i_size,
1153 const struct afs_wait_mode *wait_mode)
1155 struct afs_vnode *vnode = wb->vnode;
1156 struct afs_call *call;
1157 __be32 *bp;
1159 _enter(",%x,{%x:%u},,",
1160 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1162 call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1163 (4 + 6 + 3 * 2) * 4,
1164 (21 + 6) * 4);
1165 if (!call)
1166 return -ENOMEM;
1168 call->wb = wb;
1169 call->key = wb->key;
1170 call->reply = vnode;
1171 call->service_id = FS_SERVICE;
1172 call->port = htons(AFS_FS_PORT);
1173 call->mapping = vnode->vfs_inode.i_mapping;
1174 call->first = first;
1175 call->last = last;
1176 call->first_offset = offset;
1177 call->last_to = to;
1178 call->send_pages = true;
1179 call->store_version = vnode->status.data_version + 1;
1181 /* marshall the parameters */
1182 bp = call->request;
1183 *bp++ = htonl(FSSTOREDATA64);
1184 *bp++ = htonl(vnode->fid.vid);
1185 *bp++ = htonl(vnode->fid.vnode);
1186 *bp++ = htonl(vnode->fid.unique);
1188 *bp++ = 0; /* mask */
1189 *bp++ = 0; /* mtime */
1190 *bp++ = 0; /* owner */
1191 *bp++ = 0; /* group */
1192 *bp++ = 0; /* unix mode */
1193 *bp++ = 0; /* segment size */
1195 *bp++ = htonl(pos >> 32);
1196 *bp++ = htonl((u32) pos);
1197 *bp++ = htonl(size >> 32);
1198 *bp++ = htonl((u32) size);
1199 *bp++ = htonl(i_size >> 32);
1200 *bp++ = htonl((u32) i_size);
1202 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1206 * store a set of pages
1208 int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1209 pgoff_t first, pgoff_t last,
1210 unsigned offset, unsigned to,
1211 const struct afs_wait_mode *wait_mode)
1213 struct afs_vnode *vnode = wb->vnode;
1214 struct afs_call *call;
1215 loff_t size, pos, i_size;
1216 __be32 *bp;
1218 _enter(",%x,{%x:%u},,",
1219 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1221 size = to - offset;
1222 if (first != last)
1223 size += (loff_t)(last - first) << PAGE_SHIFT;
1224 pos = (loff_t)first << PAGE_SHIFT;
1225 pos += offset;
1227 i_size = i_size_read(&vnode->vfs_inode);
1228 if (pos + size > i_size)
1229 i_size = size + pos;
1231 _debug("size %llx, at %llx, i_size %llx",
1232 (unsigned long long) size, (unsigned long long) pos,
1233 (unsigned long long) i_size);
1235 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1236 return afs_fs_store_data64(server, wb, first, last, offset, to,
1237 size, pos, i_size, wait_mode);
1239 call = afs_alloc_flat_call(&afs_RXFSStoreData,
1240 (4 + 6 + 3) * 4,
1241 (21 + 6) * 4);
1242 if (!call)
1243 return -ENOMEM;
1245 call->wb = wb;
1246 call->key = wb->key;
1247 call->reply = vnode;
1248 call->service_id = FS_SERVICE;
1249 call->port = htons(AFS_FS_PORT);
1250 call->mapping = vnode->vfs_inode.i_mapping;
1251 call->first = first;
1252 call->last = last;
1253 call->first_offset = offset;
1254 call->last_to = to;
1255 call->send_pages = true;
1256 call->store_version = vnode->status.data_version + 1;
1258 /* marshall the parameters */
1259 bp = call->request;
1260 *bp++ = htonl(FSSTOREDATA);
1261 *bp++ = htonl(vnode->fid.vid);
1262 *bp++ = htonl(vnode->fid.vnode);
1263 *bp++ = htonl(vnode->fid.unique);
1265 *bp++ = 0; /* mask */
1266 *bp++ = 0; /* mtime */
1267 *bp++ = 0; /* owner */
1268 *bp++ = 0; /* group */
1269 *bp++ = 0; /* unix mode */
1270 *bp++ = 0; /* segment size */
1272 *bp++ = htonl(pos);
1273 *bp++ = htonl(size);
1274 *bp++ = htonl(i_size);
1276 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1280 * deliver reply data to an FS.StoreStatus
1282 static int afs_deliver_fs_store_status(struct afs_call *call,
1283 struct sk_buff *skb, bool last)
1285 afs_dataversion_t *store_version;
1286 struct afs_vnode *vnode = call->reply;
1287 const __be32 *bp;
1289 _enter(",,%u", last);
1291 afs_transfer_reply(call, skb);
1292 if (!last) {
1293 _leave(" = 0 [more]");
1294 return 0;
1297 if (call->reply_size != call->reply_max) {
1298 _leave(" = -EBADMSG [%u != %u]",
1299 call->reply_size, call->reply_max);
1300 return -EBADMSG;
1303 /* unmarshall the reply once we've received all of it */
1304 store_version = NULL;
1305 if (call->operation_ID == FSSTOREDATA)
1306 store_version = &call->store_version;
1308 bp = call->buffer;
1309 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1310 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1312 _leave(" = 0 [done]");
1313 return 0;
1317 * FS.StoreStatus operation type
1319 static const struct afs_call_type afs_RXFSStoreStatus = {
1320 .name = "FS.StoreStatus",
1321 .deliver = afs_deliver_fs_store_status,
1322 .abort_to_error = afs_abort_to_error,
1323 .destructor = afs_flat_call_destructor,
1326 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1327 .name = "FS.StoreData",
1328 .deliver = afs_deliver_fs_store_status,
1329 .abort_to_error = afs_abort_to_error,
1330 .destructor = afs_flat_call_destructor,
1333 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1334 .name = "FS.StoreData64",
1335 .deliver = afs_deliver_fs_store_status,
1336 .abort_to_error = afs_abort_to_error,
1337 .destructor = afs_flat_call_destructor,
1341 * set the attributes on a very large file, using FS.StoreData rather than
1342 * FS.StoreStatus so as to alter the file size also
1344 static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,
1345 struct afs_vnode *vnode, struct iattr *attr,
1346 const struct afs_wait_mode *wait_mode)
1348 struct afs_call *call;
1349 __be32 *bp;
1351 _enter(",%x,{%x:%u},,",
1352 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1354 ASSERT(attr->ia_valid & ATTR_SIZE);
1356 call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,
1357 (4 + 6 + 3 * 2) * 4,
1358 (21 + 6) * 4);
1359 if (!call)
1360 return -ENOMEM;
1362 call->key = key;
1363 call->reply = vnode;
1364 call->service_id = FS_SERVICE;
1365 call->port = htons(AFS_FS_PORT);
1366 call->store_version = vnode->status.data_version + 1;
1367 call->operation_ID = FSSTOREDATA;
1369 /* marshall the parameters */
1370 bp = call->request;
1371 *bp++ = htonl(FSSTOREDATA64);
1372 *bp++ = htonl(vnode->fid.vid);
1373 *bp++ = htonl(vnode->fid.vnode);
1374 *bp++ = htonl(vnode->fid.unique);
1376 xdr_encode_AFS_StoreStatus(&bp, attr);
1378 *bp++ = 0; /* position of start of write */
1379 *bp++ = 0;
1380 *bp++ = 0; /* size of write */
1381 *bp++ = 0;
1382 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1383 *bp++ = htonl((u32) attr->ia_size);
1385 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1389 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1390 * so as to alter the file size also
1392 static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1393 struct afs_vnode *vnode, struct iattr *attr,
1394 const struct afs_wait_mode *wait_mode)
1396 struct afs_call *call;
1397 __be32 *bp;
1399 _enter(",%x,{%x:%u},,",
1400 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1402 ASSERT(attr->ia_valid & ATTR_SIZE);
1403 if (attr->ia_size >> 32)
1404 return afs_fs_setattr_size64(server, key, vnode, attr,
1405 wait_mode);
1407 call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1408 (4 + 6 + 3) * 4,
1409 (21 + 6) * 4);
1410 if (!call)
1411 return -ENOMEM;
1413 call->key = key;
1414 call->reply = vnode;
1415 call->service_id = FS_SERVICE;
1416 call->port = htons(AFS_FS_PORT);
1417 call->store_version = vnode->status.data_version + 1;
1418 call->operation_ID = FSSTOREDATA;
1420 /* marshall the parameters */
1421 bp = call->request;
1422 *bp++ = htonl(FSSTOREDATA);
1423 *bp++ = htonl(vnode->fid.vid);
1424 *bp++ = htonl(vnode->fid.vnode);
1425 *bp++ = htonl(vnode->fid.unique);
1427 xdr_encode_AFS_StoreStatus(&bp, attr);
1429 *bp++ = 0; /* position of start of write */
1430 *bp++ = 0; /* size of write */
1431 *bp++ = htonl(attr->ia_size); /* new file length */
1433 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1437 * set the attributes on a file, using FS.StoreData if there's a change in file
1438 * size, and FS.StoreStatus otherwise
1440 int afs_fs_setattr(struct afs_server *server, struct key *key,
1441 struct afs_vnode *vnode, struct iattr *attr,
1442 const struct afs_wait_mode *wait_mode)
1444 struct afs_call *call;
1445 __be32 *bp;
1447 if (attr->ia_valid & ATTR_SIZE)
1448 return afs_fs_setattr_size(server, key, vnode, attr,
1449 wait_mode);
1451 _enter(",%x,{%x:%u},,",
1452 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1454 call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1455 (4 + 6) * 4,
1456 (21 + 6) * 4);
1457 if (!call)
1458 return -ENOMEM;
1460 call->key = key;
1461 call->reply = vnode;
1462 call->service_id = FS_SERVICE;
1463 call->port = htons(AFS_FS_PORT);
1464 call->operation_ID = FSSTORESTATUS;
1466 /* marshall the parameters */
1467 bp = call->request;
1468 *bp++ = htonl(FSSTORESTATUS);
1469 *bp++ = htonl(vnode->fid.vid);
1470 *bp++ = htonl(vnode->fid.vnode);
1471 *bp++ = htonl(vnode->fid.unique);
1473 xdr_encode_AFS_StoreStatus(&bp, attr);
1475 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1479 * deliver reply data to an FS.GetVolumeStatus
1481 static int afs_deliver_fs_get_volume_status(struct afs_call *call,
1482 struct sk_buff *skb, bool last)
1484 const __be32 *bp;
1485 char *p;
1486 int ret;
1488 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1490 switch (call->unmarshall) {
1491 case 0:
1492 call->offset = 0;
1493 call->unmarshall++;
1495 /* extract the returned status record */
1496 case 1:
1497 _debug("extract status");
1498 ret = afs_extract_data(call, skb, last, call->buffer,
1499 12 * 4);
1500 switch (ret) {
1501 case 0: break;
1502 case -EAGAIN: return 0;
1503 default: return ret;
1506 bp = call->buffer;
1507 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
1508 call->offset = 0;
1509 call->unmarshall++;
1511 /* extract the volume name length */
1512 case 2:
1513 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1514 switch (ret) {
1515 case 0: break;
1516 case -EAGAIN: return 0;
1517 default: return ret;
1520 call->count = ntohl(call->tmp);
1521 _debug("volname length: %u", call->count);
1522 if (call->count >= AFSNAMEMAX)
1523 return -EBADMSG;
1524 call->offset = 0;
1525 call->unmarshall++;
1527 /* extract the volume name */
1528 case 3:
1529 _debug("extract volname");
1530 if (call->count > 0) {
1531 ret = afs_extract_data(call, skb, last, call->reply3,
1532 call->count);
1533 switch (ret) {
1534 case 0: break;
1535 case -EAGAIN: return 0;
1536 default: return ret;
1540 p = call->reply3;
1541 p[call->count] = 0;
1542 _debug("volname '%s'", p);
1544 call->offset = 0;
1545 call->unmarshall++;
1547 /* extract the volume name padding */
1548 if ((call->count & 3) == 0) {
1549 call->unmarshall++;
1550 goto no_volname_padding;
1552 call->count = 4 - (call->count & 3);
1554 case 4:
1555 ret = afs_extract_data(call, skb, last, call->buffer,
1556 call->count);
1557 switch (ret) {
1558 case 0: break;
1559 case -EAGAIN: return 0;
1560 default: return ret;
1563 call->offset = 0;
1564 call->unmarshall++;
1565 no_volname_padding:
1567 /* extract the offline message length */
1568 case 5:
1569 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1570 switch (ret) {
1571 case 0: break;
1572 case -EAGAIN: return 0;
1573 default: return ret;
1576 call->count = ntohl(call->tmp);
1577 _debug("offline msg length: %u", call->count);
1578 if (call->count >= AFSNAMEMAX)
1579 return -EBADMSG;
1580 call->offset = 0;
1581 call->unmarshall++;
1583 /* extract the offline message */
1584 case 6:
1585 _debug("extract offline");
1586 if (call->count > 0) {
1587 ret = afs_extract_data(call, skb, last, call->reply3,
1588 call->count);
1589 switch (ret) {
1590 case 0: break;
1591 case -EAGAIN: return 0;
1592 default: return ret;
1596 p = call->reply3;
1597 p[call->count] = 0;
1598 _debug("offline '%s'", p);
1600 call->offset = 0;
1601 call->unmarshall++;
1603 /* extract the offline message padding */
1604 if ((call->count & 3) == 0) {
1605 call->unmarshall++;
1606 goto no_offline_padding;
1608 call->count = 4 - (call->count & 3);
1610 case 7:
1611 ret = afs_extract_data(call, skb, last, call->buffer,
1612 call->count);
1613 switch (ret) {
1614 case 0: break;
1615 case -EAGAIN: return 0;
1616 default: return ret;
1619 call->offset = 0;
1620 call->unmarshall++;
1621 no_offline_padding:
1623 /* extract the message of the day length */
1624 case 8:
1625 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1626 switch (ret) {
1627 case 0: break;
1628 case -EAGAIN: return 0;
1629 default: return ret;
1632 call->count = ntohl(call->tmp);
1633 _debug("motd length: %u", call->count);
1634 if (call->count >= AFSNAMEMAX)
1635 return -EBADMSG;
1636 call->offset = 0;
1637 call->unmarshall++;
1639 /* extract the message of the day */
1640 case 9:
1641 _debug("extract motd");
1642 if (call->count > 0) {
1643 ret = afs_extract_data(call, skb, last, call->reply3,
1644 call->count);
1645 switch (ret) {
1646 case 0: break;
1647 case -EAGAIN: return 0;
1648 default: return ret;
1652 p = call->reply3;
1653 p[call->count] = 0;
1654 _debug("motd '%s'", p);
1656 call->offset = 0;
1657 call->unmarshall++;
1659 /* extract the message of the day padding */
1660 if ((call->count & 3) == 0) {
1661 call->unmarshall++;
1662 goto no_motd_padding;
1664 call->count = 4 - (call->count & 3);
1666 case 10:
1667 ret = afs_extract_data(call, skb, last, call->buffer,
1668 call->count);
1669 switch (ret) {
1670 case 0: break;
1671 case -EAGAIN: return 0;
1672 default: return ret;
1675 call->offset = 0;
1676 call->unmarshall++;
1677 no_motd_padding:
1679 case 11:
1680 _debug("trailer %d", skb->len);
1681 if (skb->len != 0)
1682 return -EBADMSG;
1683 break;
1686 if (!last)
1687 return 0;
1689 _leave(" = 0 [done]");
1690 return 0;
1694 * destroy an FS.GetVolumeStatus call
1696 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1698 kfree(call->reply3);
1699 call->reply3 = NULL;
1700 afs_flat_call_destructor(call);
1704 * FS.GetVolumeStatus operation type
1706 static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1707 .name = "FS.GetVolumeStatus",
1708 .deliver = afs_deliver_fs_get_volume_status,
1709 .abort_to_error = afs_abort_to_error,
1710 .destructor = afs_get_volume_status_call_destructor,
1714 * fetch the status of a volume
1716 int afs_fs_get_volume_status(struct afs_server *server,
1717 struct key *key,
1718 struct afs_vnode *vnode,
1719 struct afs_volume_status *vs,
1720 const struct afs_wait_mode *wait_mode)
1722 struct afs_call *call;
1723 __be32 *bp;
1724 void *tmpbuf;
1726 _enter("");
1728 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1729 if (!tmpbuf)
1730 return -ENOMEM;
1732 call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1733 if (!call) {
1734 kfree(tmpbuf);
1735 return -ENOMEM;
1738 call->key = key;
1739 call->reply = vnode;
1740 call->reply2 = vs;
1741 call->reply3 = tmpbuf;
1742 call->service_id = FS_SERVICE;
1743 call->port = htons(AFS_FS_PORT);
1745 /* marshall the parameters */
1746 bp = call->request;
1747 bp[0] = htonl(FSGETVOLUMESTATUS);
1748 bp[1] = htonl(vnode->fid.vid);
1750 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1754 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1756 static int afs_deliver_fs_xxxx_lock(struct afs_call *call,
1757 struct sk_buff *skb, bool last)
1759 const __be32 *bp;
1761 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1763 afs_transfer_reply(call, skb);
1764 if (!last)
1765 return 0;
1767 if (call->reply_size != call->reply_max)
1768 return -EBADMSG;
1770 /* unmarshall the reply once we've received all of it */
1771 bp = call->buffer;
1772 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1774 _leave(" = 0 [done]");
1775 return 0;
1779 * FS.SetLock operation type
1781 static const struct afs_call_type afs_RXFSSetLock = {
1782 .name = "FS.SetLock",
1783 .deliver = afs_deliver_fs_xxxx_lock,
1784 .abort_to_error = afs_abort_to_error,
1785 .destructor = afs_flat_call_destructor,
1789 * FS.ExtendLock operation type
1791 static const struct afs_call_type afs_RXFSExtendLock = {
1792 .name = "FS.ExtendLock",
1793 .deliver = afs_deliver_fs_xxxx_lock,
1794 .abort_to_error = afs_abort_to_error,
1795 .destructor = afs_flat_call_destructor,
1799 * FS.ReleaseLock operation type
1801 static const struct afs_call_type afs_RXFSReleaseLock = {
1802 .name = "FS.ReleaseLock",
1803 .deliver = afs_deliver_fs_xxxx_lock,
1804 .abort_to_error = afs_abort_to_error,
1805 .destructor = afs_flat_call_destructor,
1809 * get a lock on a file
1811 int afs_fs_set_lock(struct afs_server *server,
1812 struct key *key,
1813 struct afs_vnode *vnode,
1814 afs_lock_type_t type,
1815 const struct afs_wait_mode *wait_mode)
1817 struct afs_call *call;
1818 __be32 *bp;
1820 _enter("");
1822 call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);
1823 if (!call)
1824 return -ENOMEM;
1826 call->key = key;
1827 call->reply = vnode;
1828 call->service_id = FS_SERVICE;
1829 call->port = htons(AFS_FS_PORT);
1831 /* marshall the parameters */
1832 bp = call->request;
1833 *bp++ = htonl(FSSETLOCK);
1834 *bp++ = htonl(vnode->fid.vid);
1835 *bp++ = htonl(vnode->fid.vnode);
1836 *bp++ = htonl(vnode->fid.unique);
1837 *bp++ = htonl(type);
1839 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1843 * extend a lock on a file
1845 int afs_fs_extend_lock(struct afs_server *server,
1846 struct key *key,
1847 struct afs_vnode *vnode,
1848 const struct afs_wait_mode *wait_mode)
1850 struct afs_call *call;
1851 __be32 *bp;
1853 _enter("");
1855 call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);
1856 if (!call)
1857 return -ENOMEM;
1859 call->key = key;
1860 call->reply = vnode;
1861 call->service_id = FS_SERVICE;
1862 call->port = htons(AFS_FS_PORT);
1864 /* marshall the parameters */
1865 bp = call->request;
1866 *bp++ = htonl(FSEXTENDLOCK);
1867 *bp++ = htonl(vnode->fid.vid);
1868 *bp++ = htonl(vnode->fid.vnode);
1869 *bp++ = htonl(vnode->fid.unique);
1871 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1875 * release a lock on a file
1877 int afs_fs_release_lock(struct afs_server *server,
1878 struct key *key,
1879 struct afs_vnode *vnode,
1880 const struct afs_wait_mode *wait_mode)
1882 struct afs_call *call;
1883 __be32 *bp;
1885 _enter("");
1887 call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1888 if (!call)
1889 return -ENOMEM;
1891 call->key = key;
1892 call->reply = vnode;
1893 call->service_id = FS_SERVICE;
1894 call->port = htons(AFS_FS_PORT);
1896 /* marshall the parameters */
1897 bp = call->request;
1898 *bp++ = htonl(FSRELEASELOCK);
1899 *bp++ = htonl(vnode->fid.vid);
1900 *bp++ = htonl(vnode->fid.vnode);
1901 *bp++ = htonl(vnode->fid.unique);
1903 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);