ALSA: hda - enable snoop for Intel Cougar Point
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / afs / fsclient.c
blob023b95b0d9d7612b41ef895c4a2989513fa6b47a
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/sched.h>
14 #include <linux/circ_buf.h>
15 #include "internal.h"
16 #include "afs_fs.h"
19 * decode an AFSFid block
21 static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
23 const __be32 *bp = *_bp;
25 fid->vid = ntohl(*bp++);
26 fid->vnode = ntohl(*bp++);
27 fid->unique = ntohl(*bp++);
28 *_bp = bp;
32 * decode an AFSFetchStatus block
34 static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
35 struct afs_file_status *status,
36 struct afs_vnode *vnode,
37 afs_dataversion_t *store_version)
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 */
45 #define EXTRACT(DST) \
46 do { \
47 u32 x = ntohl(*bp++); \
48 changed |= DST - x; \
49 DST = x; \
50 } while (0)
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 EXTRACT(status->lock_count);
71 size |= (u64) ntohl(*bp++) << 32;
72 bp++; /* spare 4 */
73 *_bp = bp;
75 if (size != status->size) {
76 status->size = size;
77 changed |= true;
79 status->mode &= S_IALLUGO;
81 _debug("vnode time %lx, %lx",
82 status->mtime_client, status->mtime_server);
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;
94 mode = vnode->vfs_inode.i_mode;
95 mode &= ~S_IALLUGO;
96 mode |= status->mode;
97 barrier();
98 vnode->vfs_inode.i_mode = mode;
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;
106 expected_version = status->data_version;
107 if (store_version)
108 expected_version = *store_version;
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);
119 } else if (store_version) {
120 status->data_version = data_version;
125 * decode an AFSCallBack block
127 static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode)
129 const __be32 *bp = *_bp;
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;
138 static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
139 struct afs_callback *cb)
141 const __be32 *bp = *_bp;
143 cb->version = ntohl(*bp++);
144 cb->expiry = ntohl(*bp++);
145 cb->type = ntohl(*bp++);
146 *_bp = bp;
150 * decode an AFSVolSync block
152 static void xdr_decode_AFSVolSync(const __be32 **_bp,
153 struct afs_volsync *volsync)
155 const __be32 *bp = *_bp;
157 volsync->creation = ntohl(*bp++);
158 bp++; /* spare2 */
159 bp++; /* spare3 */
160 bp++; /* spare4 */
161 bp++; /* spare5 */
162 bp++; /* spare6 */
163 *_bp = bp;
167 * encode the requested attributes into an AFSStoreStatus block
169 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
171 __be32 *bp = *_bp;
172 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
174 mask = 0;
175 if (attr->ia_valid & ATTR_MTIME) {
176 mask |= AFS_SET_MTIME;
177 mtime = attr->ia_mtime.tv_sec;
180 if (attr->ia_valid & ATTR_UID) {
181 mask |= AFS_SET_OWNER;
182 owner = attr->ia_uid;
185 if (attr->ia_valid & ATTR_GID) {
186 mask |= AFS_SET_GROUP;
187 group = attr->ia_gid;
190 if (attr->ia_valid & ATTR_MODE) {
191 mask |= AFS_SET_MODE;
192 mode = attr->ia_mode & S_IALLUGO;
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;
205 * decode an AFSFetchVolumeStatus block
207 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
208 struct afs_volume_status *vs)
210 const __be32 *bp = *_bp;
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;
228 * deliver reply data to an FS.FetchStatus
230 static int afs_deliver_fs_fetch_status(struct afs_call *call,
231 struct sk_buff *skb, bool last)
233 struct afs_vnode *vnode = call->reply;
234 const __be32 *bp;
236 _enter(",,%u", last);
238 afs_transfer_reply(call, skb);
239 if (!last)
240 return 0;
242 if (call->reply_size != call->reply_max)
243 return -EBADMSG;
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);
252 _leave(" = 0 [done]");
253 return 0;
257 * FS.FetchStatus operation type
259 static 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,
267 * fetch the status information for a file
269 int 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)
275 struct afs_call *call;
276 __be32 *bp;
278 _enter(",%x,{%x:%u},,",
279 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
281 call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
282 if (!call)
283 return -ENOMEM;
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);
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);
298 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
302 * deliver reply data to an FS.FetchData
304 static int afs_deliver_fs_fetch_data(struct afs_call *call,
305 struct sk_buff *skb, bool last)
307 struct afs_vnode *vnode = call->reply;
308 const __be32 *bp;
309 struct page *page;
310 void *buffer;
311 int ret;
313 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
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;
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;
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++;
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;
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++;
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;
377 call->offset = 0;
378 call->unmarshall++;
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;
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);
396 call->offset = 0;
397 call->unmarshall++;
399 case 5:
400 _debug("trailer");
401 if (skb->len != 0)
402 return -EBADMSG;
403 break;
406 if (!last)
407 return 0;
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);
417 _leave(" = 0 [done]");
418 return 0;
422 * FS.FetchData operation type
424 static 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,
431 static 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,
439 * fetch data from a very large file
441 static 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)
448 struct afs_call *call;
449 __be32 *bp;
451 _enter("");
453 ASSERTCMP(length, <, ULONG_MAX);
455 call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
456 if (!call)
457 return -ENOMEM;
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;
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);
478 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
482 * fetch data from a file
484 int 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)
491 struct afs_call *call;
492 __be32 *bp;
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);
498 _enter("");
500 call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
501 if (!call)
502 return -ENOMEM;
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;
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);
521 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
525 * deliver reply data to an FS.GiveUpCallBacks
527 static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
528 struct sk_buff *skb, bool last)
530 _enter(",{%u},%d", skb->len, last);
532 if (skb->len > 0)
533 return -EBADMSG; /* shouldn't be any reply data */
534 return 0;
538 * FS.GiveUpCallBacks operation type
540 static 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,
548 * give up a set of callbacks
549 * - the callbacks are held in the server->cb_break ring
551 int afs_fs_give_up_callbacks(struct afs_server *server,
552 const struct afs_wait_mode *wait_mode)
554 struct afs_call *call;
555 size_t ncallbacks;
556 __be32 *bp, *tp;
557 int loop;
559 ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
560 ARRAY_SIZE(server->cb_break));
562 _enter("{%zu},", ncallbacks);
564 if (ncallbacks == 0)
565 return 0;
566 if (ncallbacks > AFSCBMAX)
567 ncallbacks = AFSCBMAX;
569 _debug("break %zu callbacks", ncallbacks);
571 call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
572 12 + ncallbacks * 6 * 4, 0);
573 if (!call)
574 return -ENOMEM;
576 call->service_id = FS_SERVICE;
577 call->port = htons(AFS_FS_PORT);
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);
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];
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);
603 ASSERT(ncallbacks > 0);
604 wake_up_nr(&server->cb_break_waitq, ncallbacks);
606 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
610 * deliver reply data to an FS.CreateFile or an FS.MakeDir
612 static int afs_deliver_fs_create_vnode(struct afs_call *call,
613 struct sk_buff *skb, bool last)
615 struct afs_vnode *vnode = call->reply;
616 const __be32 *bp;
618 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
620 afs_transfer_reply(call, skb);
621 if (!last)
622 return 0;
624 if (call->reply_size != call->reply_max)
625 return -EBADMSG;
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); */
635 _leave(" = 0 [done]");
636 return 0;
640 * FS.CreateFile and FS.MakeDir operation type
642 static 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,
650 * create a file or make a directory
652 int 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)
662 struct afs_call *call;
663 size_t namesz, reqsz, padsz;
664 __be32 *bp;
666 _enter("");
668 namesz = strlen(name);
669 padsz = (4 - (namesz & 3)) & 3;
670 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
672 call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
673 (3 + 21 + 21 + 3 + 6) * 4);
674 if (!call)
675 return -ENOMEM;
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);
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;
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 */
705 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
709 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
711 static int afs_deliver_fs_remove(struct afs_call *call,
712 struct sk_buff *skb, bool last)
714 struct afs_vnode *vnode = call->reply;
715 const __be32 *bp;
717 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
719 afs_transfer_reply(call, skb);
720 if (!last)
721 return 0;
723 if (call->reply_size != call->reply_max)
724 return -EBADMSG;
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); */
731 _leave(" = 0 [done]");
732 return 0;
736 * FS.RemoveDir/FS.RemoveFile operation type
738 static 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,
746 * remove a file or directory
748 int 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)
755 struct afs_call *call;
756 size_t namesz, reqsz, padsz;
757 __be32 *bp;
759 _enter("");
761 namesz = strlen(name);
762 padsz = (4 - (namesz & 3)) & 3;
763 reqsz = (5 * 4) + namesz + padsz;
765 call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
766 if (!call)
767 return -ENOMEM;
769 call->key = key;
770 call->reply = vnode;
771 call->service_id = FS_SERVICE;
772 call->port = htons(AFS_FS_PORT);
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;
788 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
792 * deliver reply data to an FS.Link
794 static int afs_deliver_fs_link(struct afs_call *call,
795 struct sk_buff *skb, bool last)
797 struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
798 const __be32 *bp;
800 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
802 afs_transfer_reply(call, skb);
803 if (!last)
804 return 0;
806 if (call->reply_size != call->reply_max)
807 return -EBADMSG;
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); */
815 _leave(" = 0 [done]");
816 return 0;
820 * FS.Link operation type
822 static 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,
830 * make a hard link
832 int 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)
839 struct afs_call *call;
840 size_t namesz, reqsz, padsz;
841 __be32 *bp;
843 _enter("");
845 namesz = strlen(name);
846 padsz = (4 - (namesz & 3)) & 3;
847 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
849 call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
850 if (!call)
851 return -ENOMEM;
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);
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;
872 *bp++ = htonl(vnode->fid.vid);
873 *bp++ = htonl(vnode->fid.vnode);
874 *bp++ = htonl(vnode->fid.unique);
876 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
880 * deliver reply data to an FS.Symlink
882 static int afs_deliver_fs_symlink(struct afs_call *call,
883 struct sk_buff *skb, bool last)
885 struct afs_vnode *vnode = call->reply;
886 const __be32 *bp;
888 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
890 afs_transfer_reply(call, skb);
891 if (!last)
892 return 0;
894 if (call->reply_size != call->reply_max)
895 return -EBADMSG;
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); */
904 _leave(" = 0 [done]");
905 return 0;
909 * FS.Symlink operation type
911 static 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,
919 * create a symbolic link
921 int 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)
930 struct afs_call *call;
931 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
932 __be32 *bp;
934 _enter("");
936 namesz = strlen(name);
937 padsz = (4 - (namesz & 3)) & 3;
939 c_namesz = strlen(contents);
940 c_padsz = (4 - (c_namesz & 3)) & 3;
942 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
944 call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
945 (3 + 21 + 21 + 6) * 4);
946 if (!call)
947 return -ENOMEM;
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);
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;
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;
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 */
983 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
987 * deliver reply data to an FS.Rename
989 static int afs_deliver_fs_rename(struct afs_call *call,
990 struct sk_buff *skb, bool last)
992 struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
993 const __be32 *bp;
995 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
997 afs_transfer_reply(call, skb);
998 if (!last)
999 return 0;
1001 if (call->reply_size != call->reply_max)
1002 return -EBADMSG;
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); */
1012 _leave(" = 0 [done]");
1013 return 0;
1017 * FS.Rename operation type
1019 static 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,
1027 * create a symbolic link
1029 int 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)
1037 struct afs_call *call;
1038 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1039 __be32 *bp;
1041 _enter("");
1043 o_namesz = strlen(orig_name);
1044 o_padsz = (4 - (o_namesz & 3)) & 3;
1046 n_namesz = strlen(new_name);
1047 n_padsz = (4 - (n_namesz & 3)) & 3;
1049 reqsz = (4 * 4) +
1050 4 + o_namesz + o_padsz +
1051 (3 * 4) +
1052 4 + n_namesz + n_padsz;
1054 call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1055 if (!call)
1056 return -ENOMEM;
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);
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;
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;
1089 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1093 * deliver reply data to an FS.StoreData
1095 static int afs_deliver_fs_store_data(struct afs_call *call,
1096 struct sk_buff *skb, bool last)
1098 struct afs_vnode *vnode = call->reply;
1099 const __be32 *bp;
1101 _enter(",,%u", last);
1103 afs_transfer_reply(call, skb);
1104 if (!last) {
1105 _leave(" = 0 [more]");
1106 return 0;
1109 if (call->reply_size != call->reply_max) {
1110 _leave(" = -EBADMSG [%u != %u]",
1111 call->reply_size, call->reply_max);
1112 return -EBADMSG;
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); */
1121 afs_pages_written_back(vnode, call);
1123 _leave(" = 0 [done]");
1124 return 0;
1128 * FS.StoreData operation type
1130 static 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,
1137 static 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,
1145 * store a set of pages to a very large file
1147 static 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)
1154 struct afs_vnode *vnode = wb->vnode;
1155 struct afs_call *call;
1156 __be32 *bp;
1158 _enter(",%x,{%x:%u},,",
1159 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1161 call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1162 (4 + 6 + 3 * 2) * 4,
1163 (21 + 6) * 4);
1164 if (!call)
1165 return -ENOMEM;
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;
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);
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 */
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);
1201 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1205 * store a set of pages
1207 int 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)
1212 struct afs_vnode *vnode = wb->vnode;
1213 struct afs_call *call;
1214 loff_t size, pos, i_size;
1215 __be32 *bp;
1217 _enter(",%x,{%x:%u},,",
1218 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
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;
1226 i_size = i_size_read(&vnode->vfs_inode);
1227 if (pos + size > i_size)
1228 i_size = size + pos;
1230 _debug("size %llx, at %llx, i_size %llx",
1231 (unsigned long long) size, (unsigned long long) pos,
1232 (unsigned long long) i_size);
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);
1238 call = afs_alloc_flat_call(&afs_RXFSStoreData,
1239 (4 + 6 + 3) * 4,
1240 (21 + 6) * 4);
1241 if (!call)
1242 return -ENOMEM;
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;
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);
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 */
1271 *bp++ = htonl(pos);
1272 *bp++ = htonl(size);
1273 *bp++ = htonl(i_size);
1275 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1279 * deliver reply data to an FS.StoreStatus
1281 static int afs_deliver_fs_store_status(struct afs_call *call,
1282 struct sk_buff *skb, bool last)
1284 afs_dataversion_t *store_version;
1285 struct afs_vnode *vnode = call->reply;
1286 const __be32 *bp;
1288 _enter(",,%u", last);
1290 afs_transfer_reply(call, skb);
1291 if (!last) {
1292 _leave(" = 0 [more]");
1293 return 0;
1296 if (call->reply_size != call->reply_max) {
1297 _leave(" = -EBADMSG [%u != %u]",
1298 call->reply_size, call->reply_max);
1299 return -EBADMSG;
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;
1307 bp = call->buffer;
1308 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1309 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1311 _leave(" = 0 [done]");
1312 return 0;
1316 * FS.StoreStatus operation type
1318 static 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,
1325 static 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,
1332 static 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,
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
1343 static 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)
1347 struct afs_call *call;
1348 __be32 *bp;
1350 _enter(",%x,{%x:%u},,",
1351 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1353 ASSERT(attr->ia_valid & ATTR_SIZE);
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;
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;
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);
1375 xdr_encode_AFS_StoreStatus(&bp, attr);
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);
1384 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1388 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1389 * so as to alter the file size also
1391 static 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)
1395 struct afs_call *call;
1396 __be32 *bp;
1398 _enter(",%x,{%x:%u},,",
1399 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
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);
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;
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;
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);
1426 xdr_encode_AFS_StoreStatus(&bp, attr);
1428 *bp++ = 0; /* position of start of write */
1429 *bp++ = 0; /* size of write */
1430 *bp++ = htonl(attr->ia_size); /* new file length */
1432 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1436 * set the attributes on a file, using FS.StoreData if there's a change in file
1437 * size, and FS.StoreStatus otherwise
1439 int 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)
1443 struct afs_call *call;
1444 __be32 *bp;
1446 if (attr->ia_valid & ATTR_SIZE)
1447 return afs_fs_setattr_size(server, key, vnode, attr,
1448 wait_mode);
1450 _enter(",%x,{%x:%u},,",
1451 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1453 call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1454 (4 + 6) * 4,
1455 (21 + 6) * 4);
1456 if (!call)
1457 return -ENOMEM;
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;
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);
1472 xdr_encode_AFS_StoreStatus(&bp, attr);
1474 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1478 * deliver reply data to an FS.GetVolumeStatus
1480 static int afs_deliver_fs_get_volume_status(struct afs_call *call,
1481 struct sk_buff *skb, bool last)
1483 const __be32 *bp;
1484 char *p;
1485 int ret;
1487 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1489 switch (call->unmarshall) {
1490 case 0:
1491 call->offset = 0;
1492 call->unmarshall++;
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;
1505 bp = call->buffer;
1506 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
1507 call->offset = 0;
1508 call->unmarshall++;
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;
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++;
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;
1539 p = call->reply3;
1540 p[call->count] = 0;
1541 _debug("volname '%s'", p);
1543 call->offset = 0;
1544 call->unmarshall++;
1546 /* extract the volume name padding */
1547 if ((call->count & 3) == 0) {
1548 call->unmarshall++;
1549 goto no_volname_padding;
1551 call->count = 4 - (call->count & 3);
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;
1562 call->offset = 0;
1563 call->unmarshall++;
1564 no_volname_padding:
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;
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++;
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;
1595 p = call->reply3;
1596 p[call->count] = 0;
1597 _debug("offline '%s'", p);
1599 call->offset = 0;
1600 call->unmarshall++;
1602 /* extract the offline message padding */
1603 if ((call->count & 3) == 0) {
1604 call->unmarshall++;
1605 goto no_offline_padding;
1607 call->count = 4 - (call->count & 3);
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;
1618 call->offset = 0;
1619 call->unmarshall++;
1620 no_offline_padding:
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;
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++;
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;
1651 p = call->reply3;
1652 p[call->count] = 0;
1653 _debug("motd '%s'", p);
1655 call->offset = 0;
1656 call->unmarshall++;
1658 /* extract the message of the day padding */
1659 if ((call->count & 3) == 0) {
1660 call->unmarshall++;
1661 goto no_motd_padding;
1663 call->count = 4 - (call->count & 3);
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;
1674 call->offset = 0;
1675 call->unmarshall++;
1676 no_motd_padding:
1678 case 11:
1679 _debug("trailer %d", skb->len);
1680 if (skb->len != 0)
1681 return -EBADMSG;
1682 break;
1685 if (!last)
1686 return 0;
1688 _leave(" = 0 [done]");
1689 return 0;
1693 * destroy an FS.GetVolumeStatus call
1695 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1697 kfree(call->reply3);
1698 call->reply3 = NULL;
1699 afs_flat_call_destructor(call);
1703 * FS.GetVolumeStatus operation type
1705 static 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,
1713 * fetch the status of a volume
1715 int 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)
1721 struct afs_call *call;
1722 __be32 *bp;
1723 void *tmpbuf;
1725 _enter("");
1727 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1728 if (!tmpbuf)
1729 return -ENOMEM;
1731 call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1732 if (!call) {
1733 kfree(tmpbuf);
1734 return -ENOMEM;
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);
1744 /* marshall the parameters */
1745 bp = call->request;
1746 bp[0] = htonl(FSGETVOLUMESTATUS);
1747 bp[1] = htonl(vnode->fid.vid);
1749 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1753 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1755 static int afs_deliver_fs_xxxx_lock(struct afs_call *call,
1756 struct sk_buff *skb, bool last)
1758 const __be32 *bp;
1760 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1762 afs_transfer_reply(call, skb);
1763 if (!last)
1764 return 0;
1766 if (call->reply_size != call->reply_max)
1767 return -EBADMSG;
1769 /* unmarshall the reply once we've received all of it */
1770 bp = call->buffer;
1771 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1773 _leave(" = 0 [done]");
1774 return 0;
1778 * FS.SetLock operation type
1780 static const struct afs_call_type afs_RXFSSetLock = {
1781 .name = "FS.SetLock",
1782 .deliver = afs_deliver_fs_xxxx_lock,
1783 .abort_to_error = afs_abort_to_error,
1784 .destructor = afs_flat_call_destructor,
1788 * FS.ExtendLock operation type
1790 static const struct afs_call_type afs_RXFSExtendLock = {
1791 .name = "FS.ExtendLock",
1792 .deliver = afs_deliver_fs_xxxx_lock,
1793 .abort_to_error = afs_abort_to_error,
1794 .destructor = afs_flat_call_destructor,
1798 * FS.ReleaseLock operation type
1800 static const struct afs_call_type afs_RXFSReleaseLock = {
1801 .name = "FS.ReleaseLock",
1802 .deliver = afs_deliver_fs_xxxx_lock,
1803 .abort_to_error = afs_abort_to_error,
1804 .destructor = afs_flat_call_destructor,
1808 * get a lock on a file
1810 int afs_fs_set_lock(struct afs_server *server,
1811 struct key *key,
1812 struct afs_vnode *vnode,
1813 afs_lock_type_t type,
1814 const struct afs_wait_mode *wait_mode)
1816 struct afs_call *call;
1817 __be32 *bp;
1819 _enter("");
1821 call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);
1822 if (!call)
1823 return -ENOMEM;
1825 call->key = key;
1826 call->reply = vnode;
1827 call->service_id = FS_SERVICE;
1828 call->port = htons(AFS_FS_PORT);
1830 /* marshall the parameters */
1831 bp = call->request;
1832 *bp++ = htonl(FSSETLOCK);
1833 *bp++ = htonl(vnode->fid.vid);
1834 *bp++ = htonl(vnode->fid.vnode);
1835 *bp++ = htonl(vnode->fid.unique);
1836 *bp++ = htonl(type);
1838 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1842 * extend a lock on a file
1844 int afs_fs_extend_lock(struct afs_server *server,
1845 struct key *key,
1846 struct afs_vnode *vnode,
1847 const struct afs_wait_mode *wait_mode)
1849 struct afs_call *call;
1850 __be32 *bp;
1852 _enter("");
1854 call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);
1855 if (!call)
1856 return -ENOMEM;
1858 call->key = key;
1859 call->reply = vnode;
1860 call->service_id = FS_SERVICE;
1861 call->port = htons(AFS_FS_PORT);
1863 /* marshall the parameters */
1864 bp = call->request;
1865 *bp++ = htonl(FSEXTENDLOCK);
1866 *bp++ = htonl(vnode->fid.vid);
1867 *bp++ = htonl(vnode->fid.vnode);
1868 *bp++ = htonl(vnode->fid.unique);
1870 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1874 * release a lock on a file
1876 int afs_fs_release_lock(struct afs_server *server,
1877 struct key *key,
1878 struct afs_vnode *vnode,
1879 const struct afs_wait_mode *wait_mode)
1881 struct afs_call *call;
1882 __be32 *bp;
1884 _enter("");
1886 call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1887 if (!call)
1888 return -ENOMEM;
1890 call->key = key;
1891 call->reply = vnode;
1892 call->service_id = FS_SERVICE;
1893 call->port = htons(AFS_FS_PORT);
1895 /* marshall the parameters */
1896 bp = call->request;
1897 *bp++ = htonl(FSRELEASELOCK);
1898 *bp++ = htonl(vnode->fid.vid);
1899 *bp++ = htonl(vnode->fid.vnode);
1900 *bp++ = htonl(vnode->fid.unique);
1902 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);