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>
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++);
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;
42 u64 data_version, size;
43 u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
45 #define EXTRACT(DST) \
47 u32 x = ntohl(*bp++); \
52 status->if_version = ntohl(*bp++);
53 EXTRACT(status->type);
54 EXTRACT(status->nlink);
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);
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;
75 if (size != status->size) {
79 status->mode &= S_IALLUGO;
81 _debug("vnode time %lx, %lx",
82 status->mtime_client, status->mtime_server);
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;
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;
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();
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++);
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++);
167 * encode the requested attributes into an AFSStoreStatus block
169 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
172 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 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;
196 *bp++ = htonl(mtime);
197 *bp++ = htonl(owner);
198 *bp++ = htonl(group);
200 *bp++ = 0; /* segment size */
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;
213 _enter(",,%u", last);
215 afs_transfer_reply(call, skb);
219 if (call->reply_size != call->reply_max)
222 /* unmarshall the reply once we've received all of it */
224 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
225 xdr_decode_AFSCallBack(&bp, vnode);
227 xdr_decode_AFSVolSync(&bp, call->reply2);
229 _leave(" = 0 [done]");
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,
248 struct afs_vnode *vnode,
249 struct afs_volsync *volsync,
250 const struct afs_wait_mode *wait_mode)
252 struct afs_call *call;
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);
264 call->reply2 = volsync;
265 call->service_id = FS_SERVICE;
266 call->port = htons(AFS_FS_PORT);
268 /* marshall the parameters */
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;
290 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
292 switch (call->unmarshall) {
297 /* extract the returned data length */
299 _debug("extract data length");
300 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
303 case -EAGAIN: return 0;
307 call->count = ntohl(call->tmp);
308 _debug("DATA length: %u", call->count);
309 if (call->count > PAGE_SIZE)
314 /* extract the returned data */
316 _debug("extract data");
317 if (call->count > 0) {
319 buffer = kmap_atomic(page, KM_USER0);
320 ret = afs_extract_data(call, skb, last, buffer,
322 kunmap_atomic(buffer, KM_USER0);
325 case -EAGAIN: return 0;
333 /* extract the metadata */
335 ret = afs_extract_data(call, skb, last, call->buffer,
339 case -EAGAIN: return 0;
344 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
345 xdr_decode_AFSCallBack(&bp, vnode);
347 xdr_decode_AFSVolSync(&bp, call->reply2);
362 if (call->count < PAGE_SIZE) {
365 buffer = kmap_atomic(page, KM_USER0);
366 memset(buffer + call->count, 0, PAGE_SIZE - call->count);
367 kunmap_atomic(buffer, KM_USER0);
370 _leave(" = 0 [done]");
375 * FS.FetchData operation type
377 static const struct afs_call_type afs_RXFSFetchData = {
378 .name = "FS.FetchData",
379 .deliver = afs_deliver_fs_fetch_data,
380 .abort_to_error = afs_abort_to_error,
381 .destructor = afs_flat_call_destructor,
385 * fetch data from a file
387 int afs_fs_fetch_data(struct afs_server *server,
389 struct afs_vnode *vnode,
390 off_t offset, size_t length,
392 const struct afs_wait_mode *wait_mode)
394 struct afs_call *call;
399 call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
405 call->reply2 = NULL; /* volsync */
406 call->reply3 = buffer;
407 call->service_id = FS_SERVICE;
408 call->port = htons(AFS_FS_PORT);
410 /* marshall the parameters */
412 bp[0] = htonl(FSFETCHDATA);
413 bp[1] = htonl(vnode->fid.vid);
414 bp[2] = htonl(vnode->fid.vnode);
415 bp[3] = htonl(vnode->fid.unique);
416 bp[4] = htonl(offset);
417 bp[5] = htonl(length);
419 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
423 * deliver reply data to an FS.GiveUpCallBacks
425 static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
426 struct sk_buff *skb, bool last)
428 _enter(",{%u},%d", skb->len, last);
431 return -EBADMSG; /* shouldn't be any reply data */
436 * FS.GiveUpCallBacks operation type
438 static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
439 .name = "FS.GiveUpCallBacks",
440 .deliver = afs_deliver_fs_give_up_callbacks,
441 .abort_to_error = afs_abort_to_error,
442 .destructor = afs_flat_call_destructor,
446 * give up a set of callbacks
447 * - the callbacks are held in the server->cb_break ring
449 int afs_fs_give_up_callbacks(struct afs_server *server,
450 const struct afs_wait_mode *wait_mode)
452 struct afs_call *call;
457 ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
458 ARRAY_SIZE(server->cb_break));
460 _enter("{%zu},", ncallbacks);
464 if (ncallbacks > AFSCBMAX)
465 ncallbacks = AFSCBMAX;
467 _debug("break %zu callbacks", ncallbacks);
469 call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
470 12 + ncallbacks * 6 * 4, 0);
474 call->service_id = FS_SERVICE;
475 call->port = htons(AFS_FS_PORT);
477 /* marshall the parameters */
479 tp = bp + 2 + ncallbacks * 3;
480 *bp++ = htonl(FSGIVEUPCALLBACKS);
481 *bp++ = htonl(ncallbacks);
482 *tp++ = htonl(ncallbacks);
484 atomic_sub(ncallbacks, &server->cb_break_n);
485 for (loop = ncallbacks; loop > 0; loop--) {
486 struct afs_callback *cb =
487 &server->cb_break[server->cb_break_tail];
489 *bp++ = htonl(cb->fid.vid);
490 *bp++ = htonl(cb->fid.vnode);
491 *bp++ = htonl(cb->fid.unique);
492 *tp++ = htonl(cb->version);
493 *tp++ = htonl(cb->expiry);
494 *tp++ = htonl(cb->type);
496 server->cb_break_tail =
497 (server->cb_break_tail + 1) &
498 (ARRAY_SIZE(server->cb_break) - 1);
501 ASSERT(ncallbacks > 0);
502 wake_up_nr(&server->cb_break_waitq, ncallbacks);
504 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
508 * deliver reply data to an FS.CreateFile or an FS.MakeDir
510 static int afs_deliver_fs_create_vnode(struct afs_call *call,
511 struct sk_buff *skb, bool last)
513 struct afs_vnode *vnode = call->reply;
516 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
518 afs_transfer_reply(call, skb);
522 if (call->reply_size != call->reply_max)
525 /* unmarshall the reply once we've received all of it */
527 xdr_decode_AFSFid(&bp, call->reply2);
528 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
529 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
530 xdr_decode_AFSCallBack_raw(&bp, call->reply4);
531 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
533 _leave(" = 0 [done]");
538 * FS.CreateFile and FS.MakeDir operation type
540 static const struct afs_call_type afs_RXFSCreateXXXX = {
541 .name = "FS.CreateXXXX",
542 .deliver = afs_deliver_fs_create_vnode,
543 .abort_to_error = afs_abort_to_error,
544 .destructor = afs_flat_call_destructor,
548 * create a file or make a directory
550 int afs_fs_create(struct afs_server *server,
552 struct afs_vnode *vnode,
555 struct afs_fid *newfid,
556 struct afs_file_status *newstatus,
557 struct afs_callback *newcb,
558 const struct afs_wait_mode *wait_mode)
560 struct afs_call *call;
561 size_t namesz, reqsz, padsz;
566 namesz = strlen(name);
567 padsz = (4 - (namesz & 3)) & 3;
568 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
570 call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
571 (3 + 21 + 21 + 3 + 6) * 4);
577 call->reply2 = newfid;
578 call->reply3 = newstatus;
579 call->reply4 = newcb;
580 call->service_id = FS_SERVICE;
581 call->port = htons(AFS_FS_PORT);
583 /* marshall the parameters */
585 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
586 *bp++ = htonl(vnode->fid.vid);
587 *bp++ = htonl(vnode->fid.vnode);
588 *bp++ = htonl(vnode->fid.unique);
589 *bp++ = htonl(namesz);
590 memcpy(bp, name, namesz);
591 bp = (void *) bp + namesz;
593 memset(bp, 0, padsz);
594 bp = (void *) bp + padsz;
596 *bp++ = htonl(AFS_SET_MODE);
597 *bp++ = 0; /* mtime */
598 *bp++ = 0; /* owner */
599 *bp++ = 0; /* group */
600 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
601 *bp++ = 0; /* segment size */
603 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
607 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
609 static int afs_deliver_fs_remove(struct afs_call *call,
610 struct sk_buff *skb, bool last)
612 struct afs_vnode *vnode = call->reply;
615 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
617 afs_transfer_reply(call, skb);
621 if (call->reply_size != call->reply_max)
624 /* unmarshall the reply once we've received all of it */
626 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
627 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
629 _leave(" = 0 [done]");
634 * FS.RemoveDir/FS.RemoveFile operation type
636 static const struct afs_call_type afs_RXFSRemoveXXXX = {
637 .name = "FS.RemoveXXXX",
638 .deliver = afs_deliver_fs_remove,
639 .abort_to_error = afs_abort_to_error,
640 .destructor = afs_flat_call_destructor,
644 * remove a file or directory
646 int afs_fs_remove(struct afs_server *server,
648 struct afs_vnode *vnode,
651 const struct afs_wait_mode *wait_mode)
653 struct afs_call *call;
654 size_t namesz, reqsz, padsz;
659 namesz = strlen(name);
660 padsz = (4 - (namesz & 3)) & 3;
661 reqsz = (5 * 4) + namesz + padsz;
663 call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
669 call->service_id = FS_SERVICE;
670 call->port = htons(AFS_FS_PORT);
672 /* marshall the parameters */
674 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
675 *bp++ = htonl(vnode->fid.vid);
676 *bp++ = htonl(vnode->fid.vnode);
677 *bp++ = htonl(vnode->fid.unique);
678 *bp++ = htonl(namesz);
679 memcpy(bp, name, namesz);
680 bp = (void *) bp + namesz;
682 memset(bp, 0, padsz);
683 bp = (void *) bp + padsz;
686 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
690 * deliver reply data to an FS.Link
692 static int afs_deliver_fs_link(struct afs_call *call,
693 struct sk_buff *skb, bool last)
695 struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
698 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
700 afs_transfer_reply(call, skb);
704 if (call->reply_size != call->reply_max)
707 /* unmarshall the reply once we've received all of it */
709 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
710 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
711 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
713 _leave(" = 0 [done]");
718 * FS.Link operation type
720 static const struct afs_call_type afs_RXFSLink = {
722 .deliver = afs_deliver_fs_link,
723 .abort_to_error = afs_abort_to_error,
724 .destructor = afs_flat_call_destructor,
730 int afs_fs_link(struct afs_server *server,
732 struct afs_vnode *dvnode,
733 struct afs_vnode *vnode,
735 const struct afs_wait_mode *wait_mode)
737 struct afs_call *call;
738 size_t namesz, reqsz, padsz;
743 namesz = strlen(name);
744 padsz = (4 - (namesz & 3)) & 3;
745 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
747 call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
752 call->reply = dvnode;
753 call->reply2 = vnode;
754 call->service_id = FS_SERVICE;
755 call->port = htons(AFS_FS_PORT);
757 /* marshall the parameters */
759 *bp++ = htonl(FSLINK);
760 *bp++ = htonl(dvnode->fid.vid);
761 *bp++ = htonl(dvnode->fid.vnode);
762 *bp++ = htonl(dvnode->fid.unique);
763 *bp++ = htonl(namesz);
764 memcpy(bp, name, namesz);
765 bp = (void *) bp + namesz;
767 memset(bp, 0, padsz);
768 bp = (void *) bp + padsz;
770 *bp++ = htonl(vnode->fid.vid);
771 *bp++ = htonl(vnode->fid.vnode);
772 *bp++ = htonl(vnode->fid.unique);
774 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
778 * deliver reply data to an FS.Symlink
780 static int afs_deliver_fs_symlink(struct afs_call *call,
781 struct sk_buff *skb, bool last)
783 struct afs_vnode *vnode = call->reply;
786 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
788 afs_transfer_reply(call, skb);
792 if (call->reply_size != call->reply_max)
795 /* unmarshall the reply once we've received all of it */
797 xdr_decode_AFSFid(&bp, call->reply2);
798 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
799 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
800 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
802 _leave(" = 0 [done]");
807 * FS.Symlink operation type
809 static const struct afs_call_type afs_RXFSSymlink = {
810 .name = "FS.Symlink",
811 .deliver = afs_deliver_fs_symlink,
812 .abort_to_error = afs_abort_to_error,
813 .destructor = afs_flat_call_destructor,
817 * create a symbolic link
819 int afs_fs_symlink(struct afs_server *server,
821 struct afs_vnode *vnode,
823 const char *contents,
824 struct afs_fid *newfid,
825 struct afs_file_status *newstatus,
826 const struct afs_wait_mode *wait_mode)
828 struct afs_call *call;
829 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
834 namesz = strlen(name);
835 padsz = (4 - (namesz & 3)) & 3;
837 c_namesz = strlen(contents);
838 c_padsz = (4 - (c_namesz & 3)) & 3;
840 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
842 call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
843 (3 + 21 + 21 + 6) * 4);
849 call->reply2 = newfid;
850 call->reply3 = newstatus;
851 call->service_id = FS_SERVICE;
852 call->port = htons(AFS_FS_PORT);
854 /* marshall the parameters */
856 *bp++ = htonl(FSSYMLINK);
857 *bp++ = htonl(vnode->fid.vid);
858 *bp++ = htonl(vnode->fid.vnode);
859 *bp++ = htonl(vnode->fid.unique);
860 *bp++ = htonl(namesz);
861 memcpy(bp, name, namesz);
862 bp = (void *) bp + namesz;
864 memset(bp, 0, padsz);
865 bp = (void *) bp + padsz;
867 *bp++ = htonl(c_namesz);
868 memcpy(bp, contents, c_namesz);
869 bp = (void *) bp + c_namesz;
871 memset(bp, 0, c_padsz);
872 bp = (void *) bp + c_padsz;
874 *bp++ = htonl(AFS_SET_MODE);
875 *bp++ = 0; /* mtime */
876 *bp++ = 0; /* owner */
877 *bp++ = 0; /* group */
878 *bp++ = htonl(S_IRWXUGO); /* unix mode */
879 *bp++ = 0; /* segment size */
881 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
885 * deliver reply data to an FS.Rename
887 static int afs_deliver_fs_rename(struct afs_call *call,
888 struct sk_buff *skb, bool last)
890 struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
893 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
895 afs_transfer_reply(call, skb);
899 if (call->reply_size != call->reply_max)
902 /* unmarshall the reply once we've received all of it */
904 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
905 if (new_dvnode != orig_dvnode)
906 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
908 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
910 _leave(" = 0 [done]");
915 * FS.Rename operation type
917 static const struct afs_call_type afs_RXFSRename = {
919 .deliver = afs_deliver_fs_rename,
920 .abort_to_error = afs_abort_to_error,
921 .destructor = afs_flat_call_destructor,
925 * create a symbolic link
927 int afs_fs_rename(struct afs_server *server,
929 struct afs_vnode *orig_dvnode,
930 const char *orig_name,
931 struct afs_vnode *new_dvnode,
932 const char *new_name,
933 const struct afs_wait_mode *wait_mode)
935 struct afs_call *call;
936 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
941 o_namesz = strlen(orig_name);
942 o_padsz = (4 - (o_namesz & 3)) & 3;
944 n_namesz = strlen(new_name);
945 n_padsz = (4 - (n_namesz & 3)) & 3;
948 4 + o_namesz + o_padsz +
950 4 + n_namesz + n_padsz;
952 call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
957 call->reply = orig_dvnode;
958 call->reply2 = new_dvnode;
959 call->service_id = FS_SERVICE;
960 call->port = htons(AFS_FS_PORT);
962 /* marshall the parameters */
964 *bp++ = htonl(FSRENAME);
965 *bp++ = htonl(orig_dvnode->fid.vid);
966 *bp++ = htonl(orig_dvnode->fid.vnode);
967 *bp++ = htonl(orig_dvnode->fid.unique);
968 *bp++ = htonl(o_namesz);
969 memcpy(bp, orig_name, o_namesz);
970 bp = (void *) bp + o_namesz;
972 memset(bp, 0, o_padsz);
973 bp = (void *) bp + o_padsz;
976 *bp++ = htonl(new_dvnode->fid.vid);
977 *bp++ = htonl(new_dvnode->fid.vnode);
978 *bp++ = htonl(new_dvnode->fid.unique);
979 *bp++ = htonl(n_namesz);
980 memcpy(bp, new_name, n_namesz);
981 bp = (void *) bp + n_namesz;
983 memset(bp, 0, n_padsz);
984 bp = (void *) bp + n_padsz;
987 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
991 * deliver reply data to an FS.StoreData
993 static int afs_deliver_fs_store_data(struct afs_call *call,
994 struct sk_buff *skb, bool last)
996 struct afs_vnode *vnode = call->reply;
999 _enter(",,%u", last);
1001 afs_transfer_reply(call, skb);
1003 _leave(" = 0 [more]");
1007 if (call->reply_size != call->reply_max) {
1008 _leave(" = -EBADMSG [%u != %u]",
1009 call->reply_size, call->reply_max);
1013 /* unmarshall the reply once we've received all of it */
1015 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1016 &call->store_version);
1017 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1019 afs_pages_written_back(vnode, call);
1021 _leave(" = 0 [done]");
1026 * FS.StoreData operation type
1028 static const struct afs_call_type afs_RXFSStoreData = {
1029 .name = "FS.StoreData",
1030 .deliver = afs_deliver_fs_store_data,
1031 .abort_to_error = afs_abort_to_error,
1032 .destructor = afs_flat_call_destructor,
1036 * store a set of pages
1038 int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1039 pgoff_t first, pgoff_t last,
1040 unsigned offset, unsigned to,
1041 const struct afs_wait_mode *wait_mode)
1043 struct afs_vnode *vnode = wb->vnode;
1044 struct afs_call *call;
1045 loff_t size, pos, i_size;
1048 _enter(",%x,{%x:%u},,",
1049 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1053 size += (loff_t)(last - first) << PAGE_SHIFT;
1054 pos = (loff_t)first << PAGE_SHIFT;
1057 i_size = i_size_read(&vnode->vfs_inode);
1058 if (pos + size > i_size)
1059 i_size = size + pos;
1061 _debug("size %llx, at %llx, i_size %llx",
1062 (unsigned long long) size, (unsigned long long) pos,
1063 (unsigned long long) i_size);
1065 BUG_ON(i_size > 0xffffffff); // TODO: use 64-bit store
1067 call = afs_alloc_flat_call(&afs_RXFSStoreData,
1074 call->key = wb->key;
1075 call->reply = vnode;
1076 call->service_id = FS_SERVICE;
1077 call->port = htons(AFS_FS_PORT);
1078 call->mapping = vnode->vfs_inode.i_mapping;
1079 call->first = first;
1081 call->first_offset = offset;
1083 call->send_pages = true;
1084 call->store_version = vnode->status.data_version + 1;
1086 /* marshall the parameters */
1088 *bp++ = htonl(FSSTOREDATA);
1089 *bp++ = htonl(vnode->fid.vid);
1090 *bp++ = htonl(vnode->fid.vnode);
1091 *bp++ = htonl(vnode->fid.unique);
1093 *bp++ = 0; /* mask */
1094 *bp++ = 0; /* mtime */
1095 *bp++ = 0; /* owner */
1096 *bp++ = 0; /* group */
1097 *bp++ = 0; /* unix mode */
1098 *bp++ = 0; /* segment size */
1101 *bp++ = htonl(size);
1102 *bp++ = htonl(i_size);
1104 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1108 * deliver reply data to an FS.StoreStatus
1110 static int afs_deliver_fs_store_status(struct afs_call *call,
1111 struct sk_buff *skb, bool last)
1113 afs_dataversion_t *store_version;
1114 struct afs_vnode *vnode = call->reply;
1117 _enter(",,%u", last);
1119 afs_transfer_reply(call, skb);
1121 _leave(" = 0 [more]");
1125 if (call->reply_size != call->reply_max) {
1126 _leave(" = -EBADMSG [%u != %u]",
1127 call->reply_size, call->reply_max);
1131 /* unmarshall the reply once we've received all of it */
1132 store_version = NULL;
1133 if (call->operation_ID == FSSTOREDATA)
1134 store_version = &call->store_version;
1137 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1138 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1140 _leave(" = 0 [done]");
1145 * FS.StoreStatus operation type
1147 static const struct afs_call_type afs_RXFSStoreStatus = {
1148 .name = "FS.StoreStatus",
1149 .deliver = afs_deliver_fs_store_status,
1150 .abort_to_error = afs_abort_to_error,
1151 .destructor = afs_flat_call_destructor,
1154 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1155 .name = "FS.StoreData",
1156 .deliver = afs_deliver_fs_store_status,
1157 .abort_to_error = afs_abort_to_error,
1158 .destructor = afs_flat_call_destructor,
1162 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1163 * so as to alter the file size also
1165 static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1166 struct afs_vnode *vnode, struct iattr *attr,
1167 const struct afs_wait_mode *wait_mode)
1169 struct afs_call *call;
1172 _enter(",%x,{%x:%u},,",
1173 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1175 ASSERT(attr->ia_valid & ATTR_SIZE);
1176 ASSERTCMP(attr->ia_size, <=, 0xffffffff); // TODO: use 64-bit store
1178 call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1185 call->reply = vnode;
1186 call->service_id = FS_SERVICE;
1187 call->port = htons(AFS_FS_PORT);
1188 call->store_version = vnode->status.data_version + 1;
1189 call->operation_ID = FSSTOREDATA;
1191 /* marshall the parameters */
1193 *bp++ = htonl(FSSTOREDATA);
1194 *bp++ = htonl(vnode->fid.vid);
1195 *bp++ = htonl(vnode->fid.vnode);
1196 *bp++ = htonl(vnode->fid.unique);
1198 xdr_encode_AFS_StoreStatus(&bp, attr);
1200 *bp++ = 0; /* position of start of write */
1201 *bp++ = 0; /* size of write */
1202 *bp++ = htonl(attr->ia_size); /* new file length */
1204 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1208 * set the attributes on a file, using FS.StoreData if there's a change in file
1209 * size, and FS.StoreStatus otherwise
1211 int afs_fs_setattr(struct afs_server *server, struct key *key,
1212 struct afs_vnode *vnode, struct iattr *attr,
1213 const struct afs_wait_mode *wait_mode)
1215 struct afs_call *call;
1218 if (attr->ia_valid & ATTR_SIZE)
1219 return afs_fs_setattr_size(server, key, vnode, attr,
1222 _enter(",%x,{%x:%u},,",
1223 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1225 call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1232 call->reply = vnode;
1233 call->service_id = FS_SERVICE;
1234 call->port = htons(AFS_FS_PORT);
1235 call->operation_ID = FSSTORESTATUS;
1237 /* marshall the parameters */
1239 *bp++ = htonl(FSSTORESTATUS);
1240 *bp++ = htonl(vnode->fid.vid);
1241 *bp++ = htonl(vnode->fid.vnode);
1242 *bp++ = htonl(vnode->fid.unique);
1244 xdr_encode_AFS_StoreStatus(&bp, attr);
1246 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);