cifs: remove unneeded variable initialization in cifs_reconnect_tcon
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / afs / fsclient.c
blob346e3289abd70549987ce9f490e1d8b210b66bd1
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_generation = 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;
105 vnode->vfs_inode.i_version = data_version;
108 expected_version = status->data_version;
109 if (store_version)
110 expected_version = *store_version;
112 if (expected_version != data_version) {
113 status->data_version = data_version;
114 if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
115 _debug("vnode modified %llx on {%x:%u}",
116 (unsigned long long) data_version,
117 vnode->fid.vid, vnode->fid.vnode);
118 set_bit(AFS_VNODE_MODIFIED, &vnode->flags);
119 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
121 } else if (store_version) {
122 status->data_version = data_version;
127 * decode an AFSCallBack block
129 static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode)
131 const __be32 *bp = *_bp;
133 vnode->cb_version = ntohl(*bp++);
134 vnode->cb_expiry = ntohl(*bp++);
135 vnode->cb_type = ntohl(*bp++);
136 vnode->cb_expires = vnode->cb_expiry + get_seconds();
137 *_bp = bp;
140 static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
141 struct afs_callback *cb)
143 const __be32 *bp = *_bp;
145 cb->version = ntohl(*bp++);
146 cb->expiry = ntohl(*bp++);
147 cb->type = ntohl(*bp++);
148 *_bp = bp;
152 * decode an AFSVolSync block
154 static void xdr_decode_AFSVolSync(const __be32 **_bp,
155 struct afs_volsync *volsync)
157 const __be32 *bp = *_bp;
159 volsync->creation = ntohl(*bp++);
160 bp++; /* spare2 */
161 bp++; /* spare3 */
162 bp++; /* spare4 */
163 bp++; /* spare5 */
164 bp++; /* spare6 */
165 *_bp = bp;
169 * encode the requested attributes into an AFSStoreStatus block
171 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
173 __be32 *bp = *_bp;
174 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
176 mask = 0;
177 if (attr->ia_valid & ATTR_MTIME) {
178 mask |= AFS_SET_MTIME;
179 mtime = attr->ia_mtime.tv_sec;
182 if (attr->ia_valid & ATTR_UID) {
183 mask |= AFS_SET_OWNER;
184 owner = attr->ia_uid;
187 if (attr->ia_valid & ATTR_GID) {
188 mask |= AFS_SET_GROUP;
189 group = attr->ia_gid;
192 if (attr->ia_valid & ATTR_MODE) {
193 mask |= AFS_SET_MODE;
194 mode = attr->ia_mode & S_IALLUGO;
197 *bp++ = htonl(mask);
198 *bp++ = htonl(mtime);
199 *bp++ = htonl(owner);
200 *bp++ = htonl(group);
201 *bp++ = htonl(mode);
202 *bp++ = 0; /* segment size */
203 *_bp = bp;
207 * decode an AFSFetchVolumeStatus block
209 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
210 struct afs_volume_status *vs)
212 const __be32 *bp = *_bp;
214 vs->vid = ntohl(*bp++);
215 vs->parent_id = ntohl(*bp++);
216 vs->online = ntohl(*bp++);
217 vs->in_service = ntohl(*bp++);
218 vs->blessed = ntohl(*bp++);
219 vs->needs_salvage = ntohl(*bp++);
220 vs->type = ntohl(*bp++);
221 vs->min_quota = ntohl(*bp++);
222 vs->max_quota = ntohl(*bp++);
223 vs->blocks_in_use = ntohl(*bp++);
224 vs->part_blocks_avail = ntohl(*bp++);
225 vs->part_max_blocks = ntohl(*bp++);
226 *_bp = bp;
230 * deliver reply data to an FS.FetchStatus
232 static int afs_deliver_fs_fetch_status(struct afs_call *call,
233 struct sk_buff *skb, bool last)
235 struct afs_vnode *vnode = call->reply;
236 const __be32 *bp;
238 _enter(",,%u", last);
240 afs_transfer_reply(call, skb);
241 if (!last)
242 return 0;
244 if (call->reply_size != call->reply_max)
245 return -EBADMSG;
247 /* unmarshall the reply once we've received all of it */
248 bp = call->buffer;
249 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
250 xdr_decode_AFSCallBack(&bp, vnode);
251 if (call->reply2)
252 xdr_decode_AFSVolSync(&bp, call->reply2);
254 _leave(" = 0 [done]");
255 return 0;
259 * FS.FetchStatus operation type
261 static const struct afs_call_type afs_RXFSFetchStatus = {
262 .name = "FS.FetchStatus",
263 .deliver = afs_deliver_fs_fetch_status,
264 .abort_to_error = afs_abort_to_error,
265 .destructor = afs_flat_call_destructor,
269 * fetch the status information for a file
271 int afs_fs_fetch_file_status(struct afs_server *server,
272 struct key *key,
273 struct afs_vnode *vnode,
274 struct afs_volsync *volsync,
275 const struct afs_wait_mode *wait_mode)
277 struct afs_call *call;
278 __be32 *bp;
280 _enter(",%x,{%x:%u},,",
281 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
283 call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
284 if (!call)
285 return -ENOMEM;
287 call->key = key;
288 call->reply = vnode;
289 call->reply2 = volsync;
290 call->service_id = FS_SERVICE;
291 call->port = htons(AFS_FS_PORT);
293 /* marshall the parameters */
294 bp = call->request;
295 bp[0] = htonl(FSFETCHSTATUS);
296 bp[1] = htonl(vnode->fid.vid);
297 bp[2] = htonl(vnode->fid.vnode);
298 bp[3] = htonl(vnode->fid.unique);
300 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
304 * deliver reply data to an FS.FetchData
306 static int afs_deliver_fs_fetch_data(struct afs_call *call,
307 struct sk_buff *skb, bool last)
309 struct afs_vnode *vnode = call->reply;
310 const __be32 *bp;
311 struct page *page;
312 void *buffer;
313 int ret;
315 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
317 switch (call->unmarshall) {
318 case 0:
319 call->offset = 0;
320 call->unmarshall++;
321 if (call->operation_ID != FSFETCHDATA64) {
322 call->unmarshall++;
323 goto no_msw;
326 /* extract the upper part of the returned data length of an
327 * FSFETCHDATA64 op (which should always be 0 using this
328 * client) */
329 case 1:
330 _debug("extract data length (MSW)");
331 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
332 switch (ret) {
333 case 0: break;
334 case -EAGAIN: return 0;
335 default: return ret;
338 call->count = ntohl(call->tmp);
339 _debug("DATA length MSW: %u", call->count);
340 if (call->count > 0)
341 return -EBADMSG;
342 call->offset = 0;
343 call->unmarshall++;
345 no_msw:
346 /* extract the returned data length */
347 case 2:
348 _debug("extract data length");
349 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
350 switch (ret) {
351 case 0: break;
352 case -EAGAIN: return 0;
353 default: return ret;
356 call->count = ntohl(call->tmp);
357 _debug("DATA length: %u", call->count);
358 if (call->count > PAGE_SIZE)
359 return -EBADMSG;
360 call->offset = 0;
361 call->unmarshall++;
363 /* extract the returned data */
364 case 3:
365 _debug("extract data");
366 if (call->count > 0) {
367 page = call->reply3;
368 buffer = kmap_atomic(page, KM_USER0);
369 ret = afs_extract_data(call, skb, last, buffer,
370 call->count);
371 kunmap_atomic(buffer, KM_USER0);
372 switch (ret) {
373 case 0: break;
374 case -EAGAIN: return 0;
375 default: return ret;
379 call->offset = 0;
380 call->unmarshall++;
382 /* extract the metadata */
383 case 4:
384 ret = afs_extract_data(call, skb, last, call->buffer,
385 (21 + 3 + 6) * 4);
386 switch (ret) {
387 case 0: break;
388 case -EAGAIN: return 0;
389 default: return ret;
392 bp = call->buffer;
393 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
394 xdr_decode_AFSCallBack(&bp, vnode);
395 if (call->reply2)
396 xdr_decode_AFSVolSync(&bp, call->reply2);
398 call->offset = 0;
399 call->unmarshall++;
401 case 5:
402 _debug("trailer");
403 if (skb->len != 0)
404 return -EBADMSG;
405 break;
408 if (!last)
409 return 0;
411 if (call->count < PAGE_SIZE) {
412 _debug("clear");
413 page = call->reply3;
414 buffer = kmap_atomic(page, KM_USER0);
415 memset(buffer + call->count, 0, PAGE_SIZE - call->count);
416 kunmap_atomic(buffer, KM_USER0);
419 _leave(" = 0 [done]");
420 return 0;
424 * FS.FetchData operation type
426 static const struct afs_call_type afs_RXFSFetchData = {
427 .name = "FS.FetchData",
428 .deliver = afs_deliver_fs_fetch_data,
429 .abort_to_error = afs_abort_to_error,
430 .destructor = afs_flat_call_destructor,
433 static const struct afs_call_type afs_RXFSFetchData64 = {
434 .name = "FS.FetchData64",
435 .deliver = afs_deliver_fs_fetch_data,
436 .abort_to_error = afs_abort_to_error,
437 .destructor = afs_flat_call_destructor,
441 * fetch data from a very large file
443 static int afs_fs_fetch_data64(struct afs_server *server,
444 struct key *key,
445 struct afs_vnode *vnode,
446 off_t offset, size_t length,
447 struct page *buffer,
448 const struct afs_wait_mode *wait_mode)
450 struct afs_call *call;
451 __be32 *bp;
453 _enter("");
455 ASSERTCMP(length, <, ULONG_MAX);
457 call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
458 if (!call)
459 return -ENOMEM;
461 call->key = key;
462 call->reply = vnode;
463 call->reply2 = NULL; /* volsync */
464 call->reply3 = buffer;
465 call->service_id = FS_SERVICE;
466 call->port = htons(AFS_FS_PORT);
467 call->operation_ID = FSFETCHDATA64;
469 /* marshall the parameters */
470 bp = call->request;
471 bp[0] = htonl(FSFETCHDATA64);
472 bp[1] = htonl(vnode->fid.vid);
473 bp[2] = htonl(vnode->fid.vnode);
474 bp[3] = htonl(vnode->fid.unique);
475 bp[4] = htonl(upper_32_bits(offset));
476 bp[5] = htonl((u32) offset);
477 bp[6] = 0;
478 bp[7] = htonl((u32) length);
480 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
484 * fetch data from a file
486 int afs_fs_fetch_data(struct afs_server *server,
487 struct key *key,
488 struct afs_vnode *vnode,
489 off_t offset, size_t length,
490 struct page *buffer,
491 const struct afs_wait_mode *wait_mode)
493 struct afs_call *call;
494 __be32 *bp;
496 if (upper_32_bits(offset) || upper_32_bits(offset + length))
497 return afs_fs_fetch_data64(server, key, vnode, offset, length,
498 buffer, wait_mode);
500 _enter("");
502 call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
503 if (!call)
504 return -ENOMEM;
506 call->key = key;
507 call->reply = vnode;
508 call->reply2 = NULL; /* volsync */
509 call->reply3 = buffer;
510 call->service_id = FS_SERVICE;
511 call->port = htons(AFS_FS_PORT);
512 call->operation_ID = FSFETCHDATA;
514 /* marshall the parameters */
515 bp = call->request;
516 bp[0] = htonl(FSFETCHDATA);
517 bp[1] = htonl(vnode->fid.vid);
518 bp[2] = htonl(vnode->fid.vnode);
519 bp[3] = htonl(vnode->fid.unique);
520 bp[4] = htonl(offset);
521 bp[5] = htonl(length);
523 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
527 * deliver reply data to an FS.GiveUpCallBacks
529 static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
530 struct sk_buff *skb, bool last)
532 _enter(",{%u},%d", skb->len, last);
534 if (skb->len > 0)
535 return -EBADMSG; /* shouldn't be any reply data */
536 return 0;
540 * FS.GiveUpCallBacks operation type
542 static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
543 .name = "FS.GiveUpCallBacks",
544 .deliver = afs_deliver_fs_give_up_callbacks,
545 .abort_to_error = afs_abort_to_error,
546 .destructor = afs_flat_call_destructor,
550 * give up a set of callbacks
551 * - the callbacks are held in the server->cb_break ring
553 int afs_fs_give_up_callbacks(struct afs_server *server,
554 const struct afs_wait_mode *wait_mode)
556 struct afs_call *call;
557 size_t ncallbacks;
558 __be32 *bp, *tp;
559 int loop;
561 ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
562 ARRAY_SIZE(server->cb_break));
564 _enter("{%zu},", ncallbacks);
566 if (ncallbacks == 0)
567 return 0;
568 if (ncallbacks > AFSCBMAX)
569 ncallbacks = AFSCBMAX;
571 _debug("break %zu callbacks", ncallbacks);
573 call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
574 12 + ncallbacks * 6 * 4, 0);
575 if (!call)
576 return -ENOMEM;
578 call->service_id = FS_SERVICE;
579 call->port = htons(AFS_FS_PORT);
581 /* marshall the parameters */
582 bp = call->request;
583 tp = bp + 2 + ncallbacks * 3;
584 *bp++ = htonl(FSGIVEUPCALLBACKS);
585 *bp++ = htonl(ncallbacks);
586 *tp++ = htonl(ncallbacks);
588 atomic_sub(ncallbacks, &server->cb_break_n);
589 for (loop = ncallbacks; loop > 0; loop--) {
590 struct afs_callback *cb =
591 &server->cb_break[server->cb_break_tail];
593 *bp++ = htonl(cb->fid.vid);
594 *bp++ = htonl(cb->fid.vnode);
595 *bp++ = htonl(cb->fid.unique);
596 *tp++ = htonl(cb->version);
597 *tp++ = htonl(cb->expiry);
598 *tp++ = htonl(cb->type);
599 smp_mb();
600 server->cb_break_tail =
601 (server->cb_break_tail + 1) &
602 (ARRAY_SIZE(server->cb_break) - 1);
605 ASSERT(ncallbacks > 0);
606 wake_up_nr(&server->cb_break_waitq, ncallbacks);
608 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
612 * deliver reply data to an FS.CreateFile or an FS.MakeDir
614 static int afs_deliver_fs_create_vnode(struct afs_call *call,
615 struct sk_buff *skb, bool last)
617 struct afs_vnode *vnode = call->reply;
618 const __be32 *bp;
620 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
622 afs_transfer_reply(call, skb);
623 if (!last)
624 return 0;
626 if (call->reply_size != call->reply_max)
627 return -EBADMSG;
629 /* unmarshall the reply once we've received all of it */
630 bp = call->buffer;
631 xdr_decode_AFSFid(&bp, call->reply2);
632 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
633 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
634 xdr_decode_AFSCallBack_raw(&bp, call->reply4);
635 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
637 _leave(" = 0 [done]");
638 return 0;
642 * FS.CreateFile and FS.MakeDir operation type
644 static const struct afs_call_type afs_RXFSCreateXXXX = {
645 .name = "FS.CreateXXXX",
646 .deliver = afs_deliver_fs_create_vnode,
647 .abort_to_error = afs_abort_to_error,
648 .destructor = afs_flat_call_destructor,
652 * create a file or make a directory
654 int afs_fs_create(struct afs_server *server,
655 struct key *key,
656 struct afs_vnode *vnode,
657 const char *name,
658 umode_t mode,
659 struct afs_fid *newfid,
660 struct afs_file_status *newstatus,
661 struct afs_callback *newcb,
662 const struct afs_wait_mode *wait_mode)
664 struct afs_call *call;
665 size_t namesz, reqsz, padsz;
666 __be32 *bp;
668 _enter("");
670 namesz = strlen(name);
671 padsz = (4 - (namesz & 3)) & 3;
672 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
674 call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
675 (3 + 21 + 21 + 3 + 6) * 4);
676 if (!call)
677 return -ENOMEM;
679 call->key = key;
680 call->reply = vnode;
681 call->reply2 = newfid;
682 call->reply3 = newstatus;
683 call->reply4 = newcb;
684 call->service_id = FS_SERVICE;
685 call->port = htons(AFS_FS_PORT);
687 /* marshall the parameters */
688 bp = call->request;
689 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
690 *bp++ = htonl(vnode->fid.vid);
691 *bp++ = htonl(vnode->fid.vnode);
692 *bp++ = htonl(vnode->fid.unique);
693 *bp++ = htonl(namesz);
694 memcpy(bp, name, namesz);
695 bp = (void *) bp + namesz;
696 if (padsz > 0) {
697 memset(bp, 0, padsz);
698 bp = (void *) bp + padsz;
700 *bp++ = htonl(AFS_SET_MODE);
701 *bp++ = 0; /* mtime */
702 *bp++ = 0; /* owner */
703 *bp++ = 0; /* group */
704 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
705 *bp++ = 0; /* segment size */
707 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
711 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
713 static int afs_deliver_fs_remove(struct afs_call *call,
714 struct sk_buff *skb, bool last)
716 struct afs_vnode *vnode = call->reply;
717 const __be32 *bp;
719 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
721 afs_transfer_reply(call, skb);
722 if (!last)
723 return 0;
725 if (call->reply_size != call->reply_max)
726 return -EBADMSG;
728 /* unmarshall the reply once we've received all of it */
729 bp = call->buffer;
730 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
731 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
733 _leave(" = 0 [done]");
734 return 0;
738 * FS.RemoveDir/FS.RemoveFile operation type
740 static const struct afs_call_type afs_RXFSRemoveXXXX = {
741 .name = "FS.RemoveXXXX",
742 .deliver = afs_deliver_fs_remove,
743 .abort_to_error = afs_abort_to_error,
744 .destructor = afs_flat_call_destructor,
748 * remove a file or directory
750 int afs_fs_remove(struct afs_server *server,
751 struct key *key,
752 struct afs_vnode *vnode,
753 const char *name,
754 bool isdir,
755 const struct afs_wait_mode *wait_mode)
757 struct afs_call *call;
758 size_t namesz, reqsz, padsz;
759 __be32 *bp;
761 _enter("");
763 namesz = strlen(name);
764 padsz = (4 - (namesz & 3)) & 3;
765 reqsz = (5 * 4) + namesz + padsz;
767 call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
768 if (!call)
769 return -ENOMEM;
771 call->key = key;
772 call->reply = vnode;
773 call->service_id = FS_SERVICE;
774 call->port = htons(AFS_FS_PORT);
776 /* marshall the parameters */
777 bp = call->request;
778 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
779 *bp++ = htonl(vnode->fid.vid);
780 *bp++ = htonl(vnode->fid.vnode);
781 *bp++ = htonl(vnode->fid.unique);
782 *bp++ = htonl(namesz);
783 memcpy(bp, name, namesz);
784 bp = (void *) bp + namesz;
785 if (padsz > 0) {
786 memset(bp, 0, padsz);
787 bp = (void *) bp + padsz;
790 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
794 * deliver reply data to an FS.Link
796 static int afs_deliver_fs_link(struct afs_call *call,
797 struct sk_buff *skb, bool last)
799 struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
800 const __be32 *bp;
802 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
804 afs_transfer_reply(call, skb);
805 if (!last)
806 return 0;
808 if (call->reply_size != call->reply_max)
809 return -EBADMSG;
811 /* unmarshall the reply once we've received all of it */
812 bp = call->buffer;
813 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
814 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
815 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
817 _leave(" = 0 [done]");
818 return 0;
822 * FS.Link operation type
824 static const struct afs_call_type afs_RXFSLink = {
825 .name = "FS.Link",
826 .deliver = afs_deliver_fs_link,
827 .abort_to_error = afs_abort_to_error,
828 .destructor = afs_flat_call_destructor,
832 * make a hard link
834 int afs_fs_link(struct afs_server *server,
835 struct key *key,
836 struct afs_vnode *dvnode,
837 struct afs_vnode *vnode,
838 const char *name,
839 const struct afs_wait_mode *wait_mode)
841 struct afs_call *call;
842 size_t namesz, reqsz, padsz;
843 __be32 *bp;
845 _enter("");
847 namesz = strlen(name);
848 padsz = (4 - (namesz & 3)) & 3;
849 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
851 call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
852 if (!call)
853 return -ENOMEM;
855 call->key = key;
856 call->reply = dvnode;
857 call->reply2 = vnode;
858 call->service_id = FS_SERVICE;
859 call->port = htons(AFS_FS_PORT);
861 /* marshall the parameters */
862 bp = call->request;
863 *bp++ = htonl(FSLINK);
864 *bp++ = htonl(dvnode->fid.vid);
865 *bp++ = htonl(dvnode->fid.vnode);
866 *bp++ = htonl(dvnode->fid.unique);
867 *bp++ = htonl(namesz);
868 memcpy(bp, name, namesz);
869 bp = (void *) bp + namesz;
870 if (padsz > 0) {
871 memset(bp, 0, padsz);
872 bp = (void *) bp + padsz;
874 *bp++ = htonl(vnode->fid.vid);
875 *bp++ = htonl(vnode->fid.vnode);
876 *bp++ = htonl(vnode->fid.unique);
878 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
882 * deliver reply data to an FS.Symlink
884 static int afs_deliver_fs_symlink(struct afs_call *call,
885 struct sk_buff *skb, bool last)
887 struct afs_vnode *vnode = call->reply;
888 const __be32 *bp;
890 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
892 afs_transfer_reply(call, skb);
893 if (!last)
894 return 0;
896 if (call->reply_size != call->reply_max)
897 return -EBADMSG;
899 /* unmarshall the reply once we've received all of it */
900 bp = call->buffer;
901 xdr_decode_AFSFid(&bp, call->reply2);
902 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
903 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
904 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
906 _leave(" = 0 [done]");
907 return 0;
911 * FS.Symlink operation type
913 static const struct afs_call_type afs_RXFSSymlink = {
914 .name = "FS.Symlink",
915 .deliver = afs_deliver_fs_symlink,
916 .abort_to_error = afs_abort_to_error,
917 .destructor = afs_flat_call_destructor,
921 * create a symbolic link
923 int afs_fs_symlink(struct afs_server *server,
924 struct key *key,
925 struct afs_vnode *vnode,
926 const char *name,
927 const char *contents,
928 struct afs_fid *newfid,
929 struct afs_file_status *newstatus,
930 const struct afs_wait_mode *wait_mode)
932 struct afs_call *call;
933 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
934 __be32 *bp;
936 _enter("");
938 namesz = strlen(name);
939 padsz = (4 - (namesz & 3)) & 3;
941 c_namesz = strlen(contents);
942 c_padsz = (4 - (c_namesz & 3)) & 3;
944 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
946 call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
947 (3 + 21 + 21 + 6) * 4);
948 if (!call)
949 return -ENOMEM;
951 call->key = key;
952 call->reply = vnode;
953 call->reply2 = newfid;
954 call->reply3 = newstatus;
955 call->service_id = FS_SERVICE;
956 call->port = htons(AFS_FS_PORT);
958 /* marshall the parameters */
959 bp = call->request;
960 *bp++ = htonl(FSSYMLINK);
961 *bp++ = htonl(vnode->fid.vid);
962 *bp++ = htonl(vnode->fid.vnode);
963 *bp++ = htonl(vnode->fid.unique);
964 *bp++ = htonl(namesz);
965 memcpy(bp, name, namesz);
966 bp = (void *) bp + namesz;
967 if (padsz > 0) {
968 memset(bp, 0, padsz);
969 bp = (void *) bp + padsz;
971 *bp++ = htonl(c_namesz);
972 memcpy(bp, contents, c_namesz);
973 bp = (void *) bp + c_namesz;
974 if (c_padsz > 0) {
975 memset(bp, 0, c_padsz);
976 bp = (void *) bp + c_padsz;
978 *bp++ = htonl(AFS_SET_MODE);
979 *bp++ = 0; /* mtime */
980 *bp++ = 0; /* owner */
981 *bp++ = 0; /* group */
982 *bp++ = htonl(S_IRWXUGO); /* unix mode */
983 *bp++ = 0; /* segment size */
985 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
989 * deliver reply data to an FS.Rename
991 static int afs_deliver_fs_rename(struct afs_call *call,
992 struct sk_buff *skb, bool last)
994 struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
995 const __be32 *bp;
997 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
999 afs_transfer_reply(call, skb);
1000 if (!last)
1001 return 0;
1003 if (call->reply_size != call->reply_max)
1004 return -EBADMSG;
1006 /* unmarshall the reply once we've received all of it */
1007 bp = call->buffer;
1008 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
1009 if (new_dvnode != orig_dvnode)
1010 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
1011 NULL);
1012 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1014 _leave(" = 0 [done]");
1015 return 0;
1019 * FS.Rename operation type
1021 static const struct afs_call_type afs_RXFSRename = {
1022 .name = "FS.Rename",
1023 .deliver = afs_deliver_fs_rename,
1024 .abort_to_error = afs_abort_to_error,
1025 .destructor = afs_flat_call_destructor,
1029 * create a symbolic link
1031 int afs_fs_rename(struct afs_server *server,
1032 struct key *key,
1033 struct afs_vnode *orig_dvnode,
1034 const char *orig_name,
1035 struct afs_vnode *new_dvnode,
1036 const char *new_name,
1037 const struct afs_wait_mode *wait_mode)
1039 struct afs_call *call;
1040 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1041 __be32 *bp;
1043 _enter("");
1045 o_namesz = strlen(orig_name);
1046 o_padsz = (4 - (o_namesz & 3)) & 3;
1048 n_namesz = strlen(new_name);
1049 n_padsz = (4 - (n_namesz & 3)) & 3;
1051 reqsz = (4 * 4) +
1052 4 + o_namesz + o_padsz +
1053 (3 * 4) +
1054 4 + n_namesz + n_padsz;
1056 call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1057 if (!call)
1058 return -ENOMEM;
1060 call->key = key;
1061 call->reply = orig_dvnode;
1062 call->reply2 = new_dvnode;
1063 call->service_id = FS_SERVICE;
1064 call->port = htons(AFS_FS_PORT);
1066 /* marshall the parameters */
1067 bp = call->request;
1068 *bp++ = htonl(FSRENAME);
1069 *bp++ = htonl(orig_dvnode->fid.vid);
1070 *bp++ = htonl(orig_dvnode->fid.vnode);
1071 *bp++ = htonl(orig_dvnode->fid.unique);
1072 *bp++ = htonl(o_namesz);
1073 memcpy(bp, orig_name, o_namesz);
1074 bp = (void *) bp + o_namesz;
1075 if (o_padsz > 0) {
1076 memset(bp, 0, o_padsz);
1077 bp = (void *) bp + o_padsz;
1080 *bp++ = htonl(new_dvnode->fid.vid);
1081 *bp++ = htonl(new_dvnode->fid.vnode);
1082 *bp++ = htonl(new_dvnode->fid.unique);
1083 *bp++ = htonl(n_namesz);
1084 memcpy(bp, new_name, n_namesz);
1085 bp = (void *) bp + n_namesz;
1086 if (n_padsz > 0) {
1087 memset(bp, 0, n_padsz);
1088 bp = (void *) bp + n_padsz;
1091 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1095 * deliver reply data to an FS.StoreData
1097 static int afs_deliver_fs_store_data(struct afs_call *call,
1098 struct sk_buff *skb, bool last)
1100 struct afs_vnode *vnode = call->reply;
1101 const __be32 *bp;
1103 _enter(",,%u", last);
1105 afs_transfer_reply(call, skb);
1106 if (!last) {
1107 _leave(" = 0 [more]");
1108 return 0;
1111 if (call->reply_size != call->reply_max) {
1112 _leave(" = -EBADMSG [%u != %u]",
1113 call->reply_size, call->reply_max);
1114 return -EBADMSG;
1117 /* unmarshall the reply once we've received all of it */
1118 bp = call->buffer;
1119 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1120 &call->store_version);
1121 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1123 afs_pages_written_back(vnode, call);
1125 _leave(" = 0 [done]");
1126 return 0;
1130 * FS.StoreData operation type
1132 static const struct afs_call_type afs_RXFSStoreData = {
1133 .name = "FS.StoreData",
1134 .deliver = afs_deliver_fs_store_data,
1135 .abort_to_error = afs_abort_to_error,
1136 .destructor = afs_flat_call_destructor,
1139 static const struct afs_call_type afs_RXFSStoreData64 = {
1140 .name = "FS.StoreData64",
1141 .deliver = afs_deliver_fs_store_data,
1142 .abort_to_error = afs_abort_to_error,
1143 .destructor = afs_flat_call_destructor,
1147 * store a set of pages to a very large file
1149 static int afs_fs_store_data64(struct afs_server *server,
1150 struct afs_writeback *wb,
1151 pgoff_t first, pgoff_t last,
1152 unsigned offset, unsigned to,
1153 loff_t size, loff_t pos, loff_t i_size,
1154 const struct afs_wait_mode *wait_mode)
1156 struct afs_vnode *vnode = wb->vnode;
1157 struct afs_call *call;
1158 __be32 *bp;
1160 _enter(",%x,{%x:%u},,",
1161 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1163 call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1164 (4 + 6 + 3 * 2) * 4,
1165 (21 + 6) * 4);
1166 if (!call)
1167 return -ENOMEM;
1169 call->wb = wb;
1170 call->key = wb->key;
1171 call->reply = vnode;
1172 call->service_id = FS_SERVICE;
1173 call->port = htons(AFS_FS_PORT);
1174 call->mapping = vnode->vfs_inode.i_mapping;
1175 call->first = first;
1176 call->last = last;
1177 call->first_offset = offset;
1178 call->last_to = to;
1179 call->send_pages = true;
1180 call->store_version = vnode->status.data_version + 1;
1182 /* marshall the parameters */
1183 bp = call->request;
1184 *bp++ = htonl(FSSTOREDATA64);
1185 *bp++ = htonl(vnode->fid.vid);
1186 *bp++ = htonl(vnode->fid.vnode);
1187 *bp++ = htonl(vnode->fid.unique);
1189 *bp++ = 0; /* mask */
1190 *bp++ = 0; /* mtime */
1191 *bp++ = 0; /* owner */
1192 *bp++ = 0; /* group */
1193 *bp++ = 0; /* unix mode */
1194 *bp++ = 0; /* segment size */
1196 *bp++ = htonl(pos >> 32);
1197 *bp++ = htonl((u32) pos);
1198 *bp++ = htonl(size >> 32);
1199 *bp++ = htonl((u32) size);
1200 *bp++ = htonl(i_size >> 32);
1201 *bp++ = htonl((u32) i_size);
1203 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1207 * store a set of pages
1209 int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1210 pgoff_t first, pgoff_t last,
1211 unsigned offset, unsigned to,
1212 const struct afs_wait_mode *wait_mode)
1214 struct afs_vnode *vnode = wb->vnode;
1215 struct afs_call *call;
1216 loff_t size, pos, i_size;
1217 __be32 *bp;
1219 _enter(",%x,{%x:%u},,",
1220 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1222 size = to - offset;
1223 if (first != last)
1224 size += (loff_t)(last - first) << PAGE_SHIFT;
1225 pos = (loff_t)first << PAGE_SHIFT;
1226 pos += offset;
1228 i_size = i_size_read(&vnode->vfs_inode);
1229 if (pos + size > i_size)
1230 i_size = size + pos;
1232 _debug("size %llx, at %llx, i_size %llx",
1233 (unsigned long long) size, (unsigned long long) pos,
1234 (unsigned long long) i_size);
1236 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1237 return afs_fs_store_data64(server, wb, first, last, offset, to,
1238 size, pos, i_size, wait_mode);
1240 call = afs_alloc_flat_call(&afs_RXFSStoreData,
1241 (4 + 6 + 3) * 4,
1242 (21 + 6) * 4);
1243 if (!call)
1244 return -ENOMEM;
1246 call->wb = wb;
1247 call->key = wb->key;
1248 call->reply = vnode;
1249 call->service_id = FS_SERVICE;
1250 call->port = htons(AFS_FS_PORT);
1251 call->mapping = vnode->vfs_inode.i_mapping;
1252 call->first = first;
1253 call->last = last;
1254 call->first_offset = offset;
1255 call->last_to = to;
1256 call->send_pages = true;
1257 call->store_version = vnode->status.data_version + 1;
1259 /* marshall the parameters */
1260 bp = call->request;
1261 *bp++ = htonl(FSSTOREDATA);
1262 *bp++ = htonl(vnode->fid.vid);
1263 *bp++ = htonl(vnode->fid.vnode);
1264 *bp++ = htonl(vnode->fid.unique);
1266 *bp++ = 0; /* mask */
1267 *bp++ = 0; /* mtime */
1268 *bp++ = 0; /* owner */
1269 *bp++ = 0; /* group */
1270 *bp++ = 0; /* unix mode */
1271 *bp++ = 0; /* segment size */
1273 *bp++ = htonl(pos);
1274 *bp++ = htonl(size);
1275 *bp++ = htonl(i_size);
1277 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1281 * deliver reply data to an FS.StoreStatus
1283 static int afs_deliver_fs_store_status(struct afs_call *call,
1284 struct sk_buff *skb, bool last)
1286 afs_dataversion_t *store_version;
1287 struct afs_vnode *vnode = call->reply;
1288 const __be32 *bp;
1290 _enter(",,%u", last);
1292 afs_transfer_reply(call, skb);
1293 if (!last) {
1294 _leave(" = 0 [more]");
1295 return 0;
1298 if (call->reply_size != call->reply_max) {
1299 _leave(" = -EBADMSG [%u != %u]",
1300 call->reply_size, call->reply_max);
1301 return -EBADMSG;
1304 /* unmarshall the reply once we've received all of it */
1305 store_version = NULL;
1306 if (call->operation_ID == FSSTOREDATA)
1307 store_version = &call->store_version;
1309 bp = call->buffer;
1310 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1311 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1313 _leave(" = 0 [done]");
1314 return 0;
1318 * FS.StoreStatus operation type
1320 static const struct afs_call_type afs_RXFSStoreStatus = {
1321 .name = "FS.StoreStatus",
1322 .deliver = afs_deliver_fs_store_status,
1323 .abort_to_error = afs_abort_to_error,
1324 .destructor = afs_flat_call_destructor,
1327 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1328 .name = "FS.StoreData",
1329 .deliver = afs_deliver_fs_store_status,
1330 .abort_to_error = afs_abort_to_error,
1331 .destructor = afs_flat_call_destructor,
1334 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1335 .name = "FS.StoreData64",
1336 .deliver = afs_deliver_fs_store_status,
1337 .abort_to_error = afs_abort_to_error,
1338 .destructor = afs_flat_call_destructor,
1342 * set the attributes on a very large file, using FS.StoreData rather than
1343 * FS.StoreStatus so as to alter the file size also
1345 static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,
1346 struct afs_vnode *vnode, struct iattr *attr,
1347 const struct afs_wait_mode *wait_mode)
1349 struct afs_call *call;
1350 __be32 *bp;
1352 _enter(",%x,{%x:%u},,",
1353 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1355 ASSERT(attr->ia_valid & ATTR_SIZE);
1357 call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,
1358 (4 + 6 + 3 * 2) * 4,
1359 (21 + 6) * 4);
1360 if (!call)
1361 return -ENOMEM;
1363 call->key = key;
1364 call->reply = vnode;
1365 call->service_id = FS_SERVICE;
1366 call->port = htons(AFS_FS_PORT);
1367 call->store_version = vnode->status.data_version + 1;
1368 call->operation_ID = FSSTOREDATA;
1370 /* marshall the parameters */
1371 bp = call->request;
1372 *bp++ = htonl(FSSTOREDATA64);
1373 *bp++ = htonl(vnode->fid.vid);
1374 *bp++ = htonl(vnode->fid.vnode);
1375 *bp++ = htonl(vnode->fid.unique);
1377 xdr_encode_AFS_StoreStatus(&bp, attr);
1379 *bp++ = 0; /* position of start of write */
1380 *bp++ = 0;
1381 *bp++ = 0; /* size of write */
1382 *bp++ = 0;
1383 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1384 *bp++ = htonl((u32) attr->ia_size);
1386 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1390 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1391 * so as to alter the file size also
1393 static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1394 struct afs_vnode *vnode, struct iattr *attr,
1395 const struct afs_wait_mode *wait_mode)
1397 struct afs_call *call;
1398 __be32 *bp;
1400 _enter(",%x,{%x:%u},,",
1401 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1403 ASSERT(attr->ia_valid & ATTR_SIZE);
1404 if (attr->ia_size >> 32)
1405 return afs_fs_setattr_size64(server, key, vnode, attr,
1406 wait_mode);
1408 call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1409 (4 + 6 + 3) * 4,
1410 (21 + 6) * 4);
1411 if (!call)
1412 return -ENOMEM;
1414 call->key = key;
1415 call->reply = vnode;
1416 call->service_id = FS_SERVICE;
1417 call->port = htons(AFS_FS_PORT);
1418 call->store_version = vnode->status.data_version + 1;
1419 call->operation_ID = FSSTOREDATA;
1421 /* marshall the parameters */
1422 bp = call->request;
1423 *bp++ = htonl(FSSTOREDATA);
1424 *bp++ = htonl(vnode->fid.vid);
1425 *bp++ = htonl(vnode->fid.vnode);
1426 *bp++ = htonl(vnode->fid.unique);
1428 xdr_encode_AFS_StoreStatus(&bp, attr);
1430 *bp++ = 0; /* position of start of write */
1431 *bp++ = 0; /* size of write */
1432 *bp++ = htonl(attr->ia_size); /* new file length */
1434 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1438 * set the attributes on a file, using FS.StoreData if there's a change in file
1439 * size, and FS.StoreStatus otherwise
1441 int afs_fs_setattr(struct afs_server *server, struct key *key,
1442 struct afs_vnode *vnode, struct iattr *attr,
1443 const struct afs_wait_mode *wait_mode)
1445 struct afs_call *call;
1446 __be32 *bp;
1448 if (attr->ia_valid & ATTR_SIZE)
1449 return afs_fs_setattr_size(server, key, vnode, attr,
1450 wait_mode);
1452 _enter(",%x,{%x:%u},,",
1453 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1455 call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1456 (4 + 6) * 4,
1457 (21 + 6) * 4);
1458 if (!call)
1459 return -ENOMEM;
1461 call->key = key;
1462 call->reply = vnode;
1463 call->service_id = FS_SERVICE;
1464 call->port = htons(AFS_FS_PORT);
1465 call->operation_ID = FSSTORESTATUS;
1467 /* marshall the parameters */
1468 bp = call->request;
1469 *bp++ = htonl(FSSTORESTATUS);
1470 *bp++ = htonl(vnode->fid.vid);
1471 *bp++ = htonl(vnode->fid.vnode);
1472 *bp++ = htonl(vnode->fid.unique);
1474 xdr_encode_AFS_StoreStatus(&bp, attr);
1476 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1480 * deliver reply data to an FS.GetVolumeStatus
1482 static int afs_deliver_fs_get_volume_status(struct afs_call *call,
1483 struct sk_buff *skb, bool last)
1485 const __be32 *bp;
1486 char *p;
1487 int ret;
1489 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1491 switch (call->unmarshall) {
1492 case 0:
1493 call->offset = 0;
1494 call->unmarshall++;
1496 /* extract the returned status record */
1497 case 1:
1498 _debug("extract status");
1499 ret = afs_extract_data(call, skb, last, call->buffer,
1500 12 * 4);
1501 switch (ret) {
1502 case 0: break;
1503 case -EAGAIN: return 0;
1504 default: return ret;
1507 bp = call->buffer;
1508 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
1509 call->offset = 0;
1510 call->unmarshall++;
1512 /* extract the volume name length */
1513 case 2:
1514 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1515 switch (ret) {
1516 case 0: break;
1517 case -EAGAIN: return 0;
1518 default: return ret;
1521 call->count = ntohl(call->tmp);
1522 _debug("volname length: %u", call->count);
1523 if (call->count >= AFSNAMEMAX)
1524 return -EBADMSG;
1525 call->offset = 0;
1526 call->unmarshall++;
1528 /* extract the volume name */
1529 case 3:
1530 _debug("extract volname");
1531 if (call->count > 0) {
1532 ret = afs_extract_data(call, skb, last, call->reply3,
1533 call->count);
1534 switch (ret) {
1535 case 0: break;
1536 case -EAGAIN: return 0;
1537 default: return ret;
1541 p = call->reply3;
1542 p[call->count] = 0;
1543 _debug("volname '%s'", p);
1545 call->offset = 0;
1546 call->unmarshall++;
1548 /* extract the volume name padding */
1549 if ((call->count & 3) == 0) {
1550 call->unmarshall++;
1551 goto no_volname_padding;
1553 call->count = 4 - (call->count & 3);
1555 case 4:
1556 ret = afs_extract_data(call, skb, last, call->buffer,
1557 call->count);
1558 switch (ret) {
1559 case 0: break;
1560 case -EAGAIN: return 0;
1561 default: return ret;
1564 call->offset = 0;
1565 call->unmarshall++;
1566 no_volname_padding:
1568 /* extract the offline message length */
1569 case 5:
1570 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1571 switch (ret) {
1572 case 0: break;
1573 case -EAGAIN: return 0;
1574 default: return ret;
1577 call->count = ntohl(call->tmp);
1578 _debug("offline msg length: %u", call->count);
1579 if (call->count >= AFSNAMEMAX)
1580 return -EBADMSG;
1581 call->offset = 0;
1582 call->unmarshall++;
1584 /* extract the offline message */
1585 case 6:
1586 _debug("extract offline");
1587 if (call->count > 0) {
1588 ret = afs_extract_data(call, skb, last, call->reply3,
1589 call->count);
1590 switch (ret) {
1591 case 0: break;
1592 case -EAGAIN: return 0;
1593 default: return ret;
1597 p = call->reply3;
1598 p[call->count] = 0;
1599 _debug("offline '%s'", p);
1601 call->offset = 0;
1602 call->unmarshall++;
1604 /* extract the offline message padding */
1605 if ((call->count & 3) == 0) {
1606 call->unmarshall++;
1607 goto no_offline_padding;
1609 call->count = 4 - (call->count & 3);
1611 case 7:
1612 ret = afs_extract_data(call, skb, last, call->buffer,
1613 call->count);
1614 switch (ret) {
1615 case 0: break;
1616 case -EAGAIN: return 0;
1617 default: return ret;
1620 call->offset = 0;
1621 call->unmarshall++;
1622 no_offline_padding:
1624 /* extract the message of the day length */
1625 case 8:
1626 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1627 switch (ret) {
1628 case 0: break;
1629 case -EAGAIN: return 0;
1630 default: return ret;
1633 call->count = ntohl(call->tmp);
1634 _debug("motd length: %u", call->count);
1635 if (call->count >= AFSNAMEMAX)
1636 return -EBADMSG;
1637 call->offset = 0;
1638 call->unmarshall++;
1640 /* extract the message of the day */
1641 case 9:
1642 _debug("extract motd");
1643 if (call->count > 0) {
1644 ret = afs_extract_data(call, skb, last, call->reply3,
1645 call->count);
1646 switch (ret) {
1647 case 0: break;
1648 case -EAGAIN: return 0;
1649 default: return ret;
1653 p = call->reply3;
1654 p[call->count] = 0;
1655 _debug("motd '%s'", p);
1657 call->offset = 0;
1658 call->unmarshall++;
1660 /* extract the message of the day padding */
1661 if ((call->count & 3) == 0) {
1662 call->unmarshall++;
1663 goto no_motd_padding;
1665 call->count = 4 - (call->count & 3);
1667 case 10:
1668 ret = afs_extract_data(call, skb, last, call->buffer,
1669 call->count);
1670 switch (ret) {
1671 case 0: break;
1672 case -EAGAIN: return 0;
1673 default: return ret;
1676 call->offset = 0;
1677 call->unmarshall++;
1678 no_motd_padding:
1680 case 11:
1681 _debug("trailer %d", skb->len);
1682 if (skb->len != 0)
1683 return -EBADMSG;
1684 break;
1687 if (!last)
1688 return 0;
1690 _leave(" = 0 [done]");
1691 return 0;
1695 * destroy an FS.GetVolumeStatus call
1697 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1699 kfree(call->reply3);
1700 call->reply3 = NULL;
1701 afs_flat_call_destructor(call);
1705 * FS.GetVolumeStatus operation type
1707 static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1708 .name = "FS.GetVolumeStatus",
1709 .deliver = afs_deliver_fs_get_volume_status,
1710 .abort_to_error = afs_abort_to_error,
1711 .destructor = afs_get_volume_status_call_destructor,
1715 * fetch the status of a volume
1717 int afs_fs_get_volume_status(struct afs_server *server,
1718 struct key *key,
1719 struct afs_vnode *vnode,
1720 struct afs_volume_status *vs,
1721 const struct afs_wait_mode *wait_mode)
1723 struct afs_call *call;
1724 __be32 *bp;
1725 void *tmpbuf;
1727 _enter("");
1729 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1730 if (!tmpbuf)
1731 return -ENOMEM;
1733 call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1734 if (!call) {
1735 kfree(tmpbuf);
1736 return -ENOMEM;
1739 call->key = key;
1740 call->reply = vnode;
1741 call->reply2 = vs;
1742 call->reply3 = tmpbuf;
1743 call->service_id = FS_SERVICE;
1744 call->port = htons(AFS_FS_PORT);
1746 /* marshall the parameters */
1747 bp = call->request;
1748 bp[0] = htonl(FSGETVOLUMESTATUS);
1749 bp[1] = htonl(vnode->fid.vid);
1751 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1755 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1757 static int afs_deliver_fs_xxxx_lock(struct afs_call *call,
1758 struct sk_buff *skb, bool last)
1760 const __be32 *bp;
1762 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1764 afs_transfer_reply(call, skb);
1765 if (!last)
1766 return 0;
1768 if (call->reply_size != call->reply_max)
1769 return -EBADMSG;
1771 /* unmarshall the reply once we've received all of it */
1772 bp = call->buffer;
1773 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1775 _leave(" = 0 [done]");
1776 return 0;
1780 * FS.SetLock operation type
1782 static const struct afs_call_type afs_RXFSSetLock = {
1783 .name = "FS.SetLock",
1784 .deliver = afs_deliver_fs_xxxx_lock,
1785 .abort_to_error = afs_abort_to_error,
1786 .destructor = afs_flat_call_destructor,
1790 * FS.ExtendLock operation type
1792 static const struct afs_call_type afs_RXFSExtendLock = {
1793 .name = "FS.ExtendLock",
1794 .deliver = afs_deliver_fs_xxxx_lock,
1795 .abort_to_error = afs_abort_to_error,
1796 .destructor = afs_flat_call_destructor,
1800 * FS.ReleaseLock operation type
1802 static const struct afs_call_type afs_RXFSReleaseLock = {
1803 .name = "FS.ReleaseLock",
1804 .deliver = afs_deliver_fs_xxxx_lock,
1805 .abort_to_error = afs_abort_to_error,
1806 .destructor = afs_flat_call_destructor,
1810 * get a lock on a file
1812 int afs_fs_set_lock(struct afs_server *server,
1813 struct key *key,
1814 struct afs_vnode *vnode,
1815 afs_lock_type_t type,
1816 const struct afs_wait_mode *wait_mode)
1818 struct afs_call *call;
1819 __be32 *bp;
1821 _enter("");
1823 call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);
1824 if (!call)
1825 return -ENOMEM;
1827 call->key = key;
1828 call->reply = vnode;
1829 call->service_id = FS_SERVICE;
1830 call->port = htons(AFS_FS_PORT);
1832 /* marshall the parameters */
1833 bp = call->request;
1834 *bp++ = htonl(FSSETLOCK);
1835 *bp++ = htonl(vnode->fid.vid);
1836 *bp++ = htonl(vnode->fid.vnode);
1837 *bp++ = htonl(vnode->fid.unique);
1838 *bp++ = htonl(type);
1840 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1844 * extend a lock on a file
1846 int afs_fs_extend_lock(struct afs_server *server,
1847 struct key *key,
1848 struct afs_vnode *vnode,
1849 const struct afs_wait_mode *wait_mode)
1851 struct afs_call *call;
1852 __be32 *bp;
1854 _enter("");
1856 call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);
1857 if (!call)
1858 return -ENOMEM;
1860 call->key = key;
1861 call->reply = vnode;
1862 call->service_id = FS_SERVICE;
1863 call->port = htons(AFS_FS_PORT);
1865 /* marshall the parameters */
1866 bp = call->request;
1867 *bp++ = htonl(FSEXTENDLOCK);
1868 *bp++ = htonl(vnode->fid.vid);
1869 *bp++ = htonl(vnode->fid.vnode);
1870 *bp++ = htonl(vnode->fid.unique);
1872 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1876 * release a lock on a file
1878 int afs_fs_release_lock(struct afs_server *server,
1879 struct key *key,
1880 struct afs_vnode *vnode,
1881 const struct afs_wait_mode *wait_mode)
1883 struct afs_call *call;
1884 __be32 *bp;
1886 _enter("");
1888 call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1889 if (!call)
1890 return -ENOMEM;
1892 call->key = key;
1893 call->reply = vnode;
1894 call->service_id = FS_SERVICE;
1895 call->port = htons(AFS_FS_PORT);
1897 /* marshall the parameters */
1898 bp = call->request;
1899 *bp++ = htonl(FSRELEASELOCK);
1900 *bp++ = htonl(vnode->fid.vid);
1901 *bp++ = htonl(vnode->fid.vnode);
1902 *bp++ = htonl(vnode->fid.unique);
1904 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);