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 EXTRACT(status->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 * decode an AFSFetchVolumeStatus block
207 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
208 struct afs_volume_status *vs)
210 const __be32 *bp = *_bp;
212 vs->vid = ntohl(*bp++);
213 vs->parent_id = ntohl(*bp++);
214 vs->online = ntohl(*bp++);
215 vs->in_service = ntohl(*bp++);
216 vs->blessed = ntohl(*bp++);
217 vs->needs_salvage = ntohl(*bp++);
218 vs->type = ntohl(*bp++);
219 vs->min_quota = ntohl(*bp++);
220 vs->max_quota = ntohl(*bp++);
221 vs->blocks_in_use = ntohl(*bp++);
222 vs->part_blocks_avail = ntohl(*bp++);
223 vs->part_max_blocks = ntohl(*bp++);
228 * deliver reply data to an FS.FetchStatus
230 static int afs_deliver_fs_fetch_status(struct afs_call *call,
231 struct sk_buff *skb, bool last)
233 struct afs_vnode *vnode = call->reply;
236 _enter(",,%u", last);
238 afs_transfer_reply(call, skb);
242 if (call->reply_size != call->reply_max)
245 /* unmarshall the reply once we've received all of it */
247 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
248 xdr_decode_AFSCallBack(&bp, vnode);
250 xdr_decode_AFSVolSync(&bp, call->reply2);
252 _leave(" = 0 [done]");
257 * FS.FetchStatus operation type
259 static const struct afs_call_type afs_RXFSFetchStatus = {
260 .name = "FS.FetchStatus",
261 .deliver = afs_deliver_fs_fetch_status,
262 .abort_to_error = afs_abort_to_error,
263 .destructor = afs_flat_call_destructor,
267 * fetch the status information for a file
269 int afs_fs_fetch_file_status(struct afs_server *server,
271 struct afs_vnode *vnode,
272 struct afs_volsync *volsync,
273 const struct afs_wait_mode *wait_mode)
275 struct afs_call *call;
278 _enter(",%x,{%x:%u},,",
279 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
281 call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
287 call->reply2 = volsync;
288 call->service_id = FS_SERVICE;
289 call->port = htons(AFS_FS_PORT);
291 /* marshall the parameters */
293 bp[0] = htonl(FSFETCHSTATUS);
294 bp[1] = htonl(vnode->fid.vid);
295 bp[2] = htonl(vnode->fid.vnode);
296 bp[3] = htonl(vnode->fid.unique);
298 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
302 * deliver reply data to an FS.FetchData
304 static int afs_deliver_fs_fetch_data(struct afs_call *call,
305 struct sk_buff *skb, bool last)
307 struct afs_vnode *vnode = call->reply;
313 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
315 switch (call->unmarshall) {
319 if (call->operation_ID != FSFETCHDATA64) {
324 /* extract the upper part of the returned data length of an
325 * FSFETCHDATA64 op (which should always be 0 using this
328 _debug("extract data length (MSW)");
329 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
332 case -EAGAIN: return 0;
336 call->count = ntohl(call->tmp);
337 _debug("DATA length MSW: %u", call->count);
344 /* extract the returned data length */
346 _debug("extract data length");
347 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
350 case -EAGAIN: return 0;
354 call->count = ntohl(call->tmp);
355 _debug("DATA length: %u", call->count);
356 if (call->count > PAGE_SIZE)
361 /* extract the returned data */
363 _debug("extract data");
364 if (call->count > 0) {
366 buffer = kmap_atomic(page, KM_USER0);
367 ret = afs_extract_data(call, skb, last, buffer,
369 kunmap_atomic(buffer, KM_USER0);
372 case -EAGAIN: return 0;
380 /* extract the metadata */
382 ret = afs_extract_data(call, skb, last, call->buffer,
386 case -EAGAIN: return 0;
391 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
392 xdr_decode_AFSCallBack(&bp, vnode);
394 xdr_decode_AFSVolSync(&bp, call->reply2);
409 if (call->count < PAGE_SIZE) {
412 buffer = kmap_atomic(page, KM_USER0);
413 memset(buffer + call->count, 0, PAGE_SIZE - call->count);
414 kunmap_atomic(buffer, KM_USER0);
417 _leave(" = 0 [done]");
422 * FS.FetchData operation type
424 static const struct afs_call_type afs_RXFSFetchData = {
425 .name = "FS.FetchData",
426 .deliver = afs_deliver_fs_fetch_data,
427 .abort_to_error = afs_abort_to_error,
428 .destructor = afs_flat_call_destructor,
431 static const struct afs_call_type afs_RXFSFetchData64 = {
432 .name = "FS.FetchData64",
433 .deliver = afs_deliver_fs_fetch_data,
434 .abort_to_error = afs_abort_to_error,
435 .destructor = afs_flat_call_destructor,
439 * fetch data from a very large file
441 static int afs_fs_fetch_data64(struct afs_server *server,
443 struct afs_vnode *vnode,
444 off_t offset, size_t length,
446 const struct afs_wait_mode *wait_mode)
448 struct afs_call *call;
453 ASSERTCMP(length, <, ULONG_MAX);
455 call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
461 call->reply2 = NULL; /* volsync */
462 call->reply3 = buffer;
463 call->service_id = FS_SERVICE;
464 call->port = htons(AFS_FS_PORT);
465 call->operation_ID = FSFETCHDATA64;
467 /* marshall the parameters */
469 bp[0] = htonl(FSFETCHDATA64);
470 bp[1] = htonl(vnode->fid.vid);
471 bp[2] = htonl(vnode->fid.vnode);
472 bp[3] = htonl(vnode->fid.unique);
473 bp[4] = htonl(upper_32_bits(offset));
474 bp[5] = htonl((u32) offset);
476 bp[7] = htonl((u32) length);
478 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
482 * fetch data from a file
484 int afs_fs_fetch_data(struct afs_server *server,
486 struct afs_vnode *vnode,
487 off_t offset, size_t length,
489 const struct afs_wait_mode *wait_mode)
491 struct afs_call *call;
494 if (upper_32_bits(offset) || upper_32_bits(offset + length))
495 return afs_fs_fetch_data64(server, key, vnode, offset, length,
500 call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
506 call->reply2 = NULL; /* volsync */
507 call->reply3 = buffer;
508 call->service_id = FS_SERVICE;
509 call->port = htons(AFS_FS_PORT);
510 call->operation_ID = FSFETCHDATA;
512 /* marshall the parameters */
514 bp[0] = htonl(FSFETCHDATA);
515 bp[1] = htonl(vnode->fid.vid);
516 bp[2] = htonl(vnode->fid.vnode);
517 bp[3] = htonl(vnode->fid.unique);
518 bp[4] = htonl(offset);
519 bp[5] = htonl(length);
521 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
525 * deliver reply data to an FS.GiveUpCallBacks
527 static int afs_deliver_fs_give_up_callbacks(struct afs_call *call,
528 struct sk_buff *skb, bool last)
530 _enter(",{%u},%d", skb->len, last);
533 return -EBADMSG; /* shouldn't be any reply data */
538 * FS.GiveUpCallBacks operation type
540 static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
541 .name = "FS.GiveUpCallBacks",
542 .deliver = afs_deliver_fs_give_up_callbacks,
543 .abort_to_error = afs_abort_to_error,
544 .destructor = afs_flat_call_destructor,
548 * give up a set of callbacks
549 * - the callbacks are held in the server->cb_break ring
551 int afs_fs_give_up_callbacks(struct afs_server *server,
552 const struct afs_wait_mode *wait_mode)
554 struct afs_call *call;
559 ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
560 ARRAY_SIZE(server->cb_break));
562 _enter("{%zu},", ncallbacks);
566 if (ncallbacks > AFSCBMAX)
567 ncallbacks = AFSCBMAX;
569 _debug("break %zu callbacks", ncallbacks);
571 call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
572 12 + ncallbacks * 6 * 4, 0);
576 call->service_id = FS_SERVICE;
577 call->port = htons(AFS_FS_PORT);
579 /* marshall the parameters */
581 tp = bp + 2 + ncallbacks * 3;
582 *bp++ = htonl(FSGIVEUPCALLBACKS);
583 *bp++ = htonl(ncallbacks);
584 *tp++ = htonl(ncallbacks);
586 atomic_sub(ncallbacks, &server->cb_break_n);
587 for (loop = ncallbacks; loop > 0; loop--) {
588 struct afs_callback *cb =
589 &server->cb_break[server->cb_break_tail];
591 *bp++ = htonl(cb->fid.vid);
592 *bp++ = htonl(cb->fid.vnode);
593 *bp++ = htonl(cb->fid.unique);
594 *tp++ = htonl(cb->version);
595 *tp++ = htonl(cb->expiry);
596 *tp++ = htonl(cb->type);
598 server->cb_break_tail =
599 (server->cb_break_tail + 1) &
600 (ARRAY_SIZE(server->cb_break) - 1);
603 ASSERT(ncallbacks > 0);
604 wake_up_nr(&server->cb_break_waitq, ncallbacks);
606 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
610 * deliver reply data to an FS.CreateFile or an FS.MakeDir
612 static int afs_deliver_fs_create_vnode(struct afs_call *call,
613 struct sk_buff *skb, bool last)
615 struct afs_vnode *vnode = call->reply;
618 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
620 afs_transfer_reply(call, skb);
624 if (call->reply_size != call->reply_max)
627 /* unmarshall the reply once we've received all of it */
629 xdr_decode_AFSFid(&bp, call->reply2);
630 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
631 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
632 xdr_decode_AFSCallBack_raw(&bp, call->reply4);
633 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
635 _leave(" = 0 [done]");
640 * FS.CreateFile and FS.MakeDir operation type
642 static const struct afs_call_type afs_RXFSCreateXXXX = {
643 .name = "FS.CreateXXXX",
644 .deliver = afs_deliver_fs_create_vnode,
645 .abort_to_error = afs_abort_to_error,
646 .destructor = afs_flat_call_destructor,
650 * create a file or make a directory
652 int afs_fs_create(struct afs_server *server,
654 struct afs_vnode *vnode,
657 struct afs_fid *newfid,
658 struct afs_file_status *newstatus,
659 struct afs_callback *newcb,
660 const struct afs_wait_mode *wait_mode)
662 struct afs_call *call;
663 size_t namesz, reqsz, padsz;
668 namesz = strlen(name);
669 padsz = (4 - (namesz & 3)) & 3;
670 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
672 call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
673 (3 + 21 + 21 + 3 + 6) * 4);
679 call->reply2 = newfid;
680 call->reply3 = newstatus;
681 call->reply4 = newcb;
682 call->service_id = FS_SERVICE;
683 call->port = htons(AFS_FS_PORT);
685 /* marshall the parameters */
687 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
688 *bp++ = htonl(vnode->fid.vid);
689 *bp++ = htonl(vnode->fid.vnode);
690 *bp++ = htonl(vnode->fid.unique);
691 *bp++ = htonl(namesz);
692 memcpy(bp, name, namesz);
693 bp = (void *) bp + namesz;
695 memset(bp, 0, padsz);
696 bp = (void *) bp + padsz;
698 *bp++ = htonl(AFS_SET_MODE);
699 *bp++ = 0; /* mtime */
700 *bp++ = 0; /* owner */
701 *bp++ = 0; /* group */
702 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
703 *bp++ = 0; /* segment size */
705 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
709 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
711 static int afs_deliver_fs_remove(struct afs_call *call,
712 struct sk_buff *skb, bool last)
714 struct afs_vnode *vnode = call->reply;
717 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
719 afs_transfer_reply(call, skb);
723 if (call->reply_size != call->reply_max)
726 /* unmarshall the reply once we've received all of it */
728 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
729 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
731 _leave(" = 0 [done]");
736 * FS.RemoveDir/FS.RemoveFile operation type
738 static const struct afs_call_type afs_RXFSRemoveXXXX = {
739 .name = "FS.RemoveXXXX",
740 .deliver = afs_deliver_fs_remove,
741 .abort_to_error = afs_abort_to_error,
742 .destructor = afs_flat_call_destructor,
746 * remove a file or directory
748 int afs_fs_remove(struct afs_server *server,
750 struct afs_vnode *vnode,
753 const struct afs_wait_mode *wait_mode)
755 struct afs_call *call;
756 size_t namesz, reqsz, padsz;
761 namesz = strlen(name);
762 padsz = (4 - (namesz & 3)) & 3;
763 reqsz = (5 * 4) + namesz + padsz;
765 call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
771 call->service_id = FS_SERVICE;
772 call->port = htons(AFS_FS_PORT);
774 /* marshall the parameters */
776 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
777 *bp++ = htonl(vnode->fid.vid);
778 *bp++ = htonl(vnode->fid.vnode);
779 *bp++ = htonl(vnode->fid.unique);
780 *bp++ = htonl(namesz);
781 memcpy(bp, name, namesz);
782 bp = (void *) bp + namesz;
784 memset(bp, 0, padsz);
785 bp = (void *) bp + padsz;
788 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
792 * deliver reply data to an FS.Link
794 static int afs_deliver_fs_link(struct afs_call *call,
795 struct sk_buff *skb, bool last)
797 struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
800 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
802 afs_transfer_reply(call, skb);
806 if (call->reply_size != call->reply_max)
809 /* unmarshall the reply once we've received all of it */
811 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
812 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
813 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
815 _leave(" = 0 [done]");
820 * FS.Link operation type
822 static const struct afs_call_type afs_RXFSLink = {
824 .deliver = afs_deliver_fs_link,
825 .abort_to_error = afs_abort_to_error,
826 .destructor = afs_flat_call_destructor,
832 int afs_fs_link(struct afs_server *server,
834 struct afs_vnode *dvnode,
835 struct afs_vnode *vnode,
837 const struct afs_wait_mode *wait_mode)
839 struct afs_call *call;
840 size_t namesz, reqsz, padsz;
845 namesz = strlen(name);
846 padsz = (4 - (namesz & 3)) & 3;
847 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
849 call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
854 call->reply = dvnode;
855 call->reply2 = vnode;
856 call->service_id = FS_SERVICE;
857 call->port = htons(AFS_FS_PORT);
859 /* marshall the parameters */
861 *bp++ = htonl(FSLINK);
862 *bp++ = htonl(dvnode->fid.vid);
863 *bp++ = htonl(dvnode->fid.vnode);
864 *bp++ = htonl(dvnode->fid.unique);
865 *bp++ = htonl(namesz);
866 memcpy(bp, name, namesz);
867 bp = (void *) bp + namesz;
869 memset(bp, 0, padsz);
870 bp = (void *) bp + padsz;
872 *bp++ = htonl(vnode->fid.vid);
873 *bp++ = htonl(vnode->fid.vnode);
874 *bp++ = htonl(vnode->fid.unique);
876 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
880 * deliver reply data to an FS.Symlink
882 static int afs_deliver_fs_symlink(struct afs_call *call,
883 struct sk_buff *skb, bool last)
885 struct afs_vnode *vnode = call->reply;
888 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
890 afs_transfer_reply(call, skb);
894 if (call->reply_size != call->reply_max)
897 /* unmarshall the reply once we've received all of it */
899 xdr_decode_AFSFid(&bp, call->reply2);
900 xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
901 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
902 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
904 _leave(" = 0 [done]");
909 * FS.Symlink operation type
911 static const struct afs_call_type afs_RXFSSymlink = {
912 .name = "FS.Symlink",
913 .deliver = afs_deliver_fs_symlink,
914 .abort_to_error = afs_abort_to_error,
915 .destructor = afs_flat_call_destructor,
919 * create a symbolic link
921 int afs_fs_symlink(struct afs_server *server,
923 struct afs_vnode *vnode,
925 const char *contents,
926 struct afs_fid *newfid,
927 struct afs_file_status *newstatus,
928 const struct afs_wait_mode *wait_mode)
930 struct afs_call *call;
931 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
936 namesz = strlen(name);
937 padsz = (4 - (namesz & 3)) & 3;
939 c_namesz = strlen(contents);
940 c_padsz = (4 - (c_namesz & 3)) & 3;
942 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
944 call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
945 (3 + 21 + 21 + 6) * 4);
951 call->reply2 = newfid;
952 call->reply3 = newstatus;
953 call->service_id = FS_SERVICE;
954 call->port = htons(AFS_FS_PORT);
956 /* marshall the parameters */
958 *bp++ = htonl(FSSYMLINK);
959 *bp++ = htonl(vnode->fid.vid);
960 *bp++ = htonl(vnode->fid.vnode);
961 *bp++ = htonl(vnode->fid.unique);
962 *bp++ = htonl(namesz);
963 memcpy(bp, name, namesz);
964 bp = (void *) bp + namesz;
966 memset(bp, 0, padsz);
967 bp = (void *) bp + padsz;
969 *bp++ = htonl(c_namesz);
970 memcpy(bp, contents, c_namesz);
971 bp = (void *) bp + c_namesz;
973 memset(bp, 0, c_padsz);
974 bp = (void *) bp + c_padsz;
976 *bp++ = htonl(AFS_SET_MODE);
977 *bp++ = 0; /* mtime */
978 *bp++ = 0; /* owner */
979 *bp++ = 0; /* group */
980 *bp++ = htonl(S_IRWXUGO); /* unix mode */
981 *bp++ = 0; /* segment size */
983 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
987 * deliver reply data to an FS.Rename
989 static int afs_deliver_fs_rename(struct afs_call *call,
990 struct sk_buff *skb, bool last)
992 struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
995 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
997 afs_transfer_reply(call, skb);
1001 if (call->reply_size != call->reply_max)
1004 /* unmarshall the reply once we've received all of it */
1006 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
1007 if (new_dvnode != orig_dvnode)
1008 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
1010 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1012 _leave(" = 0 [done]");
1017 * FS.Rename operation type
1019 static const struct afs_call_type afs_RXFSRename = {
1020 .name = "FS.Rename",
1021 .deliver = afs_deliver_fs_rename,
1022 .abort_to_error = afs_abort_to_error,
1023 .destructor = afs_flat_call_destructor,
1027 * create a symbolic link
1029 int afs_fs_rename(struct afs_server *server,
1031 struct afs_vnode *orig_dvnode,
1032 const char *orig_name,
1033 struct afs_vnode *new_dvnode,
1034 const char *new_name,
1035 const struct afs_wait_mode *wait_mode)
1037 struct afs_call *call;
1038 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1043 o_namesz = strlen(orig_name);
1044 o_padsz = (4 - (o_namesz & 3)) & 3;
1046 n_namesz = strlen(new_name);
1047 n_padsz = (4 - (n_namesz & 3)) & 3;
1050 4 + o_namesz + o_padsz +
1052 4 + n_namesz + n_padsz;
1054 call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1059 call->reply = orig_dvnode;
1060 call->reply2 = new_dvnode;
1061 call->service_id = FS_SERVICE;
1062 call->port = htons(AFS_FS_PORT);
1064 /* marshall the parameters */
1066 *bp++ = htonl(FSRENAME);
1067 *bp++ = htonl(orig_dvnode->fid.vid);
1068 *bp++ = htonl(orig_dvnode->fid.vnode);
1069 *bp++ = htonl(orig_dvnode->fid.unique);
1070 *bp++ = htonl(o_namesz);
1071 memcpy(bp, orig_name, o_namesz);
1072 bp = (void *) bp + o_namesz;
1074 memset(bp, 0, o_padsz);
1075 bp = (void *) bp + o_padsz;
1078 *bp++ = htonl(new_dvnode->fid.vid);
1079 *bp++ = htonl(new_dvnode->fid.vnode);
1080 *bp++ = htonl(new_dvnode->fid.unique);
1081 *bp++ = htonl(n_namesz);
1082 memcpy(bp, new_name, n_namesz);
1083 bp = (void *) bp + n_namesz;
1085 memset(bp, 0, n_padsz);
1086 bp = (void *) bp + n_padsz;
1089 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1093 * deliver reply data to an FS.StoreData
1095 static int afs_deliver_fs_store_data(struct afs_call *call,
1096 struct sk_buff *skb, bool last)
1098 struct afs_vnode *vnode = call->reply;
1101 _enter(",,%u", last);
1103 afs_transfer_reply(call, skb);
1105 _leave(" = 0 [more]");
1109 if (call->reply_size != call->reply_max) {
1110 _leave(" = -EBADMSG [%u != %u]",
1111 call->reply_size, call->reply_max);
1115 /* unmarshall the reply once we've received all of it */
1117 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1118 &call->store_version);
1119 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1121 afs_pages_written_back(vnode, call);
1123 _leave(" = 0 [done]");
1128 * FS.StoreData operation type
1130 static const struct afs_call_type afs_RXFSStoreData = {
1131 .name = "FS.StoreData",
1132 .deliver = afs_deliver_fs_store_data,
1133 .abort_to_error = afs_abort_to_error,
1134 .destructor = afs_flat_call_destructor,
1137 static const struct afs_call_type afs_RXFSStoreData64 = {
1138 .name = "FS.StoreData64",
1139 .deliver = afs_deliver_fs_store_data,
1140 .abort_to_error = afs_abort_to_error,
1141 .destructor = afs_flat_call_destructor,
1145 * store a set of pages to a very large file
1147 static int afs_fs_store_data64(struct afs_server *server,
1148 struct afs_writeback *wb,
1149 pgoff_t first, pgoff_t last,
1150 unsigned offset, unsigned to,
1151 loff_t size, loff_t pos, loff_t i_size,
1152 const struct afs_wait_mode *wait_mode)
1154 struct afs_vnode *vnode = wb->vnode;
1155 struct afs_call *call;
1158 _enter(",%x,{%x:%u},,",
1159 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1161 call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1162 (4 + 6 + 3 * 2) * 4,
1168 call->key = wb->key;
1169 call->reply = vnode;
1170 call->service_id = FS_SERVICE;
1171 call->port = htons(AFS_FS_PORT);
1172 call->mapping = vnode->vfs_inode.i_mapping;
1173 call->first = first;
1175 call->first_offset = offset;
1177 call->send_pages = true;
1178 call->store_version = vnode->status.data_version + 1;
1180 /* marshall the parameters */
1182 *bp++ = htonl(FSSTOREDATA64);
1183 *bp++ = htonl(vnode->fid.vid);
1184 *bp++ = htonl(vnode->fid.vnode);
1185 *bp++ = htonl(vnode->fid.unique);
1187 *bp++ = 0; /* mask */
1188 *bp++ = 0; /* mtime */
1189 *bp++ = 0; /* owner */
1190 *bp++ = 0; /* group */
1191 *bp++ = 0; /* unix mode */
1192 *bp++ = 0; /* segment size */
1194 *bp++ = htonl(pos >> 32);
1195 *bp++ = htonl((u32) pos);
1196 *bp++ = htonl(size >> 32);
1197 *bp++ = htonl((u32) size);
1198 *bp++ = htonl(i_size >> 32);
1199 *bp++ = htonl((u32) i_size);
1201 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1205 * store a set of pages
1207 int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1208 pgoff_t first, pgoff_t last,
1209 unsigned offset, unsigned to,
1210 const struct afs_wait_mode *wait_mode)
1212 struct afs_vnode *vnode = wb->vnode;
1213 struct afs_call *call;
1214 loff_t size, pos, i_size;
1217 _enter(",%x,{%x:%u},,",
1218 key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1222 size += (loff_t)(last - first) << PAGE_SHIFT;
1223 pos = (loff_t)first << PAGE_SHIFT;
1226 i_size = i_size_read(&vnode->vfs_inode);
1227 if (pos + size > i_size)
1228 i_size = size + pos;
1230 _debug("size %llx, at %llx, i_size %llx",
1231 (unsigned long long) size, (unsigned long long) pos,
1232 (unsigned long long) i_size);
1234 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1235 return afs_fs_store_data64(server, wb, first, last, offset, to,
1236 size, pos, i_size, wait_mode);
1238 call = afs_alloc_flat_call(&afs_RXFSStoreData,
1245 call->key = wb->key;
1246 call->reply = vnode;
1247 call->service_id = FS_SERVICE;
1248 call->port = htons(AFS_FS_PORT);
1249 call->mapping = vnode->vfs_inode.i_mapping;
1250 call->first = first;
1252 call->first_offset = offset;
1254 call->send_pages = true;
1255 call->store_version = vnode->status.data_version + 1;
1257 /* marshall the parameters */
1259 *bp++ = htonl(FSSTOREDATA);
1260 *bp++ = htonl(vnode->fid.vid);
1261 *bp++ = htonl(vnode->fid.vnode);
1262 *bp++ = htonl(vnode->fid.unique);
1264 *bp++ = 0; /* mask */
1265 *bp++ = 0; /* mtime */
1266 *bp++ = 0; /* owner */
1267 *bp++ = 0; /* group */
1268 *bp++ = 0; /* unix mode */
1269 *bp++ = 0; /* segment size */
1272 *bp++ = htonl(size);
1273 *bp++ = htonl(i_size);
1275 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1279 * deliver reply data to an FS.StoreStatus
1281 static int afs_deliver_fs_store_status(struct afs_call *call,
1282 struct sk_buff *skb, bool last)
1284 afs_dataversion_t *store_version;
1285 struct afs_vnode *vnode = call->reply;
1288 _enter(",,%u", last);
1290 afs_transfer_reply(call, skb);
1292 _leave(" = 0 [more]");
1296 if (call->reply_size != call->reply_max) {
1297 _leave(" = -EBADMSG [%u != %u]",
1298 call->reply_size, call->reply_max);
1302 /* unmarshall the reply once we've received all of it */
1303 store_version = NULL;
1304 if (call->operation_ID == FSSTOREDATA)
1305 store_version = &call->store_version;
1308 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1309 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1311 _leave(" = 0 [done]");
1316 * FS.StoreStatus operation type
1318 static const struct afs_call_type afs_RXFSStoreStatus = {
1319 .name = "FS.StoreStatus",
1320 .deliver = afs_deliver_fs_store_status,
1321 .abort_to_error = afs_abort_to_error,
1322 .destructor = afs_flat_call_destructor,
1325 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1326 .name = "FS.StoreData",
1327 .deliver = afs_deliver_fs_store_status,
1328 .abort_to_error = afs_abort_to_error,
1329 .destructor = afs_flat_call_destructor,
1332 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1333 .name = "FS.StoreData64",
1334 .deliver = afs_deliver_fs_store_status,
1335 .abort_to_error = afs_abort_to_error,
1336 .destructor = afs_flat_call_destructor,
1340 * set the attributes on a very large file, using FS.StoreData rather than
1341 * FS.StoreStatus so as to alter the file size also
1343 static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,
1344 struct afs_vnode *vnode, struct iattr *attr,
1345 const struct afs_wait_mode *wait_mode)
1347 struct afs_call *call;
1350 _enter(",%x,{%x:%u},,",
1351 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1353 ASSERT(attr->ia_valid & ATTR_SIZE);
1355 call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,
1356 (4 + 6 + 3 * 2) * 4,
1362 call->reply = vnode;
1363 call->service_id = FS_SERVICE;
1364 call->port = htons(AFS_FS_PORT);
1365 call->store_version = vnode->status.data_version + 1;
1366 call->operation_ID = FSSTOREDATA;
1368 /* marshall the parameters */
1370 *bp++ = htonl(FSSTOREDATA64);
1371 *bp++ = htonl(vnode->fid.vid);
1372 *bp++ = htonl(vnode->fid.vnode);
1373 *bp++ = htonl(vnode->fid.unique);
1375 xdr_encode_AFS_StoreStatus(&bp, attr);
1377 *bp++ = 0; /* position of start of write */
1379 *bp++ = 0; /* size of write */
1381 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1382 *bp++ = htonl((u32) attr->ia_size);
1384 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1388 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1389 * so as to alter the file size also
1391 static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1392 struct afs_vnode *vnode, struct iattr *attr,
1393 const struct afs_wait_mode *wait_mode)
1395 struct afs_call *call;
1398 _enter(",%x,{%x:%u},,",
1399 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1401 ASSERT(attr->ia_valid & ATTR_SIZE);
1402 if (attr->ia_size >> 32)
1403 return afs_fs_setattr_size64(server, key, vnode, attr,
1406 call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1413 call->reply = vnode;
1414 call->service_id = FS_SERVICE;
1415 call->port = htons(AFS_FS_PORT);
1416 call->store_version = vnode->status.data_version + 1;
1417 call->operation_ID = FSSTOREDATA;
1419 /* marshall the parameters */
1421 *bp++ = htonl(FSSTOREDATA);
1422 *bp++ = htonl(vnode->fid.vid);
1423 *bp++ = htonl(vnode->fid.vnode);
1424 *bp++ = htonl(vnode->fid.unique);
1426 xdr_encode_AFS_StoreStatus(&bp, attr);
1428 *bp++ = 0; /* position of start of write */
1429 *bp++ = 0; /* size of write */
1430 *bp++ = htonl(attr->ia_size); /* new file length */
1432 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1436 * set the attributes on a file, using FS.StoreData if there's a change in file
1437 * size, and FS.StoreStatus otherwise
1439 int afs_fs_setattr(struct afs_server *server, struct key *key,
1440 struct afs_vnode *vnode, struct iattr *attr,
1441 const struct afs_wait_mode *wait_mode)
1443 struct afs_call *call;
1446 if (attr->ia_valid & ATTR_SIZE)
1447 return afs_fs_setattr_size(server, key, vnode, attr,
1450 _enter(",%x,{%x:%u},,",
1451 key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1453 call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1460 call->reply = vnode;
1461 call->service_id = FS_SERVICE;
1462 call->port = htons(AFS_FS_PORT);
1463 call->operation_ID = FSSTORESTATUS;
1465 /* marshall the parameters */
1467 *bp++ = htonl(FSSTORESTATUS);
1468 *bp++ = htonl(vnode->fid.vid);
1469 *bp++ = htonl(vnode->fid.vnode);
1470 *bp++ = htonl(vnode->fid.unique);
1472 xdr_encode_AFS_StoreStatus(&bp, attr);
1474 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1478 * deliver reply data to an FS.GetVolumeStatus
1480 static int afs_deliver_fs_get_volume_status(struct afs_call *call,
1481 struct sk_buff *skb, bool last)
1487 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1489 switch (call->unmarshall) {
1494 /* extract the returned status record */
1496 _debug("extract status");
1497 ret = afs_extract_data(call, skb, last, call->buffer,
1501 case -EAGAIN: return 0;
1502 default: return ret;
1506 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
1510 /* extract the volume name length */
1512 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1515 case -EAGAIN: return 0;
1516 default: return ret;
1519 call->count = ntohl(call->tmp);
1520 _debug("volname length: %u", call->count);
1521 if (call->count >= AFSNAMEMAX)
1526 /* extract the volume name */
1528 _debug("extract volname");
1529 if (call->count > 0) {
1530 ret = afs_extract_data(call, skb, last, call->reply3,
1534 case -EAGAIN: return 0;
1535 default: return ret;
1541 _debug("volname '%s'", p);
1546 /* extract the volume name padding */
1547 if ((call->count & 3) == 0) {
1549 goto no_volname_padding;
1551 call->count = 4 - (call->count & 3);
1554 ret = afs_extract_data(call, skb, last, call->buffer,
1558 case -EAGAIN: return 0;
1559 default: return ret;
1566 /* extract the offline message length */
1568 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1571 case -EAGAIN: return 0;
1572 default: return ret;
1575 call->count = ntohl(call->tmp);
1576 _debug("offline msg length: %u", call->count);
1577 if (call->count >= AFSNAMEMAX)
1582 /* extract the offline message */
1584 _debug("extract offline");
1585 if (call->count > 0) {
1586 ret = afs_extract_data(call, skb, last, call->reply3,
1590 case -EAGAIN: return 0;
1591 default: return ret;
1597 _debug("offline '%s'", p);
1602 /* extract the offline message padding */
1603 if ((call->count & 3) == 0) {
1605 goto no_offline_padding;
1607 call->count = 4 - (call->count & 3);
1610 ret = afs_extract_data(call, skb, last, call->buffer,
1614 case -EAGAIN: return 0;
1615 default: return ret;
1622 /* extract the message of the day length */
1624 ret = afs_extract_data(call, skb, last, &call->tmp, 4);
1627 case -EAGAIN: return 0;
1628 default: return ret;
1631 call->count = ntohl(call->tmp);
1632 _debug("motd length: %u", call->count);
1633 if (call->count >= AFSNAMEMAX)
1638 /* extract the message of the day */
1640 _debug("extract motd");
1641 if (call->count > 0) {
1642 ret = afs_extract_data(call, skb, last, call->reply3,
1646 case -EAGAIN: return 0;
1647 default: return ret;
1653 _debug("motd '%s'", p);
1658 /* extract the message of the day padding */
1659 if ((call->count & 3) == 0) {
1661 goto no_motd_padding;
1663 call->count = 4 - (call->count & 3);
1666 ret = afs_extract_data(call, skb, last, call->buffer,
1670 case -EAGAIN: return 0;
1671 default: return ret;
1679 _debug("trailer %d", skb->len);
1688 _leave(" = 0 [done]");
1693 * destroy an FS.GetVolumeStatus call
1695 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1697 kfree(call->reply3);
1698 call->reply3 = NULL;
1699 afs_flat_call_destructor(call);
1703 * FS.GetVolumeStatus operation type
1705 static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1706 .name = "FS.GetVolumeStatus",
1707 .deliver = afs_deliver_fs_get_volume_status,
1708 .abort_to_error = afs_abort_to_error,
1709 .destructor = afs_get_volume_status_call_destructor,
1713 * fetch the status of a volume
1715 int afs_fs_get_volume_status(struct afs_server *server,
1717 struct afs_vnode *vnode,
1718 struct afs_volume_status *vs,
1719 const struct afs_wait_mode *wait_mode)
1721 struct afs_call *call;
1727 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1731 call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1738 call->reply = vnode;
1740 call->reply3 = tmpbuf;
1741 call->service_id = FS_SERVICE;
1742 call->port = htons(AFS_FS_PORT);
1744 /* marshall the parameters */
1746 bp[0] = htonl(FSGETVOLUMESTATUS);
1747 bp[1] = htonl(vnode->fid.vid);
1749 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1753 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1755 static int afs_deliver_fs_xxxx_lock(struct afs_call *call,
1756 struct sk_buff *skb, bool last)
1760 _enter("{%u},{%u},%d", call->unmarshall, skb->len, last);
1762 afs_transfer_reply(call, skb);
1766 if (call->reply_size != call->reply_max)
1769 /* unmarshall the reply once we've received all of it */
1771 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1773 _leave(" = 0 [done]");
1778 * FS.SetLock operation type
1780 static const struct afs_call_type afs_RXFSSetLock = {
1781 .name = "FS.SetLock",
1782 .deliver = afs_deliver_fs_xxxx_lock,
1783 .abort_to_error = afs_abort_to_error,
1784 .destructor = afs_flat_call_destructor,
1788 * FS.ExtendLock operation type
1790 static const struct afs_call_type afs_RXFSExtendLock = {
1791 .name = "FS.ExtendLock",
1792 .deliver = afs_deliver_fs_xxxx_lock,
1793 .abort_to_error = afs_abort_to_error,
1794 .destructor = afs_flat_call_destructor,
1798 * FS.ReleaseLock operation type
1800 static const struct afs_call_type afs_RXFSReleaseLock = {
1801 .name = "FS.ReleaseLock",
1802 .deliver = afs_deliver_fs_xxxx_lock,
1803 .abort_to_error = afs_abort_to_error,
1804 .destructor = afs_flat_call_destructor,
1808 * get a lock on a file
1810 int afs_fs_set_lock(struct afs_server *server,
1812 struct afs_vnode *vnode,
1813 afs_lock_type_t type,
1814 const struct afs_wait_mode *wait_mode)
1816 struct afs_call *call;
1821 call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);
1826 call->reply = vnode;
1827 call->service_id = FS_SERVICE;
1828 call->port = htons(AFS_FS_PORT);
1830 /* marshall the parameters */
1832 *bp++ = htonl(FSSETLOCK);
1833 *bp++ = htonl(vnode->fid.vid);
1834 *bp++ = htonl(vnode->fid.vnode);
1835 *bp++ = htonl(vnode->fid.unique);
1836 *bp++ = htonl(type);
1838 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1842 * extend a lock on a file
1844 int afs_fs_extend_lock(struct afs_server *server,
1846 struct afs_vnode *vnode,
1847 const struct afs_wait_mode *wait_mode)
1849 struct afs_call *call;
1854 call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);
1859 call->reply = vnode;
1860 call->service_id = FS_SERVICE;
1861 call->port = htons(AFS_FS_PORT);
1863 /* marshall the parameters */
1865 *bp++ = htonl(FSEXTENDLOCK);
1866 *bp++ = htonl(vnode->fid.vid);
1867 *bp++ = htonl(vnode->fid.vnode);
1868 *bp++ = htonl(vnode->fid.unique);
1870 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);
1874 * release a lock on a file
1876 int afs_fs_release_lock(struct afs_server *server,
1878 struct afs_vnode *vnode,
1879 const struct afs_wait_mode *wait_mode)
1881 struct afs_call *call;
1886 call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1891 call->reply = vnode;
1892 call->service_id = FS_SERVICE;
1893 call->port = htons(AFS_FS_PORT);
1895 /* marshall the parameters */
1897 *bp++ = htonl(FSRELEASELOCK);
1898 *bp++ = htonl(vnode->fid.vid);
1899 *bp++ = htonl(vnode->fid.vnode);
1900 *bp++ = htonl(vnode->fid.unique);
1902 return afs_make_call(&server->addr, call, GFP_NOFS, wait_mode);