AFS: write support fixes
[linux-2.6/mini2440.git] / fs / afs / fsclient.c
blob56cc0efa2a0c06d0ffbd8552a2dfab59b9631630
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 bp++; /* 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 * deliver reply data to an FS.FetchStatus
207 static int afs_deliver_fs_fetch_status(struct afs_call *call,
208 struct sk_buff *skb, bool last)
210 struct afs_vnode *vnode = call->reply;
211 const __be32 *bp;
213 _enter(",,%u", last);
215 afs_transfer_reply(call, skb);
216 if (!last)
217 return 0;
219 if (call->reply_size != call->reply_max)
220 return -EBADMSG;
222 /* unmarshall the reply once we've received all of it */
223 bp = call->buffer;
224 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
225 xdr_decode_AFSCallBack(&bp, vnode);
226 if (call->reply2)
227 xdr_decode_AFSVolSync(&bp, call->reply2);
229 _leave(" = 0 [done]");
230 return 0;
234 * FS.FetchStatus operation type
236 static const struct afs_call_type afs_RXFSFetchStatus = {
237 .name = "FS.FetchStatus",
238 .deliver = afs_deliver_fs_fetch_status,
239 .abort_to_error = afs_abort_to_error,
240 .destructor = afs_flat_call_destructor,
244 * fetch the status information for a file
246 int afs_fs_fetch_file_status(struct afs_server *server,
247 struct key *key,
248 struct afs_vnode *vnode,
249 struct afs_volsync *volsync,
250 const struct afs_wait_mode *wait_mode)
252 struct afs_call *call;
253 __be32 *bp;
255 _enter(",%x,{%x:%u},,",
256 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
258 call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
259 if (!call)
260 return -ENOMEM;
262 call->key = key;
263 call->reply = vnode;
264 call->reply2 = volsync;
265 call->service_id = FS_SERVICE;
266 call->port = htons(AFS_FS_PORT);
268 /* marshall the parameters */
269 bp = call->request;
270 bp[0] = htonl(FSFETCHSTATUS);
271 bp[1] = htonl(vnode->fid.vid);
272 bp[2] = htonl(vnode->fid.vnode);
273 bp[3] = htonl(vnode->fid.unique);
275 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
279 * deliver reply data to an FS.FetchData
281 static int afs_deliver_fs_fetch_data(struct afs_call *call,
282 struct sk_buff *skb, bool last)
284 struct afs_vnode *vnode = call->reply;
285 const __be32 *bp;
286 struct page *page;
287 void *buffer;
288 int ret;
290 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
292 switch (call->unmarshall) {
293 case 0:
294 call->offset = 0;
295 call->unmarshall++;
296 if (call->operation_ID != FSFETCHDATA64) {
297 call->unmarshall++;
298 goto no_msw;
301 /* extract the upper part of the returned data length of an
302 * FSFETCHDATA64 op (which should always be 0 using this
303 * client) */
304 case 1:
305 _debug("extract data length (MSW)");
306 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
307 switch (ret) {
308 case 0: break;
309 case -EAGAIN: return 0;
310 default: return ret;
313 call->count = ntohl(call->tmp);
314 _debug("DATA length MSW: %u", call->count);
315 if (call->count > 0)
316 return -EBADMSG;
317 call->offset = 0;
318 call->unmarshall++;
320 no_msw:
321 /* extract the returned data length */
322 case 2:
323 _debug("extract data length");
324 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
325 switch (ret) {
326 case 0: break;
327 case -EAGAIN: return 0;
328 default: return ret;
331 call->count = ntohl(call->tmp);
332 _debug("DATA length: %u", call->count);
333 if (call->count > PAGE_SIZE)
334 return -EBADMSG;
335 call->offset = 0;
336 call->unmarshall++;
338 /* extract the returned data */
339 case 3:
340 _debug("extract data");
341 if (call->count > 0) {
342 page = call->reply3;
343 buffer = kmap_atomic(page, KM_USER0);
344 ret = afs_extract_data(call, skb, last, buffer,
345 call->count);
346 kunmap_atomic(buffer, KM_USER0);
347 switch (ret) {
348 case 0: break;
349 case -EAGAIN: return 0;
350 default: return ret;
354 call->offset = 0;
355 call->unmarshall++;
357 /* extract the metadata */
358 case 4:
359 ret = afs_extract_data(call, skb, last, call->buffer,
360 (21 + 3 + 6) * 4);
361 switch (ret) {
362 case 0: break;
363 case -EAGAIN: return 0;
364 default: return ret;
367 bp = call->buffer;
368 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
369 xdr_decode_AFSCallBack(&bp, vnode);
370 if (call->reply2)
371 xdr_decode_AFSVolSync(&bp, call->reply2);
373 call->offset = 0;
374 call->unmarshall++;
376 case 5:
377 _debug("trailer");
378 if (skb->len != 0)
379 return -EBADMSG;
380 break;
383 if (!last)
384 return 0;
386 if (call->count < PAGE_SIZE) {
387 _debug("clear");
388 page = call->reply3;
389 buffer = kmap_atomic(page, KM_USER0);
390 memset(buffer + call->count, 0, PAGE_SIZE - call->count);
391 kunmap_atomic(buffer, KM_USER0);
394 _leave(" = 0 [done]");
395 return 0;
399 * FS.FetchData operation type
401 static const struct afs_call_type afs_RXFSFetchData = {
402 .name = "FS.FetchData",
403 .deliver = afs_deliver_fs_fetch_data,
404 .abort_to_error = afs_abort_to_error,
405 .destructor = afs_flat_call_destructor,
408 static const struct afs_call_type afs_RXFSFetchData64 = {
409 .name = "FS.FetchData64",
410 .deliver = afs_deliver_fs_fetch_data,
411 .abort_to_error = afs_abort_to_error,
412 .destructor = afs_flat_call_destructor,
416 * fetch data from a very large file
418 static int afs_fs_fetch_data64(struct afs_server *server,
419 struct key *key,
420 struct afs_vnode *vnode,
421 off_t offset, size_t length,
422 struct page *buffer,
423 const struct afs_wait_mode *wait_mode)
425 struct afs_call *call;
426 __be32 *bp;
428 _enter("");
430 ASSERTCMP(length, <, ULONG_MAX);
432 call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
433 if (!call)
434 return -ENOMEM;
436 call->key = key;
437 call->reply = vnode;
438 call->reply2 = NULL; /* volsync */
439 call->reply3 = buffer;
440 call->service_id = FS_SERVICE;
441 call->port = htons(AFS_FS_PORT);
442 call->operation_ID = FSFETCHDATA64;
444 /* marshall the parameters */
445 bp = call->request;
446 bp[0] = htonl(FSFETCHDATA64);
447 bp[1] = htonl(vnode->fid.vid);
448 bp[2] = htonl(vnode->fid.vnode);
449 bp[3] = htonl(vnode->fid.unique);
450 bp[4] = htonl(upper_32_bits(offset));
451 bp[5] = htonl((u32) offset);
452 bp[6] = 0;
453 bp[7] = htonl((u32) length);
455 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
459 * fetch data from a file
461 int afs_fs_fetch_data(struct afs_server *server,
462 struct key *key,
463 struct afs_vnode *vnode,
464 off_t offset, size_t length,
465 struct page *buffer,
466 const struct afs_wait_mode *wait_mode)
468 struct afs_call *call;
469 __be32 *bp;
471 if (upper_32_bits(offset) || upper_32_bits(offset + length))
472 return afs_fs_fetch_data64(server, key, vnode, offset, length,
473 buffer, wait_mode);
475 _enter("");
477 call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
478 if (!call)
479 return -ENOMEM;
481 call->key = key;
482 call->reply = vnode;
483 call->reply2 = NULL; /* volsync */
484 call->reply3 = buffer;
485 call->service_id = FS_SERVICE;
486 call->port = htons(AFS_FS_PORT);
487 call->operation_ID = FSFETCHDATA;
489 /* marshall the parameters */
490 bp = call->request;
491 bp[0] = htonl(FSFETCHDATA);
492 bp[1] = htonl(vnode->fid.vid);
493 bp[2] = htonl(vnode->fid.vnode);
494 bp[3] = htonl(vnode->fid.unique);
495 bp[4] = htonl(offset);
496 bp[5] = htonl(length);
498 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
502 * deliver reply data to an FS.GiveUpCallBacks
504 static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
505 struct sk_buff *skb, bool last)
507 _enter(",{%u},%d", skb->len, last);
509 if (skb->len > 0)
510 return -EBADMSG; /* shouldn't be any reply data */
511 return 0;
515 * FS.GiveUpCallBacks operation type
517 static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
518 .name = "FS.GiveUpCallBacks",
519 .deliver = afs_deliver_fs_give_up_callbacks,
520 .abort_to_error = afs_abort_to_error,
521 .destructor = afs_flat_call_destructor,
525 * give up a set of callbacks
526 * - the callbacks are held in the server->cb_break ring
528 int afs_fs_give_up_callbacks(struct afs_server *server,
529 const struct afs_wait_mode *wait_mode)
531 struct afs_call *call;
532 size_t ncallbacks;
533 __be32 *bp, *tp;
534 int loop;
536 ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
537 ARRAY_SIZE(server->cb_break));
539 _enter("{%zu},", ncallbacks);
541 if (ncallbacks == 0)
542 return 0;
543 if (ncallbacks > AFSCBMAX)
544 ncallbacks = AFSCBMAX;
546 _debug("break %zu callbacks", ncallbacks);
548 call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
549 12 + ncallbacks * 6 * 4, 0);
550 if (!call)
551 return -ENOMEM;
553 call->service_id = FS_SERVICE;
554 call->port = htons(AFS_FS_PORT);
556 /* marshall the parameters */
557 bp = call->request;
558 tp = bp + 2 + ncallbacks * 3;
559 *bp++ = htonl(FSGIVEUPCALLBACKS);
560 *bp++ = htonl(ncallbacks);
561 *tp++ = htonl(ncallbacks);
563 atomic_sub(ncallbacks, &server->cb_break_n);
564 for (loop = ncallbacks; loop > 0; loop--) {
565 struct afs_callback *cb =
566 &server->cb_break[server->cb_break_tail];
568 *bp++ = htonl(cb->fid.vid);
569 *bp++ = htonl(cb->fid.vnode);
570 *bp++ = htonl(cb->fid.unique);
571 *tp++ = htonl(cb->version);
572 *tp++ = htonl(cb->expiry);
573 *tp++ = htonl(cb->type);
574 smp_mb();
575 server->cb_break_tail =
576 (server->cb_break_tail + 1) &
577 (ARRAY_SIZE(server->cb_break) - 1);
580 ASSERT(ncallbacks > 0);
581 wake_up_nr(&server->cb_break_waitq, ncallbacks);
583 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
587 * deliver reply data to an FS.CreateFile or an FS.MakeDir
589 static int afs_deliver_fs_create_vnode(struct afs_call *call,
590 struct sk_buff *skb, bool last)
592 struct afs_vnode *vnode = call->reply;
593 const __be32 *bp;
595 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
597 afs_transfer_reply(call, skb);
598 if (!last)
599 return 0;
601 if (call->reply_size != call->reply_max)
602 return -EBADMSG;
604 /* unmarshall the reply once we've received all of it */
605 bp = call->buffer;
606 xdr_decode_AFSFid(&bp, call->reply2);
607 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
608 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
609 xdr_decode_AFSCallBack_raw(&bp, call->reply4);
610 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
612 _leave(" = 0 [done]");
613 return 0;
617 * FS.CreateFile and FS.MakeDir operation type
619 static const struct afs_call_type afs_RXFSCreateXXXX = {
620 .name = "FS.CreateXXXX",
621 .deliver = afs_deliver_fs_create_vnode,
622 .abort_to_error = afs_abort_to_error,
623 .destructor = afs_flat_call_destructor,
627 * create a file or make a directory
629 int afs_fs_create(struct afs_server *server,
630 struct key *key,
631 struct afs_vnode *vnode,
632 const char *name,
633 umode_t mode,
634 struct afs_fid *newfid,
635 struct afs_file_status *newstatus,
636 struct afs_callback *newcb,
637 const struct afs_wait_mode *wait_mode)
639 struct afs_call *call;
640 size_t namesz, reqsz, padsz;
641 __be32 *bp;
643 _enter("");
645 namesz = strlen(name);
646 padsz = (4 - (namesz & 3)) & 3;
647 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
649 call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
650 (3 + 21 + 21 + 3 + 6) * 4);
651 if (!call)
652 return -ENOMEM;
654 call->key = key;
655 call->reply = vnode;
656 call->reply2 = newfid;
657 call->reply3 = newstatus;
658 call->reply4 = newcb;
659 call->service_id = FS_SERVICE;
660 call->port = htons(AFS_FS_PORT);
662 /* marshall the parameters */
663 bp = call->request;
664 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
665 *bp++ = htonl(vnode->fid.vid);
666 *bp++ = htonl(vnode->fid.vnode);
667 *bp++ = htonl(vnode->fid.unique);
668 *bp++ = htonl(namesz);
669 memcpy(bp, name, namesz);
670 bp = (void *) bp + namesz;
671 if (padsz > 0) {
672 memset(bp, 0, padsz);
673 bp = (void *) bp + padsz;
675 *bp++ = htonl(AFS_SET_MODE);
676 *bp++ = 0; /* mtime */
677 *bp++ = 0; /* owner */
678 *bp++ = 0; /* group */
679 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
680 *bp++ = 0; /* segment size */
682 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
686 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
688 static int afs_deliver_fs_remove(struct afs_call *call,
689 struct sk_buff *skb, bool last)
691 struct afs_vnode *vnode = call->reply;
692 const __be32 *bp;
694 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
696 afs_transfer_reply(call, skb);
697 if (!last)
698 return 0;
700 if (call->reply_size != call->reply_max)
701 return -EBADMSG;
703 /* unmarshall the reply once we've received all of it */
704 bp = call->buffer;
705 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
706 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
708 _leave(" = 0 [done]");
709 return 0;
713 * FS.RemoveDir/FS.RemoveFile operation type
715 static const struct afs_call_type afs_RXFSRemoveXXXX = {
716 .name = "FS.RemoveXXXX",
717 .deliver = afs_deliver_fs_remove,
718 .abort_to_error = afs_abort_to_error,
719 .destructor = afs_flat_call_destructor,
723 * remove a file or directory
725 int afs_fs_remove(struct afs_server *server,
726 struct key *key,
727 struct afs_vnode *vnode,
728 const char *name,
729 bool isdir,
730 const struct afs_wait_mode *wait_mode)
732 struct afs_call *call;
733 size_t namesz, reqsz, padsz;
734 __be32 *bp;
736 _enter("");
738 namesz = strlen(name);
739 padsz = (4 - (namesz & 3)) & 3;
740 reqsz = (5 * 4) + namesz + padsz;
742 call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
743 if (!call)
744 return -ENOMEM;
746 call->key = key;
747 call->reply = vnode;
748 call->service_id = FS_SERVICE;
749 call->port = htons(AFS_FS_PORT);
751 /* marshall the parameters */
752 bp = call->request;
753 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
754 *bp++ = htonl(vnode->fid.vid);
755 *bp++ = htonl(vnode->fid.vnode);
756 *bp++ = htonl(vnode->fid.unique);
757 *bp++ = htonl(namesz);
758 memcpy(bp, name, namesz);
759 bp = (void *) bp + namesz;
760 if (padsz > 0) {
761 memset(bp, 0, padsz);
762 bp = (void *) bp + padsz;
765 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
769 * deliver reply data to an FS.Link
771 static int afs_deliver_fs_link(struct afs_call *call,
772 struct sk_buff *skb, bool last)
774 struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
775 const __be32 *bp;
777 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
779 afs_transfer_reply(call, skb);
780 if (!last)
781 return 0;
783 if (call->reply_size != call->reply_max)
784 return -EBADMSG;
786 /* unmarshall the reply once we've received all of it */
787 bp = call->buffer;
788 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
789 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
790 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
792 _leave(" = 0 [done]");
793 return 0;
797 * FS.Link operation type
799 static const struct afs_call_type afs_RXFSLink = {
800 .name = "FS.Link",
801 .deliver = afs_deliver_fs_link,
802 .abort_to_error = afs_abort_to_error,
803 .destructor = afs_flat_call_destructor,
807 * make a hard link
809 int afs_fs_link(struct afs_server *server,
810 struct key *key,
811 struct afs_vnode *dvnode,
812 struct afs_vnode *vnode,
813 const char *name,
814 const struct afs_wait_mode *wait_mode)
816 struct afs_call *call;
817 size_t namesz, reqsz, padsz;
818 __be32 *bp;
820 _enter("");
822 namesz = strlen(name);
823 padsz = (4 - (namesz & 3)) & 3;
824 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
826 call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
827 if (!call)
828 return -ENOMEM;
830 call->key = key;
831 call->reply = dvnode;
832 call->reply2 = vnode;
833 call->service_id = FS_SERVICE;
834 call->port = htons(AFS_FS_PORT);
836 /* marshall the parameters */
837 bp = call->request;
838 *bp++ = htonl(FSLINK);
839 *bp++ = htonl(dvnode->fid.vid);
840 *bp++ = htonl(dvnode->fid.vnode);
841 *bp++ = htonl(dvnode->fid.unique);
842 *bp++ = htonl(namesz);
843 memcpy(bp, name, namesz);
844 bp = (void *) bp + namesz;
845 if (padsz > 0) {
846 memset(bp, 0, padsz);
847 bp = (void *) bp + padsz;
849 *bp++ = htonl(vnode->fid.vid);
850 *bp++ = htonl(vnode->fid.vnode);
851 *bp++ = htonl(vnode->fid.unique);
853 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
857 * deliver reply data to an FS.Symlink
859 static int afs_deliver_fs_symlink(struct afs_call *call,
860 struct sk_buff *skb, bool last)
862 struct afs_vnode *vnode = call->reply;
863 const __be32 *bp;
865 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
867 afs_transfer_reply(call, skb);
868 if (!last)
869 return 0;
871 if (call->reply_size != call->reply_max)
872 return -EBADMSG;
874 /* unmarshall the reply once we've received all of it */
875 bp = call->buffer;
876 xdr_decode_AFSFid(&bp, call->reply2);
877 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
878 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
879 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
881 _leave(" = 0 [done]");
882 return 0;
886 * FS.Symlink operation type
888 static const struct afs_call_type afs_RXFSSymlink = {
889 .name = "FS.Symlink",
890 .deliver = afs_deliver_fs_symlink,
891 .abort_to_error = afs_abort_to_error,
892 .destructor = afs_flat_call_destructor,
896 * create a symbolic link
898 int afs_fs_symlink(struct afs_server *server,
899 struct key *key,
900 struct afs_vnode *vnode,
901 const char *name,
902 const char *contents,
903 struct afs_fid *newfid,
904 struct afs_file_status *newstatus,
905 const struct afs_wait_mode *wait_mode)
907 struct afs_call *call;
908 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
909 __be32 *bp;
911 _enter("");
913 namesz = strlen(name);
914 padsz = (4 - (namesz & 3)) & 3;
916 c_namesz = strlen(contents);
917 c_padsz = (4 - (c_namesz & 3)) & 3;
919 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
921 call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
922 (3 + 21 + 21 + 6) * 4);
923 if (!call)
924 return -ENOMEM;
926 call->key = key;
927 call->reply = vnode;
928 call->reply2 = newfid;
929 call->reply3 = newstatus;
930 call->service_id = FS_SERVICE;
931 call->port = htons(AFS_FS_PORT);
933 /* marshall the parameters */
934 bp = call->request;
935 *bp++ = htonl(FSSYMLINK);
936 *bp++ = htonl(vnode->fid.vid);
937 *bp++ = htonl(vnode->fid.vnode);
938 *bp++ = htonl(vnode->fid.unique);
939 *bp++ = htonl(namesz);
940 memcpy(bp, name, namesz);
941 bp = (void *) bp + namesz;
942 if (padsz > 0) {
943 memset(bp, 0, padsz);
944 bp = (void *) bp + padsz;
946 *bp++ = htonl(c_namesz);
947 memcpy(bp, contents, c_namesz);
948 bp = (void *) bp + c_namesz;
949 if (c_padsz > 0) {
950 memset(bp, 0, c_padsz);
951 bp = (void *) bp + c_padsz;
953 *bp++ = htonl(AFS_SET_MODE);
954 *bp++ = 0; /* mtime */
955 *bp++ = 0; /* owner */
956 *bp++ = 0; /* group */
957 *bp++ = htonl(S_IRWXUGO); /* unix mode */
958 *bp++ = 0; /* segment size */
960 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
964 * deliver reply data to an FS.Rename
966 static int afs_deliver_fs_rename(struct afs_call *call,
967 struct sk_buff *skb, bool last)
969 struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
970 const __be32 *bp;
972 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
974 afs_transfer_reply(call, skb);
975 if (!last)
976 return 0;
978 if (call->reply_size != call->reply_max)
979 return -EBADMSG;
981 /* unmarshall the reply once we've received all of it */
982 bp = call->buffer;
983 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
984 if (new_dvnode != orig_dvnode)
985 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
986 NULL);
987 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
989 _leave(" = 0 [done]");
990 return 0;
994 * FS.Rename operation type
996 static const struct afs_call_type afs_RXFSRename = {
997 .name = "FS.Rename",
998 .deliver = afs_deliver_fs_rename,
999 .abort_to_error = afs_abort_to_error,
1000 .destructor = afs_flat_call_destructor,
1004 * create a symbolic link
1006 int afs_fs_rename(struct afs_server *server,
1007 struct key *key,
1008 struct afs_vnode *orig_dvnode,
1009 const char *orig_name,
1010 struct afs_vnode *new_dvnode,
1011 const char *new_name,
1012 const struct afs_wait_mode *wait_mode)
1014 struct afs_call *call;
1015 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1016 __be32 *bp;
1018 _enter("");
1020 o_namesz = strlen(orig_name);
1021 o_padsz = (4 - (o_namesz & 3)) & 3;
1023 n_namesz = strlen(new_name);
1024 n_padsz = (4 - (n_namesz & 3)) & 3;
1026 reqsz = (4 * 4) +
1027 4 + o_namesz + o_padsz +
1028 (3 * 4) +
1029 4 + n_namesz + n_padsz;
1031 call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1032 if (!call)
1033 return -ENOMEM;
1035 call->key = key;
1036 call->reply = orig_dvnode;
1037 call->reply2 = new_dvnode;
1038 call->service_id = FS_SERVICE;
1039 call->port = htons(AFS_FS_PORT);
1041 /* marshall the parameters */
1042 bp = call->request;
1043 *bp++ = htonl(FSRENAME);
1044 *bp++ = htonl(orig_dvnode->fid.vid);
1045 *bp++ = htonl(orig_dvnode->fid.vnode);
1046 *bp++ = htonl(orig_dvnode->fid.unique);
1047 *bp++ = htonl(o_namesz);
1048 memcpy(bp, orig_name, o_namesz);
1049 bp = (void *) bp + o_namesz;
1050 if (o_padsz > 0) {
1051 memset(bp, 0, o_padsz);
1052 bp = (void *) bp + o_padsz;
1055 *bp++ = htonl(new_dvnode->fid.vid);
1056 *bp++ = htonl(new_dvnode->fid.vnode);
1057 *bp++ = htonl(new_dvnode->fid.unique);
1058 *bp++ = htonl(n_namesz);
1059 memcpy(bp, new_name, n_namesz);
1060 bp = (void *) bp + n_namesz;
1061 if (n_padsz > 0) {
1062 memset(bp, 0, n_padsz);
1063 bp = (void *) bp + n_padsz;
1066 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1070 * deliver reply data to an FS.StoreData
1072 static int afs_deliver_fs_store_data(struct afs_call *call,
1073 struct sk_buff *skb, bool last)
1075 struct afs_vnode *vnode = call->reply;
1076 const __be32 *bp;
1078 _enter(",,%u", last);
1080 afs_transfer_reply(call, skb);
1081 if (!last) {
1082 _leave(" = 0 [more]");
1083 return 0;
1086 if (call->reply_size != call->reply_max) {
1087 _leave(" = -EBADMSG [%u != %u]",
1088 call->reply_size, call->reply_max);
1089 return -EBADMSG;
1092 /* unmarshall the reply once we've received all of it */
1093 bp = call->buffer;
1094 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1095 &call->store_version);
1096 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1098 afs_pages_written_back(vnode, call);
1100 _leave(" = 0 [done]");
1101 return 0;
1105 * FS.StoreData operation type
1107 static const struct afs_call_type afs_RXFSStoreData = {
1108 .name = "FS.StoreData",
1109 .deliver = afs_deliver_fs_store_data,
1110 .abort_to_error = afs_abort_to_error,
1111 .destructor = afs_flat_call_destructor,
1114 static const struct afs_call_type afs_RXFSStoreData64 = {
1115 .name = "FS.StoreData64",
1116 .deliver = afs_deliver_fs_store_data,
1117 .abort_to_error = afs_abort_to_error,
1118 .destructor = afs_flat_call_destructor,
1122 * store a set of pages to a very large file
1124 static int afs_fs_store_data64(struct afs_server *server,
1125 struct afs_writeback *wb,
1126 pgoff_t first, pgoff_t last,
1127 unsigned offset, unsigned to,
1128 loff_t size, loff_t pos, loff_t i_size,
1129 const struct afs_wait_mode *wait_mode)
1131 struct afs_vnode *vnode = wb->vnode;
1132 struct afs_call *call;
1133 __be32 *bp;
1135 _enter(",%x,{%x:%u},,",
1136 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1138 call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1139 (4 + 6 + 3 * 2) * 4,
1140 (21 + 6) * 4);
1141 if (!call)
1142 return -ENOMEM;
1144 call->wb = wb;
1145 call->key = wb->key;
1146 call->reply = vnode;
1147 call->service_id = FS_SERVICE;
1148 call->port = htons(AFS_FS_PORT);
1149 call->mapping = vnode->vfs_inode.i_mapping;
1150 call->first = first;
1151 call->last = last;
1152 call->first_offset = offset;
1153 call->last_to = to;
1154 call->send_pages = true;
1155 call->store_version = vnode->status.data_version + 1;
1157 /* marshall the parameters */
1158 bp = call->request;
1159 *bp++ = htonl(FSSTOREDATA64);
1160 *bp++ = htonl(vnode->fid.vid);
1161 *bp++ = htonl(vnode->fid.vnode);
1162 *bp++ = htonl(vnode->fid.unique);
1164 *bp++ = 0; /* mask */
1165 *bp++ = 0; /* mtime */
1166 *bp++ = 0; /* owner */
1167 *bp++ = 0; /* group */
1168 *bp++ = 0; /* unix mode */
1169 *bp++ = 0; /* segment size */
1171 *bp++ = htonl(pos >> 32);
1172 *bp++ = htonl((u32) pos);
1173 *bp++ = htonl(size >> 32);
1174 *bp++ = htonl((u32) size);
1175 *bp++ = htonl(i_size >> 32);
1176 *bp++ = htonl((u32) i_size);
1178 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1182 * store a set of pages
1184 int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1185 pgoff_t first, pgoff_t last,
1186 unsigned offset, unsigned to,
1187 const struct afs_wait_mode *wait_mode)
1189 struct afs_vnode *vnode = wb->vnode;
1190 struct afs_call *call;
1191 loff_t size, pos, i_size;
1192 __be32 *bp;
1194 _enter(",%x,{%x:%u},,",
1195 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1197 size = to - offset;
1198 if (first != last)
1199 size += (loff_t)(last - first) << PAGE_SHIFT;
1200 pos = (loff_t)first << PAGE_SHIFT;
1201 pos += offset;
1203 i_size = i_size_read(&vnode->vfs_inode);
1204 if (pos + size > i_size)
1205 i_size = size + pos;
1207 _debug("size %llx, at %llx, i_size %llx",
1208 (unsigned long long) size, (unsigned long long) pos,
1209 (unsigned long long) i_size);
1211 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1212 return afs_fs_store_data64(server, wb, first, last, offset, to,
1213 size, pos, i_size, wait_mode);
1215 call = afs_alloc_flat_call(&afs_RXFSStoreData,
1216 (4 + 6 + 3) * 4,
1217 (21 + 6) * 4);
1218 if (!call)
1219 return -ENOMEM;
1221 call->wb = wb;
1222 call->key = wb->key;
1223 call->reply = vnode;
1224 call->service_id = FS_SERVICE;
1225 call->port = htons(AFS_FS_PORT);
1226 call->mapping = vnode->vfs_inode.i_mapping;
1227 call->first = first;
1228 call->last = last;
1229 call->first_offset = offset;
1230 call->last_to = to;
1231 call->send_pages = true;
1232 call->store_version = vnode->status.data_version + 1;
1234 /* marshall the parameters */
1235 bp = call->request;
1236 *bp++ = htonl(FSSTOREDATA);
1237 *bp++ = htonl(vnode->fid.vid);
1238 *bp++ = htonl(vnode->fid.vnode);
1239 *bp++ = htonl(vnode->fid.unique);
1241 *bp++ = 0; /* mask */
1242 *bp++ = 0; /* mtime */
1243 *bp++ = 0; /* owner */
1244 *bp++ = 0; /* group */
1245 *bp++ = 0; /* unix mode */
1246 *bp++ = 0; /* segment size */
1248 *bp++ = htonl(pos);
1249 *bp++ = htonl(size);
1250 *bp++ = htonl(i_size);
1252 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1256 * deliver reply data to an FS.StoreStatus
1258 static int afs_deliver_fs_store_status(struct afs_call *call,
1259 struct sk_buff *skb, bool last)
1261 afs_dataversion_t *store_version;
1262 struct afs_vnode *vnode = call->reply;
1263 const __be32 *bp;
1265 _enter(",,%u", last);
1267 afs_transfer_reply(call, skb);
1268 if (!last) {
1269 _leave(" = 0 [more]");
1270 return 0;
1273 if (call->reply_size != call->reply_max) {
1274 _leave(" = -EBADMSG [%u != %u]",
1275 call->reply_size, call->reply_max);
1276 return -EBADMSG;
1279 /* unmarshall the reply once we've received all of it */
1280 store_version = NULL;
1281 if (call->operation_ID == FSSTOREDATA)
1282 store_version = &call->store_version;
1284 bp = call->buffer;
1285 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1286 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1288 _leave(" = 0 [done]");
1289 return 0;
1293 * FS.StoreStatus operation type
1295 static const struct afs_call_type afs_RXFSStoreStatus = {
1296 .name = "FS.StoreStatus",
1297 .deliver = afs_deliver_fs_store_status,
1298 .abort_to_error = afs_abort_to_error,
1299 .destructor = afs_flat_call_destructor,
1302 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1303 .name = "FS.StoreData",
1304 .deliver = afs_deliver_fs_store_status,
1305 .abort_to_error = afs_abort_to_error,
1306 .destructor = afs_flat_call_destructor,
1309 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1310 .name = "FS.StoreData64",
1311 .deliver = afs_deliver_fs_store_status,
1312 .abort_to_error = afs_abort_to_error,
1313 .destructor = afs_flat_call_destructor,
1317 * set the attributes on a very large file, using FS.StoreData rather than
1318 * FS.StoreStatus so as to alter the file size also
1320 static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,
1321 struct afs_vnode *vnode, struct iattr *attr,
1322 const struct afs_wait_mode *wait_mode)
1324 struct afs_call *call;
1325 __be32 *bp;
1327 _enter(",%x,{%x:%u},,",
1328 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1330 ASSERT(attr->ia_valid & ATTR_SIZE);
1332 call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,
1333 (4 + 6 + 3 * 2) * 4,
1334 (21 + 6) * 4);
1335 if (!call)
1336 return -ENOMEM;
1338 call->key = key;
1339 call->reply = vnode;
1340 call->service_id = FS_SERVICE;
1341 call->port = htons(AFS_FS_PORT);
1342 call->store_version = vnode->status.data_version + 1;
1343 call->operation_ID = FSSTOREDATA;
1345 /* marshall the parameters */
1346 bp = call->request;
1347 *bp++ = htonl(FSSTOREDATA64);
1348 *bp++ = htonl(vnode->fid.vid);
1349 *bp++ = htonl(vnode->fid.vnode);
1350 *bp++ = htonl(vnode->fid.unique);
1352 xdr_encode_AFS_StoreStatus(&bp, attr);
1354 *bp++ = 0; /* position of start of write */
1355 *bp++ = 0;
1356 *bp++ = 0; /* size of write */
1357 *bp++ = 0;
1358 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1359 *bp++ = htonl((u32) attr->ia_size);
1361 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1365 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1366 * so as to alter the file size also
1368 static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1369 struct afs_vnode *vnode, struct iattr *attr,
1370 const struct afs_wait_mode *wait_mode)
1372 struct afs_call *call;
1373 __be32 *bp;
1375 _enter(",%x,{%x:%u},,",
1376 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1378 ASSERT(attr->ia_valid & ATTR_SIZE);
1379 if (attr->ia_size >> 32)
1380 return afs_fs_setattr_size64(server, key, vnode, attr,
1381 wait_mode);
1383 call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1384 (4 + 6 + 3) * 4,
1385 (21 + 6) * 4);
1386 if (!call)
1387 return -ENOMEM;
1389 call->key = key;
1390 call->reply = vnode;
1391 call->service_id = FS_SERVICE;
1392 call->port = htons(AFS_FS_PORT);
1393 call->store_version = vnode->status.data_version + 1;
1394 call->operation_ID = FSSTOREDATA;
1396 /* marshall the parameters */
1397 bp = call->request;
1398 *bp++ = htonl(FSSTOREDATA);
1399 *bp++ = htonl(vnode->fid.vid);
1400 *bp++ = htonl(vnode->fid.vnode);
1401 *bp++ = htonl(vnode->fid.unique);
1403 xdr_encode_AFS_StoreStatus(&bp, attr);
1405 *bp++ = 0; /* position of start of write */
1406 *bp++ = 0; /* size of write */
1407 *bp++ = htonl(attr->ia_size); /* new file length */
1409 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1413 * set the attributes on a file, using FS.StoreData if there's a change in file
1414 * size, and FS.StoreStatus otherwise
1416 int afs_fs_setattr(struct afs_server *server, struct key *key,
1417 struct afs_vnode *vnode, struct iattr *attr,
1418 const struct afs_wait_mode *wait_mode)
1420 struct afs_call *call;
1421 __be32 *bp;
1423 if (attr->ia_valid & ATTR_SIZE)
1424 return afs_fs_setattr_size(server, key, vnode, attr,
1425 wait_mode);
1427 _enter(",%x,{%x:%u},,",
1428 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1430 call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1431 (4 + 6) * 4,
1432 (21 + 6) * 4);
1433 if (!call)
1434 return -ENOMEM;
1436 call->key = key;
1437 call->reply = vnode;
1438 call->service_id = FS_SERVICE;
1439 call->port = htons(AFS_FS_PORT);
1440 call->operation_ID = FSSTORESTATUS;
1442 /* marshall the parameters */
1443 bp = call->request;
1444 *bp++ = htonl(FSSTORESTATUS);
1445 *bp++ = htonl(vnode->fid.vid);
1446 *bp++ = htonl(vnode->fid.vnode);
1447 *bp++ = htonl(vnode->fid.unique);
1449 xdr_encode_AFS_StoreStatus(&bp, attr);
1451 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);