1 /* AFS File Server client stubs
3 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
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>
19 static const struct afs_fid afs_zero_fid;
22 * We need somewhere to discard into in case the server helpfully returns more
23 * than we asked for in FS.FetchData{,64}.
25 static u8 afs_discard_buffer[64];
27 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
29 call->cbi = afs_get_cb_interest(cbi);
33 * decode an AFSFid block
35 static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
37 const __be32 *bp = *_bp;
39 fid->vid = ntohl(*bp++);
40 fid->vnode = ntohl(*bp++);
41 fid->unique = ntohl(*bp++);
46 * decode an AFSFetchStatus block
48 static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
49 struct afs_file_status *status,
50 struct afs_vnode *vnode,
51 afs_dataversion_t *store_version)
53 afs_dataversion_t expected_version;
54 const __be32 *bp = *_bp;
56 u64 data_version, size;
62 write_seqlock(&vnode->cb_lock);
64 #define EXTRACT(DST) \
66 u32 x = ntohl(*bp++); \
72 status->if_version = ntohl(*bp++);
73 EXTRACT(status->type);
74 EXTRACT(status->nlink);
76 data_version = ntohl(*bp++);
77 EXTRACT(status->author);
78 owner = make_kuid(&init_user_ns, ntohl(*bp++));
79 changed |= !uid_eq(owner, status->owner);
80 status->owner = owner;
81 EXTRACT(status->caller_access); /* call ticket dependent */
82 EXTRACT(status->anon_access);
83 EXTRACT(status->mode);
84 bp++; /* parent.vnode */
85 bp++; /* parent.unique */
87 status->mtime_client = ntohl(*bp++);
88 status->mtime_server = ntohl(*bp++);
89 group = make_kgid(&init_user_ns, ntohl(*bp++));
90 changed |= !gid_eq(group, status->group);
91 status->group = group;
92 bp++; /* sync counter */
93 data_version |= (u64) ntohl(*bp++) << 32;
94 EXTRACT(status->lock_count);
95 size |= (u64) ntohl(*bp++) << 32;
99 if (size != status->size) {
103 status->mode &= S_IALLUGO;
105 _debug("vnode time %lx, %lx",
106 status->mtime_client, status->mtime_server);
109 if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
110 _debug("vnode changed");
111 i_size_write(&vnode->vfs_inode, size);
112 vnode->vfs_inode.i_uid = status->owner;
113 vnode->vfs_inode.i_gid = status->group;
114 vnode->vfs_inode.i_generation = vnode->fid.unique;
115 set_nlink(&vnode->vfs_inode, status->nlink);
117 mode = vnode->vfs_inode.i_mode;
119 mode |= status->mode;
121 vnode->vfs_inode.i_mode = mode;
124 vnode->vfs_inode.i_ctime.tv_sec = status->mtime_client;
125 vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime;
126 vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime;
127 vnode->vfs_inode.i_version = data_version;
130 expected_version = status->data_version;
132 expected_version = *store_version;
134 if (expected_version != data_version) {
135 status->data_version = data_version;
136 if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
137 _debug("vnode modified %llx on {%x:%u}",
138 (unsigned long long) data_version,
139 vnode->fid.vid, vnode->fid.vnode);
140 set_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags);
141 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
143 } else if (store_version) {
144 status->data_version = data_version;
148 write_sequnlock(&vnode->cb_lock);
152 * decode an AFSCallBack block
154 static void xdr_decode_AFSCallBack(struct afs_call *call,
155 struct afs_vnode *vnode,
158 struct afs_cb_interest *old, *cbi = call->cbi;
159 const __be32 *bp = *_bp;
162 write_seqlock(&vnode->cb_lock);
164 if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) {
165 vnode->cb_version = ntohl(*bp++);
166 cb_expiry = ntohl(*bp++);
167 vnode->cb_type = ntohl(*bp++);
168 vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds();
169 old = vnode->cb_interest;
170 if (old != call->cbi) {
171 vnode->cb_interest = cbi;
174 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
179 write_sequnlock(&vnode->cb_lock);
184 static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
185 struct afs_callback *cb)
187 const __be32 *bp = *_bp;
189 cb->version = ntohl(*bp++);
190 cb->expiry = ntohl(*bp++);
191 cb->type = ntohl(*bp++);
196 * decode an AFSVolSync block
198 static void xdr_decode_AFSVolSync(const __be32 **_bp,
199 struct afs_volsync *volsync)
201 const __be32 *bp = *_bp;
203 volsync->creation = ntohl(*bp++);
213 * encode the requested attributes into an AFSStoreStatus block
215 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
218 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
221 if (attr->ia_valid & ATTR_MTIME) {
222 mask |= AFS_SET_MTIME;
223 mtime = attr->ia_mtime.tv_sec;
226 if (attr->ia_valid & ATTR_UID) {
227 mask |= AFS_SET_OWNER;
228 owner = from_kuid(&init_user_ns, attr->ia_uid);
231 if (attr->ia_valid & ATTR_GID) {
232 mask |= AFS_SET_GROUP;
233 group = from_kgid(&init_user_ns, attr->ia_gid);
236 if (attr->ia_valid & ATTR_MODE) {
237 mask |= AFS_SET_MODE;
238 mode = attr->ia_mode & S_IALLUGO;
242 *bp++ = htonl(mtime);
243 *bp++ = htonl(owner);
244 *bp++ = htonl(group);
246 *bp++ = 0; /* segment size */
251 * decode an AFSFetchVolumeStatus block
253 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
254 struct afs_volume_status *vs)
256 const __be32 *bp = *_bp;
258 vs->vid = ntohl(*bp++);
259 vs->parent_id = ntohl(*bp++);
260 vs->online = ntohl(*bp++);
261 vs->in_service = ntohl(*bp++);
262 vs->blessed = ntohl(*bp++);
263 vs->needs_salvage = ntohl(*bp++);
264 vs->type = ntohl(*bp++);
265 vs->min_quota = ntohl(*bp++);
266 vs->max_quota = ntohl(*bp++);
267 vs->blocks_in_use = ntohl(*bp++);
268 vs->part_blocks_avail = ntohl(*bp++);
269 vs->part_max_blocks = ntohl(*bp++);
274 * deliver reply data to an FS.FetchStatus
276 static int afs_deliver_fs_fetch_status(struct afs_call *call)
278 struct afs_vnode *vnode = call->reply[0];
282 ret = afs_transfer_reply(call);
286 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
288 /* unmarshall the reply once we've received all of it */
290 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
291 xdr_decode_AFSCallBack(call, vnode, &bp);
293 xdr_decode_AFSVolSync(&bp, call->reply[1]);
295 _leave(" = 0 [done]");
300 * FS.FetchStatus operation type
302 static const struct afs_call_type afs_RXFSFetchStatus = {
303 .name = "FS.FetchStatus",
304 .op = afs_FS_FetchStatus,
305 .deliver = afs_deliver_fs_fetch_status,
306 .destructor = afs_flat_call_destructor,
310 * fetch the status information for a file
312 int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync)
314 struct afs_vnode *vnode = fc->vnode;
315 struct afs_call *call;
316 struct afs_net *net = afs_v2net(vnode);
319 _enter(",%x,{%x:%u},,",
320 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
322 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
324 fc->ac.error = -ENOMEM;
329 call->reply[0] = vnode;
330 call->reply[1] = volsync;
332 /* marshall the parameters */
334 bp[0] = htonl(FSFETCHSTATUS);
335 bp[1] = htonl(vnode->fid.vid);
336 bp[2] = htonl(vnode->fid.vnode);
337 bp[3] = htonl(vnode->fid.unique);
339 call->cb_break = fc->cb_break;
340 afs_use_fs_server(call, fc->cbi);
341 trace_afs_make_fs_call(call, &vnode->fid);
342 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
346 * deliver reply data to an FS.FetchData
348 static int afs_deliver_fs_fetch_data(struct afs_call *call)
350 struct afs_vnode *vnode = call->reply[0];
351 struct afs_read *req = call->reply[2];
357 _enter("{%u,%zu/%u;%llu/%llu}",
358 call->unmarshall, call->offset, call->count,
359 req->remain, req->actual_len);
361 switch (call->unmarshall) {
366 if (call->operation_ID != FSFETCHDATA64) {
371 /* extract the upper part of the returned data length of an
372 * FSFETCHDATA64 op (which should always be 0 using this
375 _debug("extract data length (MSW)");
376 ret = afs_extract_data(call, &call->tmp, 4, true);
380 req->actual_len = ntohl(call->tmp);
381 req->actual_len <<= 32;
386 /* extract the returned data length */
388 _debug("extract data length");
389 ret = afs_extract_data(call, &call->tmp, 4, true);
393 req->actual_len |= ntohl(call->tmp);
394 _debug("DATA length: %llu", req->actual_len);
396 req->remain = req->actual_len;
397 call->offset = req->pos & (PAGE_SIZE - 1);
399 if (req->actual_len == 0)
404 ASSERTCMP(req->index, <, req->nr_pages);
405 if (req->remain > PAGE_SIZE - call->offset)
406 size = PAGE_SIZE - call->offset;
409 call->count = call->offset + size;
410 ASSERTCMP(call->count, <=, PAGE_SIZE);
413 /* extract the returned data */
415 _debug("extract data %llu/%llu %zu/%u",
416 req->remain, req->actual_len, call->offset, call->count);
418 buffer = kmap(req->pages[req->index]);
419 ret = afs_extract_data(call, buffer, call->count, true);
420 kunmap(req->pages[req->index]);
423 if (call->offset == PAGE_SIZE) {
425 req->page_done(call, req);
427 if (req->remain > 0) {
429 if (req->index >= req->nr_pages) {
430 call->unmarshall = 4;
438 /* Discard any excess data the server gave us */
441 size = min_t(loff_t, sizeof(afs_discard_buffer), req->remain);
443 _debug("extract discard %llu/%llu %zu/%u",
444 req->remain, req->actual_len, call->offset, call->count);
447 ret = afs_extract_data(call, afs_discard_buffer, call->count, true);
448 req->remain -= call->offset;
456 call->unmarshall = 5;
458 /* extract the metadata */
460 ret = afs_extract_data(call, call->buffer,
461 (21 + 3 + 6) * 4, false);
466 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
467 xdr_decode_AFSCallBack(call, vnode, &bp);
469 xdr_decode_AFSVolSync(&bp, call->reply[1]);
478 for (; req->index < req->nr_pages; req->index++) {
479 if (call->count < PAGE_SIZE)
480 zero_user_segment(req->pages[req->index],
481 call->count, PAGE_SIZE);
483 req->page_done(call, req);
487 _leave(" = 0 [done]");
491 static void afs_fetch_data_destructor(struct afs_call *call)
493 struct afs_read *req = call->reply[2];
496 afs_flat_call_destructor(call);
500 * FS.FetchData operation type
502 static const struct afs_call_type afs_RXFSFetchData = {
503 .name = "FS.FetchData",
504 .op = afs_FS_FetchData,
505 .deliver = afs_deliver_fs_fetch_data,
506 .destructor = afs_fetch_data_destructor,
509 static const struct afs_call_type afs_RXFSFetchData64 = {
510 .name = "FS.FetchData64",
511 .op = afs_FS_FetchData64,
512 .deliver = afs_deliver_fs_fetch_data,
513 .destructor = afs_fetch_data_destructor,
517 * fetch data from a very large file
519 static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
521 struct afs_vnode *vnode = fc->vnode;
522 struct afs_call *call;
523 struct afs_net *net = afs_v2net(vnode);
528 call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
533 call->reply[0] = vnode;
534 call->reply[1] = NULL; /* volsync */
535 call->reply[2] = req;
537 /* marshall the parameters */
539 bp[0] = htonl(FSFETCHDATA64);
540 bp[1] = htonl(vnode->fid.vid);
541 bp[2] = htonl(vnode->fid.vnode);
542 bp[3] = htonl(vnode->fid.unique);
543 bp[4] = htonl(upper_32_bits(req->pos));
544 bp[5] = htonl(lower_32_bits(req->pos));
546 bp[7] = htonl(lower_32_bits(req->len));
548 atomic_inc(&req->usage);
549 call->cb_break = fc->cb_break;
550 afs_use_fs_server(call, fc->cbi);
551 trace_afs_make_fs_call(call, &vnode->fid);
552 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
556 * fetch data from a file
558 int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
560 struct afs_vnode *vnode = fc->vnode;
561 struct afs_call *call;
562 struct afs_net *net = afs_v2net(vnode);
565 if (upper_32_bits(req->pos) ||
566 upper_32_bits(req->len) ||
567 upper_32_bits(req->pos + req->len))
568 return afs_fs_fetch_data64(fc, req);
572 call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
577 call->reply[0] = vnode;
578 call->reply[1] = NULL; /* volsync */
579 call->reply[2] = req;
581 /* marshall the parameters */
583 bp[0] = htonl(FSFETCHDATA);
584 bp[1] = htonl(vnode->fid.vid);
585 bp[2] = htonl(vnode->fid.vnode);
586 bp[3] = htonl(vnode->fid.unique);
587 bp[4] = htonl(lower_32_bits(req->pos));
588 bp[5] = htonl(lower_32_bits(req->len));
590 atomic_inc(&req->usage);
591 call->cb_break = fc->cb_break;
592 afs_use_fs_server(call, fc->cbi);
593 trace_afs_make_fs_call(call, &vnode->fid);
594 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
598 * deliver reply data to an FS.CreateFile or an FS.MakeDir
600 static int afs_deliver_fs_create_vnode(struct afs_call *call)
602 struct afs_vnode *vnode = call->reply[0];
606 _enter("{%u}", call->unmarshall);
608 ret = afs_transfer_reply(call);
612 /* unmarshall the reply once we've received all of it */
614 xdr_decode_AFSFid(&bp, call->reply[1]);
615 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
616 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
617 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
618 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
620 _leave(" = 0 [done]");
625 * FS.CreateFile and FS.MakeDir operation type
627 static const struct afs_call_type afs_RXFSCreateFile = {
628 .name = "FS.CreateFile",
629 .op = afs_FS_CreateFile,
630 .deliver = afs_deliver_fs_create_vnode,
631 .destructor = afs_flat_call_destructor,
634 static const struct afs_call_type afs_RXFSMakeDir = {
635 .name = "FS.MakeDir",
636 .op = afs_FS_MakeDir,
637 .deliver = afs_deliver_fs_create_vnode,
638 .destructor = afs_flat_call_destructor,
642 * create a file or make a directory
644 int afs_fs_create(struct afs_fs_cursor *fc,
647 struct afs_fid *newfid,
648 struct afs_file_status *newstatus,
649 struct afs_callback *newcb)
651 struct afs_vnode *vnode = fc->vnode;
652 struct afs_call *call;
653 struct afs_net *net = afs_v2net(vnode);
654 size_t namesz, reqsz, padsz;
659 namesz = strlen(name);
660 padsz = (4 - (namesz & 3)) & 3;
661 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
663 call = afs_alloc_flat_call(
664 net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile,
665 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
670 call->reply[0] = vnode;
671 call->reply[1] = newfid;
672 call->reply[2] = newstatus;
673 call->reply[3] = newcb;
675 /* marshall the parameters */
677 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
678 *bp++ = htonl(vnode->fid.vid);
679 *bp++ = htonl(vnode->fid.vnode);
680 *bp++ = htonl(vnode->fid.unique);
681 *bp++ = htonl(namesz);
682 memcpy(bp, name, namesz);
683 bp = (void *) bp + namesz;
685 memset(bp, 0, padsz);
686 bp = (void *) bp + padsz;
688 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
689 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
690 *bp++ = 0; /* owner */
691 *bp++ = 0; /* group */
692 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
693 *bp++ = 0; /* segment size */
695 afs_use_fs_server(call, fc->cbi);
696 trace_afs_make_fs_call(call, &vnode->fid);
697 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
701 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
703 static int afs_deliver_fs_remove(struct afs_call *call)
705 struct afs_vnode *vnode = call->reply[0];
709 _enter("{%u}", call->unmarshall);
711 ret = afs_transfer_reply(call);
715 /* unmarshall the reply once we've received all of it */
717 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
718 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
720 _leave(" = 0 [done]");
725 * FS.RemoveDir/FS.RemoveFile operation type
727 static const struct afs_call_type afs_RXFSRemoveFile = {
728 .name = "FS.RemoveFile",
729 .op = afs_FS_RemoveFile,
730 .deliver = afs_deliver_fs_remove,
731 .destructor = afs_flat_call_destructor,
734 static const struct afs_call_type afs_RXFSRemoveDir = {
735 .name = "FS.RemoveDir",
736 .op = afs_FS_RemoveDir,
737 .deliver = afs_deliver_fs_remove,
738 .destructor = afs_flat_call_destructor,
742 * remove a file or directory
744 int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir)
746 struct afs_vnode *vnode = fc->vnode;
747 struct afs_call *call;
748 struct afs_net *net = afs_v2net(vnode);
749 size_t namesz, reqsz, padsz;
754 namesz = strlen(name);
755 padsz = (4 - (namesz & 3)) & 3;
756 reqsz = (5 * 4) + namesz + padsz;
758 call = afs_alloc_flat_call(
759 net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile,
760 reqsz, (21 + 6) * 4);
765 call->reply[0] = vnode;
767 /* marshall the parameters */
769 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
770 *bp++ = htonl(vnode->fid.vid);
771 *bp++ = htonl(vnode->fid.vnode);
772 *bp++ = htonl(vnode->fid.unique);
773 *bp++ = htonl(namesz);
774 memcpy(bp, name, namesz);
775 bp = (void *) bp + namesz;
777 memset(bp, 0, padsz);
778 bp = (void *) bp + padsz;
781 afs_use_fs_server(call, fc->cbi);
782 trace_afs_make_fs_call(call, &vnode->fid);
783 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
787 * deliver reply data to an FS.Link
789 static int afs_deliver_fs_link(struct afs_call *call)
791 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
795 _enter("{%u}", call->unmarshall);
797 ret = afs_transfer_reply(call);
801 /* unmarshall the reply once we've received all of it */
803 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
804 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
805 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
807 _leave(" = 0 [done]");
812 * FS.Link operation type
814 static const struct afs_call_type afs_RXFSLink = {
817 .deliver = afs_deliver_fs_link,
818 .destructor = afs_flat_call_destructor,
824 int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
827 struct afs_vnode *dvnode = fc->vnode;
828 struct afs_call *call;
829 struct afs_net *net = afs_v2net(vnode);
830 size_t namesz, reqsz, padsz;
835 namesz = strlen(name);
836 padsz = (4 - (namesz & 3)) & 3;
837 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
839 call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
844 call->reply[0] = dvnode;
845 call->reply[1] = vnode;
847 /* marshall the parameters */
849 *bp++ = htonl(FSLINK);
850 *bp++ = htonl(dvnode->fid.vid);
851 *bp++ = htonl(dvnode->fid.vnode);
852 *bp++ = htonl(dvnode->fid.unique);
853 *bp++ = htonl(namesz);
854 memcpy(bp, name, namesz);
855 bp = (void *) bp + namesz;
857 memset(bp, 0, padsz);
858 bp = (void *) bp + padsz;
860 *bp++ = htonl(vnode->fid.vid);
861 *bp++ = htonl(vnode->fid.vnode);
862 *bp++ = htonl(vnode->fid.unique);
864 afs_use_fs_server(call, fc->cbi);
865 trace_afs_make_fs_call(call, &vnode->fid);
866 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
870 * deliver reply data to an FS.Symlink
872 static int afs_deliver_fs_symlink(struct afs_call *call)
874 struct afs_vnode *vnode = call->reply[0];
878 _enter("{%u}", call->unmarshall);
880 ret = afs_transfer_reply(call);
884 /* unmarshall the reply once we've received all of it */
886 xdr_decode_AFSFid(&bp, call->reply[1]);
887 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
888 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
889 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
891 _leave(" = 0 [done]");
896 * FS.Symlink operation type
898 static const struct afs_call_type afs_RXFSSymlink = {
899 .name = "FS.Symlink",
900 .op = afs_FS_Symlink,
901 .deliver = afs_deliver_fs_symlink,
902 .destructor = afs_flat_call_destructor,
906 * create a symbolic link
908 int afs_fs_symlink(struct afs_fs_cursor *fc,
910 const char *contents,
911 struct afs_fid *newfid,
912 struct afs_file_status *newstatus)
914 struct afs_vnode *vnode = fc->vnode;
915 struct afs_call *call;
916 struct afs_net *net = afs_v2net(vnode);
917 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
922 namesz = strlen(name);
923 padsz = (4 - (namesz & 3)) & 3;
925 c_namesz = strlen(contents);
926 c_padsz = (4 - (c_namesz & 3)) & 3;
928 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
930 call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,
931 (3 + 21 + 21 + 6) * 4);
936 call->reply[0] = vnode;
937 call->reply[1] = newfid;
938 call->reply[2] = newstatus;
940 /* marshall the parameters */
942 *bp++ = htonl(FSSYMLINK);
943 *bp++ = htonl(vnode->fid.vid);
944 *bp++ = htonl(vnode->fid.vnode);
945 *bp++ = htonl(vnode->fid.unique);
946 *bp++ = htonl(namesz);
947 memcpy(bp, name, namesz);
948 bp = (void *) bp + namesz;
950 memset(bp, 0, padsz);
951 bp = (void *) bp + padsz;
953 *bp++ = htonl(c_namesz);
954 memcpy(bp, contents, c_namesz);
955 bp = (void *) bp + c_namesz;
957 memset(bp, 0, c_padsz);
958 bp = (void *) bp + c_padsz;
960 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
961 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
962 *bp++ = 0; /* owner */
963 *bp++ = 0; /* group */
964 *bp++ = htonl(S_IRWXUGO); /* unix mode */
965 *bp++ = 0; /* segment size */
967 afs_use_fs_server(call, fc->cbi);
968 trace_afs_make_fs_call(call, &vnode->fid);
969 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
973 * deliver reply data to an FS.Rename
975 static int afs_deliver_fs_rename(struct afs_call *call)
977 struct afs_vnode *orig_dvnode = call->reply[0], *new_dvnode = call->reply[1];
981 _enter("{%u}", call->unmarshall);
983 ret = afs_transfer_reply(call);
987 /* unmarshall the reply once we've received all of it */
989 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
990 if (new_dvnode != orig_dvnode)
991 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
993 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
995 _leave(" = 0 [done]");
1000 * FS.Rename operation type
1002 static const struct afs_call_type afs_RXFSRename = {
1003 .name = "FS.Rename",
1004 .op = afs_FS_Rename,
1005 .deliver = afs_deliver_fs_rename,
1006 .destructor = afs_flat_call_destructor,
1010 * create a symbolic link
1012 int afs_fs_rename(struct afs_fs_cursor *fc,
1013 const char *orig_name,
1014 struct afs_vnode *new_dvnode,
1015 const char *new_name)
1017 struct afs_vnode *orig_dvnode = fc->vnode;
1018 struct afs_call *call;
1019 struct afs_net *net = afs_v2net(orig_dvnode);
1020 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1025 o_namesz = strlen(orig_name);
1026 o_padsz = (4 - (o_namesz & 3)) & 3;
1028 n_namesz = strlen(new_name);
1029 n_padsz = (4 - (n_namesz & 3)) & 3;
1032 4 + o_namesz + o_padsz +
1034 4 + n_namesz + n_padsz;
1036 call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1040 call->key = fc->key;
1041 call->reply[0] = orig_dvnode;
1042 call->reply[1] = new_dvnode;
1044 /* marshall the parameters */
1046 *bp++ = htonl(FSRENAME);
1047 *bp++ = htonl(orig_dvnode->fid.vid);
1048 *bp++ = htonl(orig_dvnode->fid.vnode);
1049 *bp++ = htonl(orig_dvnode->fid.unique);
1050 *bp++ = htonl(o_namesz);
1051 memcpy(bp, orig_name, o_namesz);
1052 bp = (void *) bp + o_namesz;
1054 memset(bp, 0, o_padsz);
1055 bp = (void *) bp + o_padsz;
1058 *bp++ = htonl(new_dvnode->fid.vid);
1059 *bp++ = htonl(new_dvnode->fid.vnode);
1060 *bp++ = htonl(new_dvnode->fid.unique);
1061 *bp++ = htonl(n_namesz);
1062 memcpy(bp, new_name, n_namesz);
1063 bp = (void *) bp + n_namesz;
1065 memset(bp, 0, n_padsz);
1066 bp = (void *) bp + n_padsz;
1069 afs_use_fs_server(call, fc->cbi);
1070 trace_afs_make_fs_call(call, &orig_dvnode->fid);
1071 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1075 * deliver reply data to an FS.StoreData
1077 static int afs_deliver_fs_store_data(struct afs_call *call)
1079 struct afs_vnode *vnode = call->reply[0];
1085 ret = afs_transfer_reply(call);
1089 /* unmarshall the reply once we've received all of it */
1091 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1092 &call->store_version);
1093 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1095 afs_pages_written_back(vnode, call);
1097 _leave(" = 0 [done]");
1102 * FS.StoreData operation type
1104 static const struct afs_call_type afs_RXFSStoreData = {
1105 .name = "FS.StoreData",
1106 .op = afs_FS_StoreData,
1107 .deliver = afs_deliver_fs_store_data,
1108 .destructor = afs_flat_call_destructor,
1111 static const struct afs_call_type afs_RXFSStoreData64 = {
1112 .name = "FS.StoreData64",
1113 .op = afs_FS_StoreData64,
1114 .deliver = afs_deliver_fs_store_data,
1115 .destructor = afs_flat_call_destructor,
1119 * store a set of pages to a very large file
1121 static int afs_fs_store_data64(struct afs_fs_cursor *fc,
1122 struct address_space *mapping,
1123 pgoff_t first, pgoff_t last,
1124 unsigned offset, unsigned to,
1125 loff_t size, loff_t pos, loff_t i_size)
1127 struct afs_vnode *vnode = fc->vnode;
1128 struct afs_call *call;
1129 struct afs_net *net = afs_v2net(vnode);
1132 _enter(",%x,{%x:%u},,",
1133 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1135 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,
1136 (4 + 6 + 3 * 2) * 4,
1141 call->key = fc->key;
1142 call->mapping = mapping;
1143 call->reply[0] = vnode;
1144 call->first = first;
1146 call->first_offset = offset;
1148 call->send_pages = true;
1149 call->store_version = vnode->status.data_version + 1;
1151 /* marshall the parameters */
1153 *bp++ = htonl(FSSTOREDATA64);
1154 *bp++ = htonl(vnode->fid.vid);
1155 *bp++ = htonl(vnode->fid.vnode);
1156 *bp++ = htonl(vnode->fid.unique);
1158 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1159 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1160 *bp++ = 0; /* owner */
1161 *bp++ = 0; /* group */
1162 *bp++ = 0; /* unix mode */
1163 *bp++ = 0; /* segment size */
1165 *bp++ = htonl(pos >> 32);
1166 *bp++ = htonl((u32) pos);
1167 *bp++ = htonl(size >> 32);
1168 *bp++ = htonl((u32) size);
1169 *bp++ = htonl(i_size >> 32);
1170 *bp++ = htonl((u32) i_size);
1172 trace_afs_make_fs_call(call, &vnode->fid);
1173 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1177 * store a set of pages
1179 int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1180 pgoff_t first, pgoff_t last,
1181 unsigned offset, unsigned to)
1183 struct afs_vnode *vnode = fc->vnode;
1184 struct afs_call *call;
1185 struct afs_net *net = afs_v2net(vnode);
1186 loff_t size, pos, i_size;
1189 _enter(",%x,{%x:%u},,",
1190 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1192 size = (loff_t)to - (loff_t)offset;
1194 size += (loff_t)(last - first) << PAGE_SHIFT;
1195 pos = (loff_t)first << PAGE_SHIFT;
1198 i_size = i_size_read(&vnode->vfs_inode);
1199 if (pos + size > i_size)
1200 i_size = size + pos;
1202 _debug("size %llx, at %llx, i_size %llx",
1203 (unsigned long long) size, (unsigned long long) pos,
1204 (unsigned long long) i_size);
1206 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1207 return afs_fs_store_data64(fc, mapping, first, last, offset, to,
1210 call = afs_alloc_flat_call(net, &afs_RXFSStoreData,
1216 call->key = fc->key;
1217 call->mapping = mapping;
1218 call->reply[0] = vnode;
1219 call->first = first;
1221 call->first_offset = offset;
1223 call->send_pages = true;
1224 call->store_version = vnode->status.data_version + 1;
1226 /* marshall the parameters */
1228 *bp++ = htonl(FSSTOREDATA);
1229 *bp++ = htonl(vnode->fid.vid);
1230 *bp++ = htonl(vnode->fid.vnode);
1231 *bp++ = htonl(vnode->fid.unique);
1233 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1234 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1235 *bp++ = 0; /* owner */
1236 *bp++ = 0; /* group */
1237 *bp++ = 0; /* unix mode */
1238 *bp++ = 0; /* segment size */
1241 *bp++ = htonl(size);
1242 *bp++ = htonl(i_size);
1244 afs_use_fs_server(call, fc->cbi);
1245 trace_afs_make_fs_call(call, &vnode->fid);
1246 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1250 * deliver reply data to an FS.StoreStatus
1252 static int afs_deliver_fs_store_status(struct afs_call *call)
1254 afs_dataversion_t *store_version;
1255 struct afs_vnode *vnode = call->reply[0];
1261 ret = afs_transfer_reply(call);
1265 /* unmarshall the reply once we've received all of it */
1266 store_version = NULL;
1267 if (call->operation_ID == FSSTOREDATA)
1268 store_version = &call->store_version;
1271 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1272 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1274 _leave(" = 0 [done]");
1279 * FS.StoreStatus operation type
1281 static const struct afs_call_type afs_RXFSStoreStatus = {
1282 .name = "FS.StoreStatus",
1283 .op = afs_FS_StoreStatus,
1284 .deliver = afs_deliver_fs_store_status,
1285 .destructor = afs_flat_call_destructor,
1288 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1289 .name = "FS.StoreData",
1290 .op = afs_FS_StoreData,
1291 .deliver = afs_deliver_fs_store_status,
1292 .destructor = afs_flat_call_destructor,
1295 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1296 .name = "FS.StoreData64",
1297 .op = afs_FS_StoreData64,
1298 .deliver = afs_deliver_fs_store_status,
1299 .destructor = afs_flat_call_destructor,
1303 * set the attributes on a very large file, using FS.StoreData rather than
1304 * FS.StoreStatus so as to alter the file size also
1306 static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
1308 struct afs_vnode *vnode = fc->vnode;
1309 struct afs_call *call;
1310 struct afs_net *net = afs_v2net(vnode);
1313 _enter(",%x,{%x:%u},,",
1314 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1316 ASSERT(attr->ia_valid & ATTR_SIZE);
1318 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,
1319 (4 + 6 + 3 * 2) * 4,
1324 call->key = fc->key;
1325 call->reply[0] = vnode;
1326 call->store_version = vnode->status.data_version + 1;
1328 /* marshall the parameters */
1330 *bp++ = htonl(FSSTOREDATA64);
1331 *bp++ = htonl(vnode->fid.vid);
1332 *bp++ = htonl(vnode->fid.vnode);
1333 *bp++ = htonl(vnode->fid.unique);
1335 xdr_encode_AFS_StoreStatus(&bp, attr);
1337 *bp++ = 0; /* position of start of write */
1339 *bp++ = 0; /* size of write */
1341 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1342 *bp++ = htonl((u32) attr->ia_size);
1344 afs_use_fs_server(call, fc->cbi);
1345 trace_afs_make_fs_call(call, &vnode->fid);
1346 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1350 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1351 * so as to alter the file size also
1353 static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1355 struct afs_vnode *vnode = fc->vnode;
1356 struct afs_call *call;
1357 struct afs_net *net = afs_v2net(vnode);
1360 _enter(",%x,{%x:%u},,",
1361 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1363 ASSERT(attr->ia_valid & ATTR_SIZE);
1364 if (attr->ia_size >> 32)
1365 return afs_fs_setattr_size64(fc, attr);
1367 call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,
1373 call->key = fc->key;
1374 call->reply[0] = vnode;
1375 call->store_version = vnode->status.data_version + 1;
1377 /* marshall the parameters */
1379 *bp++ = htonl(FSSTOREDATA);
1380 *bp++ = htonl(vnode->fid.vid);
1381 *bp++ = htonl(vnode->fid.vnode);
1382 *bp++ = htonl(vnode->fid.unique);
1384 xdr_encode_AFS_StoreStatus(&bp, attr);
1386 *bp++ = 0; /* position of start of write */
1387 *bp++ = 0; /* size of write */
1388 *bp++ = htonl(attr->ia_size); /* new file length */
1390 afs_use_fs_server(call, fc->cbi);
1391 trace_afs_make_fs_call(call, &vnode->fid);
1392 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1396 * set the attributes on a file, using FS.StoreData if there's a change in file
1397 * size, and FS.StoreStatus otherwise
1399 int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1401 struct afs_vnode *vnode = fc->vnode;
1402 struct afs_call *call;
1403 struct afs_net *net = afs_v2net(vnode);
1406 if (attr->ia_valid & ATTR_SIZE)
1407 return afs_fs_setattr_size(fc, attr);
1409 _enter(",%x,{%x:%u},,",
1410 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1412 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,
1418 call->key = fc->key;
1419 call->reply[0] = vnode;
1421 /* marshall the parameters */
1423 *bp++ = htonl(FSSTORESTATUS);
1424 *bp++ = htonl(vnode->fid.vid);
1425 *bp++ = htonl(vnode->fid.vnode);
1426 *bp++ = htonl(vnode->fid.unique);
1428 xdr_encode_AFS_StoreStatus(&bp, attr);
1430 afs_use_fs_server(call, fc->cbi);
1431 trace_afs_make_fs_call(call, &vnode->fid);
1432 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1436 * deliver reply data to an FS.GetVolumeStatus
1438 static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1444 _enter("{%u}", call->unmarshall);
1446 switch (call->unmarshall) {
1451 /* extract the returned status record */
1453 _debug("extract status");
1454 ret = afs_extract_data(call, call->buffer,
1460 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply[1]);
1464 /* extract the volume name length */
1466 ret = afs_extract_data(call, &call->tmp, 4, true);
1470 call->count = ntohl(call->tmp);
1471 _debug("volname length: %u", call->count);
1472 if (call->count >= AFSNAMEMAX)
1477 /* extract the volume name */
1479 _debug("extract volname");
1480 if (call->count > 0) {
1481 ret = afs_extract_data(call, call->reply[2],
1489 _debug("volname '%s'", p);
1494 /* extract the volume name padding */
1495 if ((call->count & 3) == 0) {
1497 goto no_volname_padding;
1499 call->count = 4 - (call->count & 3);
1502 ret = afs_extract_data(call, call->buffer,
1511 /* extract the offline message length */
1513 ret = afs_extract_data(call, &call->tmp, 4, true);
1517 call->count = ntohl(call->tmp);
1518 _debug("offline msg length: %u", call->count);
1519 if (call->count >= AFSNAMEMAX)
1524 /* extract the offline message */
1526 _debug("extract offline");
1527 if (call->count > 0) {
1528 ret = afs_extract_data(call, call->reply[2],
1536 _debug("offline '%s'", p);
1541 /* extract the offline message padding */
1542 if ((call->count & 3) == 0) {
1544 goto no_offline_padding;
1546 call->count = 4 - (call->count & 3);
1549 ret = afs_extract_data(call, call->buffer,
1558 /* extract the message of the day length */
1560 ret = afs_extract_data(call, &call->tmp, 4, true);
1564 call->count = ntohl(call->tmp);
1565 _debug("motd length: %u", call->count);
1566 if (call->count >= AFSNAMEMAX)
1571 /* extract the message of the day */
1573 _debug("extract motd");
1574 if (call->count > 0) {
1575 ret = afs_extract_data(call, call->reply[2],
1583 _debug("motd '%s'", p);
1588 /* extract the message of the day padding */
1589 call->count = (4 - (call->count & 3)) & 3;
1592 ret = afs_extract_data(call, call->buffer,
1593 call->count, false);
1603 _leave(" = 0 [done]");
1608 * destroy an FS.GetVolumeStatus call
1610 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1612 kfree(call->reply[2]);
1613 call->reply[2] = NULL;
1614 afs_flat_call_destructor(call);
1618 * FS.GetVolumeStatus operation type
1620 static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1621 .name = "FS.GetVolumeStatus",
1622 .op = afs_FS_GetVolumeStatus,
1623 .deliver = afs_deliver_fs_get_volume_status,
1624 .destructor = afs_get_volume_status_call_destructor,
1628 * fetch the status of a volume
1630 int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
1631 struct afs_volume_status *vs)
1633 struct afs_vnode *vnode = fc->vnode;
1634 struct afs_call *call;
1635 struct afs_net *net = afs_v2net(vnode);
1641 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1645 call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1651 call->key = fc->key;
1652 call->reply[0] = vnode;
1653 call->reply[1] = vs;
1654 call->reply[2] = tmpbuf;
1656 /* marshall the parameters */
1658 bp[0] = htonl(FSGETVOLUMESTATUS);
1659 bp[1] = htonl(vnode->fid.vid);
1661 afs_use_fs_server(call, fc->cbi);
1662 trace_afs_make_fs_call(call, &vnode->fid);
1663 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1667 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1669 static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
1674 _enter("{%u}", call->unmarshall);
1676 ret = afs_transfer_reply(call);
1680 /* unmarshall the reply once we've received all of it */
1682 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1684 _leave(" = 0 [done]");
1689 * FS.SetLock operation type
1691 static const struct afs_call_type afs_RXFSSetLock = {
1692 .name = "FS.SetLock",
1693 .op = afs_FS_SetLock,
1694 .deliver = afs_deliver_fs_xxxx_lock,
1695 .destructor = afs_flat_call_destructor,
1699 * FS.ExtendLock operation type
1701 static const struct afs_call_type afs_RXFSExtendLock = {
1702 .name = "FS.ExtendLock",
1703 .op = afs_FS_ExtendLock,
1704 .deliver = afs_deliver_fs_xxxx_lock,
1705 .destructor = afs_flat_call_destructor,
1709 * FS.ReleaseLock operation type
1711 static const struct afs_call_type afs_RXFSReleaseLock = {
1712 .name = "FS.ReleaseLock",
1713 .op = afs_FS_ReleaseLock,
1714 .deliver = afs_deliver_fs_xxxx_lock,
1715 .destructor = afs_flat_call_destructor,
1719 * Set a lock on a file
1721 int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1723 struct afs_vnode *vnode = fc->vnode;
1724 struct afs_call *call;
1725 struct afs_net *net = afs_v2net(vnode);
1730 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
1734 call->key = fc->key;
1735 call->reply[0] = vnode;
1737 /* marshall the parameters */
1739 *bp++ = htonl(FSSETLOCK);
1740 *bp++ = htonl(vnode->fid.vid);
1741 *bp++ = htonl(vnode->fid.vnode);
1742 *bp++ = htonl(vnode->fid.unique);
1743 *bp++ = htonl(type);
1745 afs_use_fs_server(call, fc->cbi);
1746 trace_afs_make_fs_call(call, &vnode->fid);
1747 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1751 * extend a lock on a file
1753 int afs_fs_extend_lock(struct afs_fs_cursor *fc)
1755 struct afs_vnode *vnode = fc->vnode;
1756 struct afs_call *call;
1757 struct afs_net *net = afs_v2net(vnode);
1762 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
1766 call->key = fc->key;
1767 call->reply[0] = vnode;
1769 /* marshall the parameters */
1771 *bp++ = htonl(FSEXTENDLOCK);
1772 *bp++ = htonl(vnode->fid.vid);
1773 *bp++ = htonl(vnode->fid.vnode);
1774 *bp++ = htonl(vnode->fid.unique);
1776 afs_use_fs_server(call, fc->cbi);
1777 trace_afs_make_fs_call(call, &vnode->fid);
1778 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1782 * release a lock on a file
1784 int afs_fs_release_lock(struct afs_fs_cursor *fc)
1786 struct afs_vnode *vnode = fc->vnode;
1787 struct afs_call *call;
1788 struct afs_net *net = afs_v2net(vnode);
1793 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1797 call->key = fc->key;
1798 call->reply[0] = vnode;
1800 /* marshall the parameters */
1802 *bp++ = htonl(FSRELEASELOCK);
1803 *bp++ = htonl(vnode->fid.vid);
1804 *bp++ = htonl(vnode->fid.vnode);
1805 *bp++ = htonl(vnode->fid.unique);
1807 afs_use_fs_server(call, fc->cbi);
1808 trace_afs_make_fs_call(call, &vnode->fid);
1809 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1813 * Deliver reply data to an FS.GiveUpAllCallBacks operation.
1815 static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)
1817 return afs_transfer_reply(call);
1821 * FS.GiveUpAllCallBacks operation type
1823 static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
1824 .name = "FS.GiveUpAllCallBacks",
1825 .op = afs_FS_GiveUpAllCallBacks,
1826 .deliver = afs_deliver_fs_give_up_all_callbacks,
1827 .destructor = afs_flat_call_destructor,
1831 * Flush all the callbacks we have on a server.
1833 int afs_fs_give_up_all_callbacks(struct afs_net *net,
1834 struct afs_server *server,
1835 struct afs_addr_cursor *ac,
1838 struct afs_call *call;
1843 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);
1849 /* marshall the parameters */
1851 *bp++ = htonl(FSGIVEUPALLCALLBACKS);
1853 /* Can't take a ref on server */
1854 return afs_make_call(ac, call, GFP_NOFS, false);
1858 * Deliver reply data to an FS.GetCapabilities operation.
1860 static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1865 _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count);
1868 switch (call->unmarshall) {
1873 /* Extract the capabilities word count */
1875 ret = afs_extract_data(call, &call->tmp,
1881 count = ntohl(call->tmp);
1883 call->count = count;
1884 call->count2 = count;
1888 /* Extract capabilities words */
1890 count = min(call->count, 16U);
1891 ret = afs_extract_data(call, call->buffer,
1892 count * sizeof(__be32),
1897 /* TODO: Examine capabilities */
1899 call->count -= count;
1900 if (call->count > 0)
1907 _leave(" = 0 [done]");
1912 * FS.GetCapabilities operation type
1914 static const struct afs_call_type afs_RXFSGetCapabilities = {
1915 .name = "FS.GetCapabilities",
1916 .op = afs_FS_GetCapabilities,
1917 .deliver = afs_deliver_fs_get_capabilities,
1918 .destructor = afs_flat_call_destructor,
1922 * Probe a fileserver for the capabilities that it supports. This can
1923 * return up to 196 words.
1925 int afs_fs_get_capabilities(struct afs_net *net,
1926 struct afs_server *server,
1927 struct afs_addr_cursor *ac,
1930 struct afs_call *call;
1935 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
1941 /* marshall the parameters */
1943 *bp++ = htonl(FSGETCAPABILITIES);
1945 /* Can't take a ref on server */
1946 trace_afs_make_fs_call(call, NULL);
1947 return afs_make_call(ac, call, GFP_NOFS, false);