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 <linux/iversion.h>
21 static const struct afs_fid afs_zero_fid;
24 * We need somewhere to discard into in case the server helpfully returns more
25 * than we asked for in FS.FetchData{,64}.
27 static u8 afs_discard_buffer[64];
29 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
31 call->cbi = afs_get_cb_interest(cbi);
35 * decode an AFSFid block
37 static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
39 const __be32 *bp = *_bp;
41 fid->vid = ntohl(*bp++);
42 fid->vnode = ntohl(*bp++);
43 fid->unique = ntohl(*bp++);
48 * Dump a bad file status record.
50 static void xdr_dump_bad(const __be32 *bp)
55 pr_notice("AFS XDR: Bad status record\n");
56 for (i = 0; i < 5 * 4 * 4; i += 16) {
59 pr_notice("%03x: %08x %08x %08x %08x\n",
60 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
64 pr_notice("0x50: %08x\n", ntohl(x[0]));
68 * Update the core inode struct from a returned status record.
70 void afs_update_inode_from_status(struct afs_vnode *vnode,
71 struct afs_file_status *status,
72 const afs_dataversion_t *expected_version,
78 t.tv_sec = status->mtime_client;
80 vnode->vfs_inode.i_ctime = t;
81 vnode->vfs_inode.i_mtime = t;
82 vnode->vfs_inode.i_atime = t;
84 if (flags & (AFS_VNODE_META_CHANGED | AFS_VNODE_NOT_YET_SET)) {
85 vnode->vfs_inode.i_uid = make_kuid(&init_user_ns, status->owner);
86 vnode->vfs_inode.i_gid = make_kgid(&init_user_ns, status->group);
87 set_nlink(&vnode->vfs_inode, status->nlink);
89 mode = vnode->vfs_inode.i_mode;
93 vnode->vfs_inode.i_mode = mode;
96 if (!(flags & AFS_VNODE_NOT_YET_SET)) {
97 if (expected_version &&
98 *expected_version != status->data_version) {
99 _debug("vnode modified %llx on {%x:%u} [exp %llx]",
100 (unsigned long long) status->data_version,
101 vnode->fid.vid, vnode->fid.vnode,
102 (unsigned long long) *expected_version);
103 vnode->invalid_before = status->data_version;
104 if (vnode->status.type == AFS_FTYPE_DIR) {
105 if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
106 afs_stat_v(vnode, n_inval);
108 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
110 } else if (vnode->status.type == AFS_FTYPE_DIR) {
111 /* Expected directory change is handled elsewhere so
112 * that we can locally edit the directory and save on a
115 if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
116 flags &= ~AFS_VNODE_DATA_CHANGED;
120 if (flags & (AFS_VNODE_DATA_CHANGED | AFS_VNODE_NOT_YET_SET)) {
121 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
122 i_size_write(&vnode->vfs_inode, status->size);
127 * decode an AFSFetchStatus block
129 static int xdr_decode_AFSFetchStatus(struct afs_call *call,
131 struct afs_file_status *status,
132 struct afs_vnode *vnode,
133 const afs_dataversion_t *expected_version,
134 struct afs_read *read_req)
136 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
137 u64 data_version, size;
138 u32 type, abort_code;
143 write_seqlock(&vnode->cb_lock);
145 if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {
146 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
150 type = ntohl(xdr->type);
151 abort_code = ntohl(xdr->abort_code);
155 case AFS_FTYPE_SYMLINK:
156 if (type != status->type &&
158 !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
159 pr_warning("Vnode %x:%x:%x changed type %u to %u\n",
168 case AFS_FTYPE_INVALID:
169 if (abort_code != 0) {
170 status->abort_code = abort_code;
179 #define EXTRACT_M(FIELD) \
181 u32 x = ntohl(xdr->FIELD); \
182 if (status->FIELD != x) { \
183 flags |= AFS_VNODE_META_CHANGED; \
191 EXTRACT_M(caller_access); /* call ticket dependent */
192 EXTRACT_M(anon_access);
196 status->mtime_client = ntohl(xdr->mtime_client);
197 status->mtime_server = ntohl(xdr->mtime_server);
198 status->lock_count = ntohl(xdr->lock_count);
200 size = (u64)ntohl(xdr->size_lo);
201 size |= (u64)ntohl(xdr->size_hi) << 32;
204 data_version = (u64)ntohl(xdr->data_version_lo);
205 data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
206 if (data_version != status->data_version) {
207 status->data_version = data_version;
208 flags |= AFS_VNODE_DATA_CHANGED;
212 read_req->data_version = data_version;
213 read_req->file_size = size;
216 *_bp = (const void *)*_bp + sizeof(*xdr);
219 if (test_bit(AFS_VNODE_UNSET, &vnode->flags))
220 flags |= AFS_VNODE_NOT_YET_SET;
221 afs_update_inode_from_status(vnode, status, expected_version,
229 write_sequnlock(&vnode->cb_lock);
234 ret = afs_protocol_error(call, -EBADMSG);
239 * decode an AFSCallBack block
241 static void xdr_decode_AFSCallBack(struct afs_call *call,
242 struct afs_vnode *vnode,
245 struct afs_cb_interest *old, *cbi = call->cbi;
246 const __be32 *bp = *_bp;
249 write_seqlock(&vnode->cb_lock);
251 if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) {
252 vnode->cb_version = ntohl(*bp++);
253 cb_expiry = ntohl(*bp++);
254 vnode->cb_type = ntohl(*bp++);
255 vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds();
256 old = vnode->cb_interest;
257 if (old != call->cbi) {
258 vnode->cb_interest = cbi;
261 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
266 write_sequnlock(&vnode->cb_lock);
271 static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
272 struct afs_callback *cb)
274 const __be32 *bp = *_bp;
276 cb->version = ntohl(*bp++);
277 cb->expiry = ntohl(*bp++);
278 cb->type = ntohl(*bp++);
283 * decode an AFSVolSync block
285 static void xdr_decode_AFSVolSync(const __be32 **_bp,
286 struct afs_volsync *volsync)
288 const __be32 *bp = *_bp;
290 volsync->creation = ntohl(*bp++);
300 * encode the requested attributes into an AFSStoreStatus block
302 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
305 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
308 if (attr->ia_valid & ATTR_MTIME) {
309 mask |= AFS_SET_MTIME;
310 mtime = attr->ia_mtime.tv_sec;
313 if (attr->ia_valid & ATTR_UID) {
314 mask |= AFS_SET_OWNER;
315 owner = from_kuid(&init_user_ns, attr->ia_uid);
318 if (attr->ia_valid & ATTR_GID) {
319 mask |= AFS_SET_GROUP;
320 group = from_kgid(&init_user_ns, attr->ia_gid);
323 if (attr->ia_valid & ATTR_MODE) {
324 mask |= AFS_SET_MODE;
325 mode = attr->ia_mode & S_IALLUGO;
329 *bp++ = htonl(mtime);
330 *bp++ = htonl(owner);
331 *bp++ = htonl(group);
333 *bp++ = 0; /* segment size */
338 * decode an AFSFetchVolumeStatus block
340 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
341 struct afs_volume_status *vs)
343 const __be32 *bp = *_bp;
345 vs->vid = ntohl(*bp++);
346 vs->parent_id = ntohl(*bp++);
347 vs->online = ntohl(*bp++);
348 vs->in_service = ntohl(*bp++);
349 vs->blessed = ntohl(*bp++);
350 vs->needs_salvage = ntohl(*bp++);
351 vs->type = ntohl(*bp++);
352 vs->min_quota = ntohl(*bp++);
353 vs->max_quota = ntohl(*bp++);
354 vs->blocks_in_use = ntohl(*bp++);
355 vs->part_blocks_avail = ntohl(*bp++);
356 vs->part_max_blocks = ntohl(*bp++);
361 * deliver reply data to an FS.FetchStatus
363 static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
365 struct afs_vnode *vnode = call->reply[0];
369 ret = afs_transfer_reply(call);
373 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
375 /* unmarshall the reply once we've received all of it */
377 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
378 &call->expected_version, NULL) < 0)
379 return afs_protocol_error(call, -EBADMSG);
380 xdr_decode_AFSCallBack(call, vnode, &bp);
382 xdr_decode_AFSVolSync(&bp, call->reply[1]);
384 _leave(" = 0 [done]");
389 * FS.FetchStatus operation type
391 static const struct afs_call_type afs_RXFSFetchStatus_vnode = {
392 .name = "FS.FetchStatus(vnode)",
393 .op = afs_FS_FetchStatus,
394 .deliver = afs_deliver_fs_fetch_status_vnode,
395 .destructor = afs_flat_call_destructor,
399 * fetch the status information for a file
401 int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
404 struct afs_vnode *vnode = fc->vnode;
405 struct afs_call *call;
406 struct afs_net *net = afs_v2net(vnode);
409 _enter(",%x,{%x:%u},,",
410 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
412 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode,
413 16, (21 + 3 + 6) * 4);
415 fc->ac.error = -ENOMEM;
420 call->reply[0] = vnode;
421 call->reply[1] = volsync;
422 call->expected_version = new_inode ? 1 : vnode->status.data_version;
424 /* marshall the parameters */
426 bp[0] = htonl(FSFETCHSTATUS);
427 bp[1] = htonl(vnode->fid.vid);
428 bp[2] = htonl(vnode->fid.vnode);
429 bp[3] = htonl(vnode->fid.unique);
431 call->cb_break = fc->cb_break;
432 afs_use_fs_server(call, fc->cbi);
433 trace_afs_make_fs_call(call, &vnode->fid);
434 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
438 * deliver reply data to an FS.FetchData
440 static int afs_deliver_fs_fetch_data(struct afs_call *call)
442 struct afs_vnode *vnode = call->reply[0];
443 struct afs_read *req = call->reply[2];
449 _enter("{%u,%zu/%u;%llu/%llu}",
450 call->unmarshall, call->offset, call->count,
451 req->remain, req->actual_len);
453 switch (call->unmarshall) {
458 if (call->operation_ID != FSFETCHDATA64) {
463 /* extract the upper part of the returned data length of an
464 * FSFETCHDATA64 op (which should always be 0 using this
467 _debug("extract data length (MSW)");
468 ret = afs_extract_data(call, &call->tmp, 4, true);
472 req->actual_len = ntohl(call->tmp);
473 req->actual_len <<= 32;
478 /* extract the returned data length */
480 _debug("extract data length");
481 ret = afs_extract_data(call, &call->tmp, 4, true);
485 req->actual_len |= ntohl(call->tmp);
486 _debug("DATA length: %llu", req->actual_len);
488 req->remain = req->actual_len;
489 call->offset = req->pos & (PAGE_SIZE - 1);
491 if (req->actual_len == 0)
496 ASSERTCMP(req->index, <, req->nr_pages);
497 if (req->remain > PAGE_SIZE - call->offset)
498 size = PAGE_SIZE - call->offset;
501 call->count = call->offset + size;
502 ASSERTCMP(call->count, <=, PAGE_SIZE);
505 /* extract the returned data */
507 _debug("extract data %llu/%llu %zu/%u",
508 req->remain, req->actual_len, call->offset, call->count);
510 buffer = kmap(req->pages[req->index]);
511 ret = afs_extract_data(call, buffer, call->count, true);
512 kunmap(req->pages[req->index]);
515 if (call->offset == PAGE_SIZE) {
517 req->page_done(call, req);
519 if (req->remain > 0) {
521 if (req->index >= req->nr_pages) {
522 call->unmarshall = 4;
530 /* Discard any excess data the server gave us */
533 size = min_t(loff_t, sizeof(afs_discard_buffer), req->remain);
535 _debug("extract discard %llu/%llu %zu/%u",
536 req->remain, req->actual_len, call->offset, call->count);
539 ret = afs_extract_data(call, afs_discard_buffer, call->count, true);
540 req->remain -= call->offset;
548 call->unmarshall = 5;
550 /* extract the metadata */
552 ret = afs_extract_data(call, call->buffer,
553 (21 + 3 + 6) * 4, false);
558 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
559 &vnode->status.data_version, req) < 0)
560 return afs_protocol_error(call, -EBADMSG);
561 xdr_decode_AFSCallBack(call, vnode, &bp);
563 xdr_decode_AFSVolSync(&bp, call->reply[1]);
572 for (; req->index < req->nr_pages; req->index++) {
573 if (call->count < PAGE_SIZE)
574 zero_user_segment(req->pages[req->index],
575 call->count, PAGE_SIZE);
577 req->page_done(call, req);
581 _leave(" = 0 [done]");
585 static void afs_fetch_data_destructor(struct afs_call *call)
587 struct afs_read *req = call->reply[2];
590 afs_flat_call_destructor(call);
594 * FS.FetchData operation type
596 static const struct afs_call_type afs_RXFSFetchData = {
597 .name = "FS.FetchData",
598 .op = afs_FS_FetchData,
599 .deliver = afs_deliver_fs_fetch_data,
600 .destructor = afs_fetch_data_destructor,
603 static const struct afs_call_type afs_RXFSFetchData64 = {
604 .name = "FS.FetchData64",
605 .op = afs_FS_FetchData64,
606 .deliver = afs_deliver_fs_fetch_data,
607 .destructor = afs_fetch_data_destructor,
611 * fetch data from a very large file
613 static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
615 struct afs_vnode *vnode = fc->vnode;
616 struct afs_call *call;
617 struct afs_net *net = afs_v2net(vnode);
622 call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
627 call->reply[0] = vnode;
628 call->reply[1] = NULL; /* volsync */
629 call->reply[2] = req;
630 call->expected_version = vnode->status.data_version;
632 /* marshall the parameters */
634 bp[0] = htonl(FSFETCHDATA64);
635 bp[1] = htonl(vnode->fid.vid);
636 bp[2] = htonl(vnode->fid.vnode);
637 bp[3] = htonl(vnode->fid.unique);
638 bp[4] = htonl(upper_32_bits(req->pos));
639 bp[5] = htonl(lower_32_bits(req->pos));
641 bp[7] = htonl(lower_32_bits(req->len));
643 refcount_inc(&req->usage);
644 call->cb_break = fc->cb_break;
645 afs_use_fs_server(call, fc->cbi);
646 trace_afs_make_fs_call(call, &vnode->fid);
647 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
651 * fetch data from a file
653 int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
655 struct afs_vnode *vnode = fc->vnode;
656 struct afs_call *call;
657 struct afs_net *net = afs_v2net(vnode);
660 if (upper_32_bits(req->pos) ||
661 upper_32_bits(req->len) ||
662 upper_32_bits(req->pos + req->len))
663 return afs_fs_fetch_data64(fc, req);
667 call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
672 call->reply[0] = vnode;
673 call->reply[1] = NULL; /* volsync */
674 call->reply[2] = req;
675 call->expected_version = vnode->status.data_version;
677 /* marshall the parameters */
679 bp[0] = htonl(FSFETCHDATA);
680 bp[1] = htonl(vnode->fid.vid);
681 bp[2] = htonl(vnode->fid.vnode);
682 bp[3] = htonl(vnode->fid.unique);
683 bp[4] = htonl(lower_32_bits(req->pos));
684 bp[5] = htonl(lower_32_bits(req->len));
686 refcount_inc(&req->usage);
687 call->cb_break = fc->cb_break;
688 afs_use_fs_server(call, fc->cbi);
689 trace_afs_make_fs_call(call, &vnode->fid);
690 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
694 * deliver reply data to an FS.CreateFile or an FS.MakeDir
696 static int afs_deliver_fs_create_vnode(struct afs_call *call)
698 struct afs_vnode *vnode = call->reply[0];
702 _enter("{%u}", call->unmarshall);
704 ret = afs_transfer_reply(call);
708 /* unmarshall the reply once we've received all of it */
710 xdr_decode_AFSFid(&bp, call->reply[1]);
711 if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 ||
712 xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
713 &call->expected_version, NULL) < 0)
714 return afs_protocol_error(call, -EBADMSG);
715 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
716 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
718 _leave(" = 0 [done]");
723 * FS.CreateFile and FS.MakeDir operation type
725 static const struct afs_call_type afs_RXFSCreateFile = {
726 .name = "FS.CreateFile",
727 .op = afs_FS_CreateFile,
728 .deliver = afs_deliver_fs_create_vnode,
729 .destructor = afs_flat_call_destructor,
732 static const struct afs_call_type afs_RXFSMakeDir = {
733 .name = "FS.MakeDir",
734 .op = afs_FS_MakeDir,
735 .deliver = afs_deliver_fs_create_vnode,
736 .destructor = afs_flat_call_destructor,
740 * create a file or make a directory
742 int afs_fs_create(struct afs_fs_cursor *fc,
745 u64 current_data_version,
746 struct afs_fid *newfid,
747 struct afs_file_status *newstatus,
748 struct afs_callback *newcb)
750 struct afs_vnode *vnode = fc->vnode;
751 struct afs_call *call;
752 struct afs_net *net = afs_v2net(vnode);
753 size_t namesz, reqsz, padsz;
758 namesz = strlen(name);
759 padsz = (4 - (namesz & 3)) & 3;
760 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
762 call = afs_alloc_flat_call(
763 net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile,
764 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
769 call->reply[0] = vnode;
770 call->reply[1] = newfid;
771 call->reply[2] = newstatus;
772 call->reply[3] = newcb;
773 call->expected_version = current_data_version + 1;
775 /* marshall the parameters */
777 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
778 *bp++ = htonl(vnode->fid.vid);
779 *bp++ = htonl(vnode->fid.vnode);
780 *bp++ = htonl(vnode->fid.unique);
781 *bp++ = htonl(namesz);
782 memcpy(bp, name, namesz);
783 bp = (void *) bp + namesz;
785 memset(bp, 0, padsz);
786 bp = (void *) bp + padsz;
788 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
789 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
790 *bp++ = 0; /* owner */
791 *bp++ = 0; /* group */
792 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
793 *bp++ = 0; /* segment size */
795 afs_use_fs_server(call, fc->cbi);
796 trace_afs_make_fs_call(call, &vnode->fid);
797 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
801 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
803 static int afs_deliver_fs_remove(struct afs_call *call)
805 struct afs_vnode *vnode = call->reply[0];
809 _enter("{%u}", call->unmarshall);
811 ret = afs_transfer_reply(call);
815 /* unmarshall the reply once we've received all of it */
817 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
818 &call->expected_version, NULL) < 0)
819 return afs_protocol_error(call, -EBADMSG);
820 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
822 _leave(" = 0 [done]");
827 * FS.RemoveDir/FS.RemoveFile operation type
829 static const struct afs_call_type afs_RXFSRemoveFile = {
830 .name = "FS.RemoveFile",
831 .op = afs_FS_RemoveFile,
832 .deliver = afs_deliver_fs_remove,
833 .destructor = afs_flat_call_destructor,
836 static const struct afs_call_type afs_RXFSRemoveDir = {
837 .name = "FS.RemoveDir",
838 .op = afs_FS_RemoveDir,
839 .deliver = afs_deliver_fs_remove,
840 .destructor = afs_flat_call_destructor,
844 * remove a file or directory
846 int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir,
847 u64 current_data_version)
849 struct afs_vnode *vnode = fc->vnode;
850 struct afs_call *call;
851 struct afs_net *net = afs_v2net(vnode);
852 size_t namesz, reqsz, padsz;
857 namesz = strlen(name);
858 padsz = (4 - (namesz & 3)) & 3;
859 reqsz = (5 * 4) + namesz + padsz;
861 call = afs_alloc_flat_call(
862 net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile,
863 reqsz, (21 + 6) * 4);
868 call->reply[0] = vnode;
869 call->expected_version = current_data_version + 1;
871 /* marshall the parameters */
873 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
874 *bp++ = htonl(vnode->fid.vid);
875 *bp++ = htonl(vnode->fid.vnode);
876 *bp++ = htonl(vnode->fid.unique);
877 *bp++ = htonl(namesz);
878 memcpy(bp, name, namesz);
879 bp = (void *) bp + namesz;
881 memset(bp, 0, padsz);
882 bp = (void *) bp + padsz;
885 afs_use_fs_server(call, fc->cbi);
886 trace_afs_make_fs_call(call, &vnode->fid);
887 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
891 * deliver reply data to an FS.Link
893 static int afs_deliver_fs_link(struct afs_call *call)
895 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
899 _enter("{%u}", call->unmarshall);
901 ret = afs_transfer_reply(call);
905 /* unmarshall the reply once we've received all of it */
907 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 ||
908 xdr_decode_AFSFetchStatus(call, &bp, &dvnode->status, dvnode,
909 &call->expected_version, NULL) < 0)
910 return afs_protocol_error(call, -EBADMSG);
911 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
913 _leave(" = 0 [done]");
918 * FS.Link operation type
920 static const struct afs_call_type afs_RXFSLink = {
923 .deliver = afs_deliver_fs_link,
924 .destructor = afs_flat_call_destructor,
930 int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
931 const char *name, u64 current_data_version)
933 struct afs_vnode *dvnode = fc->vnode;
934 struct afs_call *call;
935 struct afs_net *net = afs_v2net(vnode);
936 size_t namesz, reqsz, padsz;
941 namesz = strlen(name);
942 padsz = (4 - (namesz & 3)) & 3;
943 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
945 call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
950 call->reply[0] = dvnode;
951 call->reply[1] = vnode;
952 call->expected_version = current_data_version + 1;
954 /* marshall the parameters */
956 *bp++ = htonl(FSLINK);
957 *bp++ = htonl(dvnode->fid.vid);
958 *bp++ = htonl(dvnode->fid.vnode);
959 *bp++ = htonl(dvnode->fid.unique);
960 *bp++ = htonl(namesz);
961 memcpy(bp, name, namesz);
962 bp = (void *) bp + namesz;
964 memset(bp, 0, padsz);
965 bp = (void *) bp + padsz;
967 *bp++ = htonl(vnode->fid.vid);
968 *bp++ = htonl(vnode->fid.vnode);
969 *bp++ = htonl(vnode->fid.unique);
971 afs_use_fs_server(call, fc->cbi);
972 trace_afs_make_fs_call(call, &vnode->fid);
973 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
977 * deliver reply data to an FS.Symlink
979 static int afs_deliver_fs_symlink(struct afs_call *call)
981 struct afs_vnode *vnode = call->reply[0];
985 _enter("{%u}", call->unmarshall);
987 ret = afs_transfer_reply(call);
991 /* unmarshall the reply once we've received all of it */
993 xdr_decode_AFSFid(&bp, call->reply[1]);
994 if (xdr_decode_AFSFetchStatus(call, &bp, call->reply[2], NULL, NULL, NULL) ||
995 xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
996 &call->expected_version, NULL) < 0)
997 return afs_protocol_error(call, -EBADMSG);
998 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1000 _leave(" = 0 [done]");
1005 * FS.Symlink operation type
1007 static const struct afs_call_type afs_RXFSSymlink = {
1008 .name = "FS.Symlink",
1009 .op = afs_FS_Symlink,
1010 .deliver = afs_deliver_fs_symlink,
1011 .destructor = afs_flat_call_destructor,
1015 * create a symbolic link
1017 int afs_fs_symlink(struct afs_fs_cursor *fc,
1019 const char *contents,
1020 u64 current_data_version,
1021 struct afs_fid *newfid,
1022 struct afs_file_status *newstatus)
1024 struct afs_vnode *vnode = fc->vnode;
1025 struct afs_call *call;
1026 struct afs_net *net = afs_v2net(vnode);
1027 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
1032 namesz = strlen(name);
1033 padsz = (4 - (namesz & 3)) & 3;
1035 c_namesz = strlen(contents);
1036 c_padsz = (4 - (c_namesz & 3)) & 3;
1038 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
1040 call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,
1041 (3 + 21 + 21 + 6) * 4);
1045 call->key = fc->key;
1046 call->reply[0] = vnode;
1047 call->reply[1] = newfid;
1048 call->reply[2] = newstatus;
1049 call->expected_version = current_data_version + 1;
1051 /* marshall the parameters */
1053 *bp++ = htonl(FSSYMLINK);
1054 *bp++ = htonl(vnode->fid.vid);
1055 *bp++ = htonl(vnode->fid.vnode);
1056 *bp++ = htonl(vnode->fid.unique);
1057 *bp++ = htonl(namesz);
1058 memcpy(bp, name, namesz);
1059 bp = (void *) bp + namesz;
1061 memset(bp, 0, padsz);
1062 bp = (void *) bp + padsz;
1064 *bp++ = htonl(c_namesz);
1065 memcpy(bp, contents, c_namesz);
1066 bp = (void *) bp + c_namesz;
1068 memset(bp, 0, c_padsz);
1069 bp = (void *) bp + c_padsz;
1071 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
1072 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1073 *bp++ = 0; /* owner */
1074 *bp++ = 0; /* group */
1075 *bp++ = htonl(S_IRWXUGO); /* unix mode */
1076 *bp++ = 0; /* segment size */
1078 afs_use_fs_server(call, fc->cbi);
1079 trace_afs_make_fs_call(call, &vnode->fid);
1080 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1084 * deliver reply data to an FS.Rename
1086 static int afs_deliver_fs_rename(struct afs_call *call)
1088 struct afs_vnode *orig_dvnode = call->reply[0], *new_dvnode = call->reply[1];
1092 _enter("{%u}", call->unmarshall);
1094 ret = afs_transfer_reply(call);
1098 /* unmarshall the reply once we've received all of it */
1100 if (xdr_decode_AFSFetchStatus(call, &bp, &orig_dvnode->status, orig_dvnode,
1101 &call->expected_version, NULL) < 0)
1102 return afs_protocol_error(call, -EBADMSG);
1103 if (new_dvnode != orig_dvnode &&
1104 xdr_decode_AFSFetchStatus(call, &bp, &new_dvnode->status, new_dvnode,
1105 &call->expected_version_2, NULL) < 0)
1106 return afs_protocol_error(call, -EBADMSG);
1107 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1109 _leave(" = 0 [done]");
1114 * FS.Rename operation type
1116 static const struct afs_call_type afs_RXFSRename = {
1117 .name = "FS.Rename",
1118 .op = afs_FS_Rename,
1119 .deliver = afs_deliver_fs_rename,
1120 .destructor = afs_flat_call_destructor,
1124 * create a symbolic link
1126 int afs_fs_rename(struct afs_fs_cursor *fc,
1127 const char *orig_name,
1128 struct afs_vnode *new_dvnode,
1129 const char *new_name,
1130 u64 current_orig_data_version,
1131 u64 current_new_data_version)
1133 struct afs_vnode *orig_dvnode = fc->vnode;
1134 struct afs_call *call;
1135 struct afs_net *net = afs_v2net(orig_dvnode);
1136 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1141 o_namesz = strlen(orig_name);
1142 o_padsz = (4 - (o_namesz & 3)) & 3;
1144 n_namesz = strlen(new_name);
1145 n_padsz = (4 - (n_namesz & 3)) & 3;
1148 4 + o_namesz + o_padsz +
1150 4 + n_namesz + n_padsz;
1152 call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1156 call->key = fc->key;
1157 call->reply[0] = orig_dvnode;
1158 call->reply[1] = new_dvnode;
1159 call->expected_version = current_orig_data_version + 1;
1160 call->expected_version_2 = current_new_data_version + 1;
1162 /* marshall the parameters */
1164 *bp++ = htonl(FSRENAME);
1165 *bp++ = htonl(orig_dvnode->fid.vid);
1166 *bp++ = htonl(orig_dvnode->fid.vnode);
1167 *bp++ = htonl(orig_dvnode->fid.unique);
1168 *bp++ = htonl(o_namesz);
1169 memcpy(bp, orig_name, o_namesz);
1170 bp = (void *) bp + o_namesz;
1172 memset(bp, 0, o_padsz);
1173 bp = (void *) bp + o_padsz;
1176 *bp++ = htonl(new_dvnode->fid.vid);
1177 *bp++ = htonl(new_dvnode->fid.vnode);
1178 *bp++ = htonl(new_dvnode->fid.unique);
1179 *bp++ = htonl(n_namesz);
1180 memcpy(bp, new_name, n_namesz);
1181 bp = (void *) bp + n_namesz;
1183 memset(bp, 0, n_padsz);
1184 bp = (void *) bp + n_padsz;
1187 afs_use_fs_server(call, fc->cbi);
1188 trace_afs_make_fs_call(call, &orig_dvnode->fid);
1189 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1193 * deliver reply data to an FS.StoreData
1195 static int afs_deliver_fs_store_data(struct afs_call *call)
1197 struct afs_vnode *vnode = call->reply[0];
1203 ret = afs_transfer_reply(call);
1207 /* unmarshall the reply once we've received all of it */
1209 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
1210 &call->expected_version, NULL) < 0)
1211 return afs_protocol_error(call, -EBADMSG);
1212 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1214 afs_pages_written_back(vnode, call);
1216 _leave(" = 0 [done]");
1221 * FS.StoreData operation type
1223 static const struct afs_call_type afs_RXFSStoreData = {
1224 .name = "FS.StoreData",
1225 .op = afs_FS_StoreData,
1226 .deliver = afs_deliver_fs_store_data,
1227 .destructor = afs_flat_call_destructor,
1230 static const struct afs_call_type afs_RXFSStoreData64 = {
1231 .name = "FS.StoreData64",
1232 .op = afs_FS_StoreData64,
1233 .deliver = afs_deliver_fs_store_data,
1234 .destructor = afs_flat_call_destructor,
1238 * store a set of pages to a very large file
1240 static int afs_fs_store_data64(struct afs_fs_cursor *fc,
1241 struct address_space *mapping,
1242 pgoff_t first, pgoff_t last,
1243 unsigned offset, unsigned to,
1244 loff_t size, loff_t pos, loff_t i_size)
1246 struct afs_vnode *vnode = fc->vnode;
1247 struct afs_call *call;
1248 struct afs_net *net = afs_v2net(vnode);
1251 _enter(",%x,{%x:%u},,",
1252 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1254 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,
1255 (4 + 6 + 3 * 2) * 4,
1260 call->key = fc->key;
1261 call->mapping = mapping;
1262 call->reply[0] = vnode;
1263 call->first = first;
1265 call->first_offset = offset;
1267 call->send_pages = true;
1268 call->expected_version = vnode->status.data_version + 1;
1270 /* marshall the parameters */
1272 *bp++ = htonl(FSSTOREDATA64);
1273 *bp++ = htonl(vnode->fid.vid);
1274 *bp++ = htonl(vnode->fid.vnode);
1275 *bp++ = htonl(vnode->fid.unique);
1277 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1278 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1279 *bp++ = 0; /* owner */
1280 *bp++ = 0; /* group */
1281 *bp++ = 0; /* unix mode */
1282 *bp++ = 0; /* segment size */
1284 *bp++ = htonl(pos >> 32);
1285 *bp++ = htonl((u32) pos);
1286 *bp++ = htonl(size >> 32);
1287 *bp++ = htonl((u32) size);
1288 *bp++ = htonl(i_size >> 32);
1289 *bp++ = htonl((u32) i_size);
1291 trace_afs_make_fs_call(call, &vnode->fid);
1292 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1296 * store a set of pages
1298 int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1299 pgoff_t first, pgoff_t last,
1300 unsigned offset, unsigned to)
1302 struct afs_vnode *vnode = fc->vnode;
1303 struct afs_call *call;
1304 struct afs_net *net = afs_v2net(vnode);
1305 loff_t size, pos, i_size;
1308 _enter(",%x,{%x:%u},,",
1309 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1311 size = (loff_t)to - (loff_t)offset;
1313 size += (loff_t)(last - first) << PAGE_SHIFT;
1314 pos = (loff_t)first << PAGE_SHIFT;
1317 i_size = i_size_read(&vnode->vfs_inode);
1318 if (pos + size > i_size)
1319 i_size = size + pos;
1321 _debug("size %llx, at %llx, i_size %llx",
1322 (unsigned long long) size, (unsigned long long) pos,
1323 (unsigned long long) i_size);
1325 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1326 return afs_fs_store_data64(fc, mapping, first, last, offset, to,
1329 call = afs_alloc_flat_call(net, &afs_RXFSStoreData,
1335 call->key = fc->key;
1336 call->mapping = mapping;
1337 call->reply[0] = vnode;
1338 call->first = first;
1340 call->first_offset = offset;
1342 call->send_pages = true;
1343 call->expected_version = vnode->status.data_version + 1;
1345 /* marshall the parameters */
1347 *bp++ = htonl(FSSTOREDATA);
1348 *bp++ = htonl(vnode->fid.vid);
1349 *bp++ = htonl(vnode->fid.vnode);
1350 *bp++ = htonl(vnode->fid.unique);
1352 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1353 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1354 *bp++ = 0; /* owner */
1355 *bp++ = 0; /* group */
1356 *bp++ = 0; /* unix mode */
1357 *bp++ = 0; /* segment size */
1360 *bp++ = htonl(size);
1361 *bp++ = htonl(i_size);
1363 afs_use_fs_server(call, fc->cbi);
1364 trace_afs_make_fs_call(call, &vnode->fid);
1365 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1369 * deliver reply data to an FS.StoreStatus
1371 static int afs_deliver_fs_store_status(struct afs_call *call)
1373 struct afs_vnode *vnode = call->reply[0];
1379 ret = afs_transfer_reply(call);
1383 /* unmarshall the reply once we've received all of it */
1385 if (xdr_decode_AFSFetchStatus(call, &bp, &vnode->status, vnode,
1386 &call->expected_version, NULL) < 0)
1387 return afs_protocol_error(call, -EBADMSG);
1388 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1390 _leave(" = 0 [done]");
1395 * FS.StoreStatus operation type
1397 static const struct afs_call_type afs_RXFSStoreStatus = {
1398 .name = "FS.StoreStatus",
1399 .op = afs_FS_StoreStatus,
1400 .deliver = afs_deliver_fs_store_status,
1401 .destructor = afs_flat_call_destructor,
1404 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1405 .name = "FS.StoreData",
1406 .op = afs_FS_StoreData,
1407 .deliver = afs_deliver_fs_store_status,
1408 .destructor = afs_flat_call_destructor,
1411 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1412 .name = "FS.StoreData64",
1413 .op = afs_FS_StoreData64,
1414 .deliver = afs_deliver_fs_store_status,
1415 .destructor = afs_flat_call_destructor,
1419 * set the attributes on a very large file, using FS.StoreData rather than
1420 * FS.StoreStatus so as to alter the file size also
1422 static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
1424 struct afs_vnode *vnode = fc->vnode;
1425 struct afs_call *call;
1426 struct afs_net *net = afs_v2net(vnode);
1429 _enter(",%x,{%x:%u},,",
1430 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1432 ASSERT(attr->ia_valid & ATTR_SIZE);
1434 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,
1435 (4 + 6 + 3 * 2) * 4,
1440 call->key = fc->key;
1441 call->reply[0] = vnode;
1442 call->expected_version = vnode->status.data_version + 1;
1444 /* marshall the parameters */
1446 *bp++ = htonl(FSSTOREDATA64);
1447 *bp++ = htonl(vnode->fid.vid);
1448 *bp++ = htonl(vnode->fid.vnode);
1449 *bp++ = htonl(vnode->fid.unique);
1451 xdr_encode_AFS_StoreStatus(&bp, attr);
1453 *bp++ = 0; /* position of start of write */
1455 *bp++ = 0; /* size of write */
1457 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1458 *bp++ = htonl((u32) attr->ia_size);
1460 afs_use_fs_server(call, fc->cbi);
1461 trace_afs_make_fs_call(call, &vnode->fid);
1462 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1466 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1467 * so as to alter the file size also
1469 static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1471 struct afs_vnode *vnode = fc->vnode;
1472 struct afs_call *call;
1473 struct afs_net *net = afs_v2net(vnode);
1476 _enter(",%x,{%x:%u},,",
1477 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1479 ASSERT(attr->ia_valid & ATTR_SIZE);
1480 if (attr->ia_size >> 32)
1481 return afs_fs_setattr_size64(fc, attr);
1483 call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,
1489 call->key = fc->key;
1490 call->reply[0] = vnode;
1491 call->expected_version = vnode->status.data_version + 1;
1493 /* marshall the parameters */
1495 *bp++ = htonl(FSSTOREDATA);
1496 *bp++ = htonl(vnode->fid.vid);
1497 *bp++ = htonl(vnode->fid.vnode);
1498 *bp++ = htonl(vnode->fid.unique);
1500 xdr_encode_AFS_StoreStatus(&bp, attr);
1502 *bp++ = 0; /* position of start of write */
1503 *bp++ = 0; /* size of write */
1504 *bp++ = htonl(attr->ia_size); /* new file length */
1506 afs_use_fs_server(call, fc->cbi);
1507 trace_afs_make_fs_call(call, &vnode->fid);
1508 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1512 * set the attributes on a file, using FS.StoreData if there's a change in file
1513 * size, and FS.StoreStatus otherwise
1515 int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1517 struct afs_vnode *vnode = fc->vnode;
1518 struct afs_call *call;
1519 struct afs_net *net = afs_v2net(vnode);
1522 if (attr->ia_valid & ATTR_SIZE)
1523 return afs_fs_setattr_size(fc, attr);
1525 _enter(",%x,{%x:%u},,",
1526 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1528 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,
1534 call->key = fc->key;
1535 call->reply[0] = vnode;
1536 call->expected_version = vnode->status.data_version;
1538 /* marshall the parameters */
1540 *bp++ = htonl(FSSTORESTATUS);
1541 *bp++ = htonl(vnode->fid.vid);
1542 *bp++ = htonl(vnode->fid.vnode);
1543 *bp++ = htonl(vnode->fid.unique);
1545 xdr_encode_AFS_StoreStatus(&bp, attr);
1547 afs_use_fs_server(call, fc->cbi);
1548 trace_afs_make_fs_call(call, &vnode->fid);
1549 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1553 * deliver reply data to an FS.GetVolumeStatus
1555 static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1561 _enter("{%u}", call->unmarshall);
1563 switch (call->unmarshall) {
1568 /* extract the returned status record */
1570 _debug("extract status");
1571 ret = afs_extract_data(call, call->buffer,
1577 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply[1]);
1581 /* extract the volume name length */
1583 ret = afs_extract_data(call, &call->tmp, 4, true);
1587 call->count = ntohl(call->tmp);
1588 _debug("volname length: %u", call->count);
1589 if (call->count >= AFSNAMEMAX)
1590 return afs_protocol_error(call, -EBADMSG);
1594 /* extract the volume name */
1596 _debug("extract volname");
1597 if (call->count > 0) {
1598 ret = afs_extract_data(call, call->reply[2],
1606 _debug("volname '%s'", p);
1611 /* extract the volume name padding */
1612 if ((call->count & 3) == 0) {
1614 goto no_volname_padding;
1616 call->count = 4 - (call->count & 3);
1619 ret = afs_extract_data(call, call->buffer,
1628 /* extract the offline message length */
1630 ret = afs_extract_data(call, &call->tmp, 4, true);
1634 call->count = ntohl(call->tmp);
1635 _debug("offline msg length: %u", call->count);
1636 if (call->count >= AFSNAMEMAX)
1637 return afs_protocol_error(call, -EBADMSG);
1641 /* extract the offline message */
1643 _debug("extract offline");
1644 if (call->count > 0) {
1645 ret = afs_extract_data(call, call->reply[2],
1653 _debug("offline '%s'", p);
1658 /* extract the offline message padding */
1659 if ((call->count & 3) == 0) {
1661 goto no_offline_padding;
1663 call->count = 4 - (call->count & 3);
1666 ret = afs_extract_data(call, call->buffer,
1675 /* extract the message of the day length */
1677 ret = afs_extract_data(call, &call->tmp, 4, true);
1681 call->count = ntohl(call->tmp);
1682 _debug("motd length: %u", call->count);
1683 if (call->count >= AFSNAMEMAX)
1684 return afs_protocol_error(call, -EBADMSG);
1688 /* extract the message of the day */
1690 _debug("extract motd");
1691 if (call->count > 0) {
1692 ret = afs_extract_data(call, call->reply[2],
1700 _debug("motd '%s'", p);
1705 /* extract the message of the day padding */
1706 call->count = (4 - (call->count & 3)) & 3;
1709 ret = afs_extract_data(call, call->buffer,
1710 call->count, false);
1720 _leave(" = 0 [done]");
1725 * destroy an FS.GetVolumeStatus call
1727 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1729 kfree(call->reply[2]);
1730 call->reply[2] = NULL;
1731 afs_flat_call_destructor(call);
1735 * FS.GetVolumeStatus operation type
1737 static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1738 .name = "FS.GetVolumeStatus",
1739 .op = afs_FS_GetVolumeStatus,
1740 .deliver = afs_deliver_fs_get_volume_status,
1741 .destructor = afs_get_volume_status_call_destructor,
1745 * fetch the status of a volume
1747 int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
1748 struct afs_volume_status *vs)
1750 struct afs_vnode *vnode = fc->vnode;
1751 struct afs_call *call;
1752 struct afs_net *net = afs_v2net(vnode);
1758 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1762 call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1768 call->key = fc->key;
1769 call->reply[0] = vnode;
1770 call->reply[1] = vs;
1771 call->reply[2] = tmpbuf;
1773 /* marshall the parameters */
1775 bp[0] = htonl(FSGETVOLUMESTATUS);
1776 bp[1] = htonl(vnode->fid.vid);
1778 afs_use_fs_server(call, fc->cbi);
1779 trace_afs_make_fs_call(call, &vnode->fid);
1780 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1784 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1786 static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
1791 _enter("{%u}", call->unmarshall);
1793 ret = afs_transfer_reply(call);
1797 /* unmarshall the reply once we've received all of it */
1799 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1801 _leave(" = 0 [done]");
1806 * FS.SetLock operation type
1808 static const struct afs_call_type afs_RXFSSetLock = {
1809 .name = "FS.SetLock",
1810 .op = afs_FS_SetLock,
1811 .deliver = afs_deliver_fs_xxxx_lock,
1812 .destructor = afs_flat_call_destructor,
1816 * FS.ExtendLock operation type
1818 static const struct afs_call_type afs_RXFSExtendLock = {
1819 .name = "FS.ExtendLock",
1820 .op = afs_FS_ExtendLock,
1821 .deliver = afs_deliver_fs_xxxx_lock,
1822 .destructor = afs_flat_call_destructor,
1826 * FS.ReleaseLock operation type
1828 static const struct afs_call_type afs_RXFSReleaseLock = {
1829 .name = "FS.ReleaseLock",
1830 .op = afs_FS_ReleaseLock,
1831 .deliver = afs_deliver_fs_xxxx_lock,
1832 .destructor = afs_flat_call_destructor,
1836 * Set a lock on a file
1838 int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1840 struct afs_vnode *vnode = fc->vnode;
1841 struct afs_call *call;
1842 struct afs_net *net = afs_v2net(vnode);
1847 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
1851 call->key = fc->key;
1852 call->reply[0] = vnode;
1854 /* marshall the parameters */
1856 *bp++ = htonl(FSSETLOCK);
1857 *bp++ = htonl(vnode->fid.vid);
1858 *bp++ = htonl(vnode->fid.vnode);
1859 *bp++ = htonl(vnode->fid.unique);
1860 *bp++ = htonl(type);
1862 afs_use_fs_server(call, fc->cbi);
1863 trace_afs_make_fs_call(call, &vnode->fid);
1864 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1868 * extend a lock on a file
1870 int afs_fs_extend_lock(struct afs_fs_cursor *fc)
1872 struct afs_vnode *vnode = fc->vnode;
1873 struct afs_call *call;
1874 struct afs_net *net = afs_v2net(vnode);
1879 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
1883 call->key = fc->key;
1884 call->reply[0] = vnode;
1886 /* marshall the parameters */
1888 *bp++ = htonl(FSEXTENDLOCK);
1889 *bp++ = htonl(vnode->fid.vid);
1890 *bp++ = htonl(vnode->fid.vnode);
1891 *bp++ = htonl(vnode->fid.unique);
1893 afs_use_fs_server(call, fc->cbi);
1894 trace_afs_make_fs_call(call, &vnode->fid);
1895 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1899 * release a lock on a file
1901 int afs_fs_release_lock(struct afs_fs_cursor *fc)
1903 struct afs_vnode *vnode = fc->vnode;
1904 struct afs_call *call;
1905 struct afs_net *net = afs_v2net(vnode);
1910 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1914 call->key = fc->key;
1915 call->reply[0] = vnode;
1917 /* marshall the parameters */
1919 *bp++ = htonl(FSRELEASELOCK);
1920 *bp++ = htonl(vnode->fid.vid);
1921 *bp++ = htonl(vnode->fid.vnode);
1922 *bp++ = htonl(vnode->fid.unique);
1924 afs_use_fs_server(call, fc->cbi);
1925 trace_afs_make_fs_call(call, &vnode->fid);
1926 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1930 * Deliver reply data to an FS.GiveUpAllCallBacks operation.
1932 static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)
1934 return afs_transfer_reply(call);
1938 * FS.GiveUpAllCallBacks operation type
1940 static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
1941 .name = "FS.GiveUpAllCallBacks",
1942 .op = afs_FS_GiveUpAllCallBacks,
1943 .deliver = afs_deliver_fs_give_up_all_callbacks,
1944 .destructor = afs_flat_call_destructor,
1948 * Flush all the callbacks we have on a server.
1950 int afs_fs_give_up_all_callbacks(struct afs_net *net,
1951 struct afs_server *server,
1952 struct afs_addr_cursor *ac,
1955 struct afs_call *call;
1960 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);
1966 /* marshall the parameters */
1968 *bp++ = htonl(FSGIVEUPALLCALLBACKS);
1970 /* Can't take a ref on server */
1971 return afs_make_call(ac, call, GFP_NOFS, false);
1975 * Deliver reply data to an FS.GetCapabilities operation.
1977 static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1982 _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count);
1985 switch (call->unmarshall) {
1990 /* Extract the capabilities word count */
1992 ret = afs_extract_data(call, &call->tmp,
1998 count = ntohl(call->tmp);
2000 call->count = count;
2001 call->count2 = count;
2005 /* Extract capabilities words */
2007 count = min(call->count, 16U);
2008 ret = afs_extract_data(call, call->buffer,
2009 count * sizeof(__be32),
2014 /* TODO: Examine capabilities */
2016 call->count -= count;
2017 if (call->count > 0)
2024 _leave(" = 0 [done]");
2029 * FS.GetCapabilities operation type
2031 static const struct afs_call_type afs_RXFSGetCapabilities = {
2032 .name = "FS.GetCapabilities",
2033 .op = afs_FS_GetCapabilities,
2034 .deliver = afs_deliver_fs_get_capabilities,
2035 .destructor = afs_flat_call_destructor,
2039 * Probe a fileserver for the capabilities that it supports. This can
2040 * return up to 196 words.
2042 int afs_fs_get_capabilities(struct afs_net *net,
2043 struct afs_server *server,
2044 struct afs_addr_cursor *ac,
2047 struct afs_call *call;
2052 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
2058 /* marshall the parameters */
2060 *bp++ = htonl(FSGETCAPABILITIES);
2062 /* Can't take a ref on server */
2063 trace_afs_make_fs_call(call, NULL);
2064 return afs_make_call(ac, call, GFP_NOFS, false);
2068 * Deliver reply data to an FS.FetchStatus with no vnode.
2070 static int afs_deliver_fs_fetch_status(struct afs_call *call)
2072 struct afs_file_status *status = call->reply[1];
2073 struct afs_callback *callback = call->reply[2];
2074 struct afs_volsync *volsync = call->reply[3];
2075 struct afs_vnode *vnode = call->reply[0];
2079 ret = afs_transfer_reply(call);
2083 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
2085 /* unmarshall the reply once we've received all of it */
2087 xdr_decode_AFSFetchStatus(call, &bp, status, vnode,
2088 &call->expected_version, NULL);
2089 callback[call->count].version = ntohl(bp[0]);
2090 callback[call->count].expiry = ntohl(bp[1]);
2091 callback[call->count].type = ntohl(bp[2]);
2093 xdr_decode_AFSCallBack(call, vnode, &bp);
2097 xdr_decode_AFSVolSync(&bp, volsync);
2099 _leave(" = 0 [done]");
2104 * FS.FetchStatus operation type
2106 static const struct afs_call_type afs_RXFSFetchStatus = {
2107 .name = "FS.FetchStatus",
2108 .op = afs_FS_FetchStatus,
2109 .deliver = afs_deliver_fs_fetch_status,
2110 .destructor = afs_flat_call_destructor,
2114 * Fetch the status information for a fid without needing a vnode handle.
2116 int afs_fs_fetch_status(struct afs_fs_cursor *fc,
2117 struct afs_net *net,
2118 struct afs_fid *fid,
2119 struct afs_file_status *status,
2120 struct afs_callback *callback,
2121 struct afs_volsync *volsync)
2123 struct afs_call *call;
2126 _enter(",%x,{%x:%u},,",
2127 key_serial(fc->key), fid->vid, fid->vnode);
2129 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
2131 fc->ac.error = -ENOMEM;
2135 call->key = fc->key;
2136 call->reply[0] = NULL; /* vnode for fid[0] */
2137 call->reply[1] = status;
2138 call->reply[2] = callback;
2139 call->reply[3] = volsync;
2140 call->expected_version = 1; /* vnode->status.data_version */
2142 /* marshall the parameters */
2144 bp[0] = htonl(FSFETCHSTATUS);
2145 bp[1] = htonl(fid->vid);
2146 bp[2] = htonl(fid->vnode);
2147 bp[3] = htonl(fid->unique);
2149 call->cb_break = fc->cb_break;
2150 afs_use_fs_server(call, fc->cbi);
2151 trace_afs_make_fs_call(call, fid);
2152 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2156 * Deliver reply data to an FS.InlineBulkStatus call
2158 static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
2160 struct afs_file_status *statuses;
2161 struct afs_callback *callbacks;
2162 struct afs_vnode *vnode = call->reply[0];
2167 _enter("{%u}", call->unmarshall);
2169 switch (call->unmarshall) {
2174 /* Extract the file status count and array in two steps */
2176 _debug("extract status count");
2177 ret = afs_extract_data(call, &call->tmp, 4, true);
2181 tmp = ntohl(call->tmp);
2182 _debug("status count: %u/%u", tmp, call->count2);
2183 if (tmp != call->count2)
2184 return afs_protocol_error(call, -EBADMSG);
2192 _debug("extract status array %u", call->count);
2193 ret = afs_extract_data(call, call->buffer, 21 * 4, true);
2198 statuses = call->reply[1];
2199 if (xdr_decode_AFSFetchStatus(call, &bp, &statuses[call->count],
2200 call->count == 0 ? vnode : NULL,
2202 return afs_protocol_error(call, -EBADMSG);
2205 if (call->count < call->count2)
2212 /* Extract the callback count and array in two steps */
2214 _debug("extract CB count");
2215 ret = afs_extract_data(call, &call->tmp, 4, true);
2219 tmp = ntohl(call->tmp);
2220 _debug("CB count: %u", tmp);
2221 if (tmp != call->count2)
2222 return afs_protocol_error(call, -EBADMSG);
2229 _debug("extract CB array");
2230 ret = afs_extract_data(call, call->buffer, 3 * 4, true);
2234 _debug("unmarshall CB array");
2236 callbacks = call->reply[2];
2237 callbacks[call->count].version = ntohl(bp[0]);
2238 callbacks[call->count].expiry = ntohl(bp[1]);
2239 callbacks[call->count].type = ntohl(bp[2]);
2240 statuses = call->reply[1];
2241 if (call->count == 0 && vnode && statuses[0].abort_code == 0)
2242 xdr_decode_AFSCallBack(call, vnode, &bp);
2244 if (call->count < call->count2)
2251 ret = afs_extract_data(call, call->buffer, 6 * 4, false);
2257 xdr_decode_AFSVolSync(&bp, call->reply[3]);
2266 _leave(" = 0 [done]");
2271 * FS.InlineBulkStatus operation type
2273 static const struct afs_call_type afs_RXFSInlineBulkStatus = {
2274 .name = "FS.InlineBulkStatus",
2275 .op = afs_FS_InlineBulkStatus,
2276 .deliver = afs_deliver_fs_inline_bulk_status,
2277 .destructor = afs_flat_call_destructor,
2281 * Fetch the status information for up to 50 files
2283 int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2284 struct afs_net *net,
2285 struct afs_fid *fids,
2286 struct afs_file_status *statuses,
2287 struct afs_callback *callbacks,
2288 unsigned int nr_fids,
2289 struct afs_volsync *volsync)
2291 struct afs_call *call;
2295 _enter(",%x,{%x:%u},%u",
2296 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2298 call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus,
2299 (2 + nr_fids * 3) * 4,
2302 fc->ac.error = -ENOMEM;
2306 call->key = fc->key;
2307 call->reply[0] = NULL; /* vnode for fid[0] */
2308 call->reply[1] = statuses;
2309 call->reply[2] = callbacks;
2310 call->reply[3] = volsync;
2311 call->count2 = nr_fids;
2313 /* marshall the parameters */
2315 *bp++ = htonl(FSINLINEBULKSTATUS);
2316 *bp++ = htonl(nr_fids);
2317 for (i = 0; i < nr_fids; i++) {
2318 *bp++ = htonl(fids[i].vid);
2319 *bp++ = htonl(fids[i].vnode);
2320 *bp++ = htonl(fids[i].unique);
2323 call->cb_break = fc->cb_break;
2324 afs_use_fs_server(call, fc->cbi);
2325 trace_afs_make_fs_call(call, &fids[0]);
2326 return afs_make_call(&fc->ac, call, GFP_NOFS, false);