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>
20 * decode an AFSFid block
22 static void xdr_decode_AFSFid(const __be32
**_bp
, struct afs_fid
*fid
)
24 const __be32
*bp
= *_bp
;
26 fid
->vid
= ntohl(*bp
++);
27 fid
->vnode
= ntohl(*bp
++);
28 fid
->unique
= ntohl(*bp
++);
33 * decode an AFSFetchStatus block
35 static void xdr_decode_AFSFetchStatus(const __be32
**_bp
,
36 struct afs_file_status
*status
,
37 struct afs_vnode
*vnode
,
38 afs_dataversion_t
*store_version
)
40 afs_dataversion_t expected_version
;
41 const __be32
*bp
= *_bp
;
43 u64 data_version
, size
;
44 u32 changed
= 0; /* becomes non-zero if ctime-type changes seen */
48 #define EXTRACT(DST) \
50 u32 x = ntohl(*bp++); \
55 status
->if_version
= ntohl(*bp
++);
56 EXTRACT(status
->type
);
57 EXTRACT(status
->nlink
);
59 data_version
= ntohl(*bp
++);
60 EXTRACT(status
->author
);
61 owner
= make_kuid(&init_user_ns
, ntohl(*bp
++));
62 changed
|= !uid_eq(owner
, status
->owner
);
63 status
->owner
= owner
;
64 EXTRACT(status
->caller_access
); /* call ticket dependent */
65 EXTRACT(status
->anon_access
);
66 EXTRACT(status
->mode
);
67 EXTRACT(status
->parent
.vnode
);
68 EXTRACT(status
->parent
.unique
);
70 status
->mtime_client
= ntohl(*bp
++);
71 status
->mtime_server
= ntohl(*bp
++);
72 group
= make_kgid(&init_user_ns
, ntohl(*bp
++));
73 changed
|= !gid_eq(group
, status
->group
);
74 status
->group
= group
;
75 bp
++; /* sync counter */
76 data_version
|= (u64
) ntohl(*bp
++) << 32;
77 EXTRACT(status
->lock_count
);
78 size
|= (u64
) ntohl(*bp
++) << 32;
82 if (size
!= status
->size
) {
86 status
->mode
&= S_IALLUGO
;
88 _debug("vnode time %lx, %lx",
89 status
->mtime_client
, status
->mtime_server
);
92 status
->parent
.vid
= vnode
->fid
.vid
;
93 if (changed
&& !test_bit(AFS_VNODE_UNSET
, &vnode
->flags
)) {
94 _debug("vnode changed");
95 i_size_write(&vnode
->vfs_inode
, size
);
96 vnode
->vfs_inode
.i_uid
= status
->owner
;
97 vnode
->vfs_inode
.i_gid
= status
->group
;
98 vnode
->vfs_inode
.i_generation
= vnode
->fid
.unique
;
99 set_nlink(&vnode
->vfs_inode
, status
->nlink
);
101 mode
= vnode
->vfs_inode
.i_mode
;
103 mode
|= status
->mode
;
105 vnode
->vfs_inode
.i_mode
= mode
;
108 vnode
->vfs_inode
.i_ctime
.tv_sec
= status
->mtime_server
;
109 vnode
->vfs_inode
.i_mtime
= vnode
->vfs_inode
.i_ctime
;
110 vnode
->vfs_inode
.i_atime
= vnode
->vfs_inode
.i_ctime
;
111 vnode
->vfs_inode
.i_version
= data_version
;
114 expected_version
= status
->data_version
;
116 expected_version
= *store_version
;
118 if (expected_version
!= data_version
) {
119 status
->data_version
= data_version
;
120 if (vnode
&& !test_bit(AFS_VNODE_UNSET
, &vnode
->flags
)) {
121 _debug("vnode modified %llx on {%x:%u}",
122 (unsigned long long) data_version
,
123 vnode
->fid
.vid
, vnode
->fid
.vnode
);
124 set_bit(AFS_VNODE_MODIFIED
, &vnode
->flags
);
125 set_bit(AFS_VNODE_ZAP_DATA
, &vnode
->flags
);
127 } else if (store_version
) {
128 status
->data_version
= data_version
;
133 * decode an AFSCallBack block
135 static void xdr_decode_AFSCallBack(const __be32
**_bp
, struct afs_vnode
*vnode
)
137 const __be32
*bp
= *_bp
;
139 vnode
->cb_version
= ntohl(*bp
++);
140 vnode
->cb_expiry
= ntohl(*bp
++);
141 vnode
->cb_type
= ntohl(*bp
++);
142 vnode
->cb_expires
= vnode
->cb_expiry
+ get_seconds();
146 static void xdr_decode_AFSCallBack_raw(const __be32
**_bp
,
147 struct afs_callback
*cb
)
149 const __be32
*bp
= *_bp
;
151 cb
->version
= ntohl(*bp
++);
152 cb
->expiry
= ntohl(*bp
++);
153 cb
->type
= ntohl(*bp
++);
158 * decode an AFSVolSync block
160 static void xdr_decode_AFSVolSync(const __be32
**_bp
,
161 struct afs_volsync
*volsync
)
163 const __be32
*bp
= *_bp
;
165 volsync
->creation
= ntohl(*bp
++);
175 * encode the requested attributes into an AFSStoreStatus block
177 static void xdr_encode_AFS_StoreStatus(__be32
**_bp
, struct iattr
*attr
)
180 u32 mask
= 0, mtime
= 0, owner
= 0, group
= 0, mode
= 0;
183 if (attr
->ia_valid
& ATTR_MTIME
) {
184 mask
|= AFS_SET_MTIME
;
185 mtime
= attr
->ia_mtime
.tv_sec
;
188 if (attr
->ia_valid
& ATTR_UID
) {
189 mask
|= AFS_SET_OWNER
;
190 owner
= from_kuid(&init_user_ns
, attr
->ia_uid
);
193 if (attr
->ia_valid
& ATTR_GID
) {
194 mask
|= AFS_SET_GROUP
;
195 group
= from_kgid(&init_user_ns
, attr
->ia_gid
);
198 if (attr
->ia_valid
& ATTR_MODE
) {
199 mask
|= AFS_SET_MODE
;
200 mode
= attr
->ia_mode
& S_IALLUGO
;
204 *bp
++ = htonl(mtime
);
205 *bp
++ = htonl(owner
);
206 *bp
++ = htonl(group
);
208 *bp
++ = 0; /* segment size */
213 * decode an AFSFetchVolumeStatus block
215 static void xdr_decode_AFSFetchVolumeStatus(const __be32
**_bp
,
216 struct afs_volume_status
*vs
)
218 const __be32
*bp
= *_bp
;
220 vs
->vid
= ntohl(*bp
++);
221 vs
->parent_id
= ntohl(*bp
++);
222 vs
->online
= ntohl(*bp
++);
223 vs
->in_service
= ntohl(*bp
++);
224 vs
->blessed
= ntohl(*bp
++);
225 vs
->needs_salvage
= ntohl(*bp
++);
226 vs
->type
= ntohl(*bp
++);
227 vs
->min_quota
= ntohl(*bp
++);
228 vs
->max_quota
= ntohl(*bp
++);
229 vs
->blocks_in_use
= ntohl(*bp
++);
230 vs
->part_blocks_avail
= ntohl(*bp
++);
231 vs
->part_max_blocks
= ntohl(*bp
++);
236 * deliver reply data to an FS.FetchStatus
238 static int afs_deliver_fs_fetch_status(struct afs_call
*call
)
240 struct afs_vnode
*vnode
= call
->reply
;
246 ret
= afs_transfer_reply(call
);
250 /* unmarshall the reply once we've received all of it */
252 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
253 xdr_decode_AFSCallBack(&bp
, vnode
);
255 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
257 _leave(" = 0 [done]");
262 * FS.FetchStatus operation type
264 static const struct afs_call_type afs_RXFSFetchStatus
= {
265 .name
= "FS.FetchStatus",
266 .deliver
= afs_deliver_fs_fetch_status
,
267 .abort_to_error
= afs_abort_to_error
,
268 .destructor
= afs_flat_call_destructor
,
272 * fetch the status information for a file
274 int afs_fs_fetch_file_status(struct afs_server
*server
,
276 struct afs_vnode
*vnode
,
277 struct afs_volsync
*volsync
,
278 const struct afs_wait_mode
*wait_mode
)
280 struct afs_call
*call
;
283 _enter(",%x,{%x:%u},,",
284 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
286 call
= afs_alloc_flat_call(&afs_RXFSFetchStatus
, 16, (21 + 3 + 6) * 4);
292 call
->reply2
= volsync
;
293 call
->service_id
= FS_SERVICE
;
294 call
->port
= htons(AFS_FS_PORT
);
296 /* marshall the parameters */
298 bp
[0] = htonl(FSFETCHSTATUS
);
299 bp
[1] = htonl(vnode
->fid
.vid
);
300 bp
[2] = htonl(vnode
->fid
.vnode
);
301 bp
[3] = htonl(vnode
->fid
.unique
);
303 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
307 * deliver reply data to an FS.FetchData
309 static int afs_deliver_fs_fetch_data(struct afs_call
*call
)
311 struct afs_vnode
*vnode
= call
->reply
;
317 _enter("{%u}", call
->unmarshall
);
319 switch (call
->unmarshall
) {
323 if (call
->operation_ID
!= FSFETCHDATA64
) {
328 /* extract the upper part of the returned data length of an
329 * FSFETCHDATA64 op (which should always be 0 using this
332 _debug("extract data length (MSW)");
333 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
337 call
->count
= ntohl(call
->tmp
);
338 _debug("DATA length MSW: %u", call
->count
);
345 /* extract the returned data length */
347 _debug("extract data length");
348 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
352 call
->count
= ntohl(call
->tmp
);
353 _debug("DATA length: %u", call
->count
);
354 if (call
->count
> PAGE_SIZE
)
359 /* extract the returned data */
361 _debug("extract data");
362 if (call
->count
> 0) {
365 ret
= afs_extract_data(call
, buffer
,
375 /* extract the metadata */
377 ret
= afs_extract_data(call
, call
->buffer
,
378 (21 + 3 + 6) * 4, false);
383 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
384 xdr_decode_AFSCallBack(&bp
, vnode
);
386 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
395 if (call
->count
< PAGE_SIZE
) {
399 memset(buffer
+ call
->count
, 0, PAGE_SIZE
- call
->count
);
403 _leave(" = 0 [done]");
408 * FS.FetchData operation type
410 static const struct afs_call_type afs_RXFSFetchData
= {
411 .name
= "FS.FetchData",
412 .deliver
= afs_deliver_fs_fetch_data
,
413 .abort_to_error
= afs_abort_to_error
,
414 .destructor
= afs_flat_call_destructor
,
417 static const struct afs_call_type afs_RXFSFetchData64
= {
418 .name
= "FS.FetchData64",
419 .deliver
= afs_deliver_fs_fetch_data
,
420 .abort_to_error
= afs_abort_to_error
,
421 .destructor
= afs_flat_call_destructor
,
425 * fetch data from a very large file
427 static int afs_fs_fetch_data64(struct afs_server
*server
,
429 struct afs_vnode
*vnode
,
430 off_t offset
, size_t length
,
432 const struct afs_wait_mode
*wait_mode
)
434 struct afs_call
*call
;
439 ASSERTCMP(length
, <, ULONG_MAX
);
441 call
= afs_alloc_flat_call(&afs_RXFSFetchData64
, 32, (21 + 3 + 6) * 4);
447 call
->reply2
= NULL
; /* volsync */
448 call
->reply3
= buffer
;
449 call
->service_id
= FS_SERVICE
;
450 call
->port
= htons(AFS_FS_PORT
);
451 call
->operation_ID
= FSFETCHDATA64
;
453 /* marshall the parameters */
455 bp
[0] = htonl(FSFETCHDATA64
);
456 bp
[1] = htonl(vnode
->fid
.vid
);
457 bp
[2] = htonl(vnode
->fid
.vnode
);
458 bp
[3] = htonl(vnode
->fid
.unique
);
459 bp
[4] = htonl(upper_32_bits(offset
));
460 bp
[5] = htonl((u32
) offset
);
462 bp
[7] = htonl((u32
) length
);
464 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
468 * fetch data from a file
470 int afs_fs_fetch_data(struct afs_server
*server
,
472 struct afs_vnode
*vnode
,
473 off_t offset
, size_t length
,
475 const struct afs_wait_mode
*wait_mode
)
477 struct afs_call
*call
;
480 if (upper_32_bits(offset
) || upper_32_bits(offset
+ length
))
481 return afs_fs_fetch_data64(server
, key
, vnode
, offset
, length
,
486 call
= afs_alloc_flat_call(&afs_RXFSFetchData
, 24, (21 + 3 + 6) * 4);
492 call
->reply2
= NULL
; /* volsync */
493 call
->reply3
= buffer
;
494 call
->service_id
= FS_SERVICE
;
495 call
->port
= htons(AFS_FS_PORT
);
496 call
->operation_ID
= FSFETCHDATA
;
498 /* marshall the parameters */
500 bp
[0] = htonl(FSFETCHDATA
);
501 bp
[1] = htonl(vnode
->fid
.vid
);
502 bp
[2] = htonl(vnode
->fid
.vnode
);
503 bp
[3] = htonl(vnode
->fid
.unique
);
504 bp
[4] = htonl(offset
);
505 bp
[5] = htonl(length
);
507 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
511 * deliver reply data to an FS.GiveUpCallBacks
513 static int afs_deliver_fs_give_up_callbacks(struct afs_call
*call
)
517 /* shouldn't be any reply data */
518 return afs_extract_data(call
, NULL
, 0, false);
522 * FS.GiveUpCallBacks operation type
524 static const struct afs_call_type afs_RXFSGiveUpCallBacks
= {
525 .name
= "FS.GiveUpCallBacks",
526 .deliver
= afs_deliver_fs_give_up_callbacks
,
527 .abort_to_error
= afs_abort_to_error
,
528 .destructor
= afs_flat_call_destructor
,
532 * give up a set of callbacks
533 * - the callbacks are held in the server->cb_break ring
535 int afs_fs_give_up_callbacks(struct afs_server
*server
,
536 const struct afs_wait_mode
*wait_mode
)
538 struct afs_call
*call
;
543 ncallbacks
= CIRC_CNT(server
->cb_break_head
, server
->cb_break_tail
,
544 ARRAY_SIZE(server
->cb_break
));
546 _enter("{%zu},", ncallbacks
);
550 if (ncallbacks
> AFSCBMAX
)
551 ncallbacks
= AFSCBMAX
;
553 _debug("break %zu callbacks", ncallbacks
);
555 call
= afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks
,
556 12 + ncallbacks
* 6 * 4, 0);
560 call
->service_id
= FS_SERVICE
;
561 call
->port
= htons(AFS_FS_PORT
);
563 /* marshall the parameters */
565 tp
= bp
+ 2 + ncallbacks
* 3;
566 *bp
++ = htonl(FSGIVEUPCALLBACKS
);
567 *bp
++ = htonl(ncallbacks
);
568 *tp
++ = htonl(ncallbacks
);
570 atomic_sub(ncallbacks
, &server
->cb_break_n
);
571 for (loop
= ncallbacks
; loop
> 0; loop
--) {
572 struct afs_callback
*cb
=
573 &server
->cb_break
[server
->cb_break_tail
];
575 *bp
++ = htonl(cb
->fid
.vid
);
576 *bp
++ = htonl(cb
->fid
.vnode
);
577 *bp
++ = htonl(cb
->fid
.unique
);
578 *tp
++ = htonl(cb
->version
);
579 *tp
++ = htonl(cb
->expiry
);
580 *tp
++ = htonl(cb
->type
);
582 server
->cb_break_tail
=
583 (server
->cb_break_tail
+ 1) &
584 (ARRAY_SIZE(server
->cb_break
) - 1);
587 ASSERT(ncallbacks
> 0);
588 wake_up_nr(&server
->cb_break_waitq
, ncallbacks
);
590 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
594 * deliver reply data to an FS.CreateFile or an FS.MakeDir
596 static int afs_deliver_fs_create_vnode(struct afs_call
*call
)
598 struct afs_vnode
*vnode
= call
->reply
;
602 _enter("{%u}", call
->unmarshall
);
604 ret
= afs_transfer_reply(call
);
608 /* unmarshall the reply once we've received all of it */
610 xdr_decode_AFSFid(&bp
, call
->reply2
);
611 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
612 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
613 xdr_decode_AFSCallBack_raw(&bp
, call
->reply4
);
614 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
616 _leave(" = 0 [done]");
621 * FS.CreateFile and FS.MakeDir operation type
623 static const struct afs_call_type afs_RXFSCreateXXXX
= {
624 .name
= "FS.CreateXXXX",
625 .deliver
= afs_deliver_fs_create_vnode
,
626 .abort_to_error
= afs_abort_to_error
,
627 .destructor
= afs_flat_call_destructor
,
631 * create a file or make a directory
633 int afs_fs_create(struct afs_server
*server
,
635 struct afs_vnode
*vnode
,
638 struct afs_fid
*newfid
,
639 struct afs_file_status
*newstatus
,
640 struct afs_callback
*newcb
,
641 const struct afs_wait_mode
*wait_mode
)
643 struct afs_call
*call
;
644 size_t namesz
, reqsz
, padsz
;
649 namesz
= strlen(name
);
650 padsz
= (4 - (namesz
& 3)) & 3;
651 reqsz
= (5 * 4) + namesz
+ padsz
+ (6 * 4);
653 call
= afs_alloc_flat_call(&afs_RXFSCreateXXXX
, reqsz
,
654 (3 + 21 + 21 + 3 + 6) * 4);
660 call
->reply2
= newfid
;
661 call
->reply3
= newstatus
;
662 call
->reply4
= newcb
;
663 call
->service_id
= FS_SERVICE
;
664 call
->port
= htons(AFS_FS_PORT
);
666 /* marshall the parameters */
668 *bp
++ = htonl(S_ISDIR(mode
) ? FSMAKEDIR
: FSCREATEFILE
);
669 *bp
++ = htonl(vnode
->fid
.vid
);
670 *bp
++ = htonl(vnode
->fid
.vnode
);
671 *bp
++ = htonl(vnode
->fid
.unique
);
672 *bp
++ = htonl(namesz
);
673 memcpy(bp
, name
, namesz
);
674 bp
= (void *) bp
+ namesz
;
676 memset(bp
, 0, padsz
);
677 bp
= (void *) bp
+ padsz
;
679 *bp
++ = htonl(AFS_SET_MODE
);
680 *bp
++ = 0; /* mtime */
681 *bp
++ = 0; /* owner */
682 *bp
++ = 0; /* group */
683 *bp
++ = htonl(mode
& S_IALLUGO
); /* unix mode */
684 *bp
++ = 0; /* segment size */
686 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
690 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
692 static int afs_deliver_fs_remove(struct afs_call
*call
)
694 struct afs_vnode
*vnode
= call
->reply
;
698 _enter("{%u}", call
->unmarshall
);
700 ret
= afs_transfer_reply(call
);
704 /* unmarshall the reply once we've received all of it */
706 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
707 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
709 _leave(" = 0 [done]");
714 * FS.RemoveDir/FS.RemoveFile operation type
716 static const struct afs_call_type afs_RXFSRemoveXXXX
= {
717 .name
= "FS.RemoveXXXX",
718 .deliver
= afs_deliver_fs_remove
,
719 .abort_to_error
= afs_abort_to_error
,
720 .destructor
= afs_flat_call_destructor
,
724 * remove a file or directory
726 int afs_fs_remove(struct afs_server
*server
,
728 struct afs_vnode
*vnode
,
731 const struct afs_wait_mode
*wait_mode
)
733 struct afs_call
*call
;
734 size_t namesz
, reqsz
, padsz
;
739 namesz
= strlen(name
);
740 padsz
= (4 - (namesz
& 3)) & 3;
741 reqsz
= (5 * 4) + namesz
+ padsz
;
743 call
= afs_alloc_flat_call(&afs_RXFSRemoveXXXX
, reqsz
, (21 + 6) * 4);
749 call
->service_id
= FS_SERVICE
;
750 call
->port
= htons(AFS_FS_PORT
);
752 /* marshall the parameters */
754 *bp
++ = htonl(isdir
? FSREMOVEDIR
: FSREMOVEFILE
);
755 *bp
++ = htonl(vnode
->fid
.vid
);
756 *bp
++ = htonl(vnode
->fid
.vnode
);
757 *bp
++ = htonl(vnode
->fid
.unique
);
758 *bp
++ = htonl(namesz
);
759 memcpy(bp
, name
, namesz
);
760 bp
= (void *) bp
+ namesz
;
762 memset(bp
, 0, padsz
);
763 bp
= (void *) bp
+ padsz
;
766 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
770 * deliver reply data to an FS.Link
772 static int afs_deliver_fs_link(struct afs_call
*call
)
774 struct afs_vnode
*dvnode
= call
->reply
, *vnode
= call
->reply2
;
778 _enter("{%u}", call
->unmarshall
);
780 ret
= afs_transfer_reply(call
);
784 /* unmarshall the reply once we've received all of it */
786 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
787 xdr_decode_AFSFetchStatus(&bp
, &dvnode
->status
, dvnode
, NULL
);
788 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
790 _leave(" = 0 [done]");
795 * FS.Link operation type
797 static const struct afs_call_type afs_RXFSLink
= {
799 .deliver
= afs_deliver_fs_link
,
800 .abort_to_error
= afs_abort_to_error
,
801 .destructor
= afs_flat_call_destructor
,
807 int afs_fs_link(struct afs_server
*server
,
809 struct afs_vnode
*dvnode
,
810 struct afs_vnode
*vnode
,
812 const struct afs_wait_mode
*wait_mode
)
814 struct afs_call
*call
;
815 size_t namesz
, reqsz
, padsz
;
820 namesz
= strlen(name
);
821 padsz
= (4 - (namesz
& 3)) & 3;
822 reqsz
= (5 * 4) + namesz
+ padsz
+ (3 * 4);
824 call
= afs_alloc_flat_call(&afs_RXFSLink
, reqsz
, (21 + 21 + 6) * 4);
829 call
->reply
= dvnode
;
830 call
->reply2
= vnode
;
831 call
->service_id
= FS_SERVICE
;
832 call
->port
= htons(AFS_FS_PORT
);
834 /* marshall the parameters */
836 *bp
++ = htonl(FSLINK
);
837 *bp
++ = htonl(dvnode
->fid
.vid
);
838 *bp
++ = htonl(dvnode
->fid
.vnode
);
839 *bp
++ = htonl(dvnode
->fid
.unique
);
840 *bp
++ = htonl(namesz
);
841 memcpy(bp
, name
, namesz
);
842 bp
= (void *) bp
+ namesz
;
844 memset(bp
, 0, padsz
);
845 bp
= (void *) bp
+ padsz
;
847 *bp
++ = htonl(vnode
->fid
.vid
);
848 *bp
++ = htonl(vnode
->fid
.vnode
);
849 *bp
++ = htonl(vnode
->fid
.unique
);
851 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
855 * deliver reply data to an FS.Symlink
857 static int afs_deliver_fs_symlink(struct afs_call
*call
)
859 struct afs_vnode
*vnode
= call
->reply
;
863 _enter("{%u}", call
->unmarshall
);
865 ret
= afs_transfer_reply(call
);
869 /* unmarshall the reply once we've received all of it */
871 xdr_decode_AFSFid(&bp
, call
->reply2
);
872 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
873 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
874 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
876 _leave(" = 0 [done]");
881 * FS.Symlink operation type
883 static const struct afs_call_type afs_RXFSSymlink
= {
884 .name
= "FS.Symlink",
885 .deliver
= afs_deliver_fs_symlink
,
886 .abort_to_error
= afs_abort_to_error
,
887 .destructor
= afs_flat_call_destructor
,
891 * create a symbolic link
893 int afs_fs_symlink(struct afs_server
*server
,
895 struct afs_vnode
*vnode
,
897 const char *contents
,
898 struct afs_fid
*newfid
,
899 struct afs_file_status
*newstatus
,
900 const struct afs_wait_mode
*wait_mode
)
902 struct afs_call
*call
;
903 size_t namesz
, reqsz
, padsz
, c_namesz
, c_padsz
;
908 namesz
= strlen(name
);
909 padsz
= (4 - (namesz
& 3)) & 3;
911 c_namesz
= strlen(contents
);
912 c_padsz
= (4 - (c_namesz
& 3)) & 3;
914 reqsz
= (6 * 4) + namesz
+ padsz
+ c_namesz
+ c_padsz
+ (6 * 4);
916 call
= afs_alloc_flat_call(&afs_RXFSSymlink
, reqsz
,
917 (3 + 21 + 21 + 6) * 4);
923 call
->reply2
= newfid
;
924 call
->reply3
= newstatus
;
925 call
->service_id
= FS_SERVICE
;
926 call
->port
= htons(AFS_FS_PORT
);
928 /* marshall the parameters */
930 *bp
++ = htonl(FSSYMLINK
);
931 *bp
++ = htonl(vnode
->fid
.vid
);
932 *bp
++ = htonl(vnode
->fid
.vnode
);
933 *bp
++ = htonl(vnode
->fid
.unique
);
934 *bp
++ = htonl(namesz
);
935 memcpy(bp
, name
, namesz
);
936 bp
= (void *) bp
+ namesz
;
938 memset(bp
, 0, padsz
);
939 bp
= (void *) bp
+ padsz
;
941 *bp
++ = htonl(c_namesz
);
942 memcpy(bp
, contents
, c_namesz
);
943 bp
= (void *) bp
+ c_namesz
;
945 memset(bp
, 0, c_padsz
);
946 bp
= (void *) bp
+ c_padsz
;
948 *bp
++ = htonl(AFS_SET_MODE
);
949 *bp
++ = 0; /* mtime */
950 *bp
++ = 0; /* owner */
951 *bp
++ = 0; /* group */
952 *bp
++ = htonl(S_IRWXUGO
); /* unix mode */
953 *bp
++ = 0; /* segment size */
955 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
959 * deliver reply data to an FS.Rename
961 static int afs_deliver_fs_rename(struct afs_call
*call
)
963 struct afs_vnode
*orig_dvnode
= call
->reply
, *new_dvnode
= call
->reply2
;
967 _enter("{%u}", call
->unmarshall
);
969 ret
= afs_transfer_reply(call
);
973 /* unmarshall the reply once we've received all of it */
975 xdr_decode_AFSFetchStatus(&bp
, &orig_dvnode
->status
, orig_dvnode
, NULL
);
976 if (new_dvnode
!= orig_dvnode
)
977 xdr_decode_AFSFetchStatus(&bp
, &new_dvnode
->status
, new_dvnode
,
979 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
981 _leave(" = 0 [done]");
986 * FS.Rename operation type
988 static const struct afs_call_type afs_RXFSRename
= {
990 .deliver
= afs_deliver_fs_rename
,
991 .abort_to_error
= afs_abort_to_error
,
992 .destructor
= afs_flat_call_destructor
,
996 * create a symbolic link
998 int afs_fs_rename(struct afs_server
*server
,
1000 struct afs_vnode
*orig_dvnode
,
1001 const char *orig_name
,
1002 struct afs_vnode
*new_dvnode
,
1003 const char *new_name
,
1004 const struct afs_wait_mode
*wait_mode
)
1006 struct afs_call
*call
;
1007 size_t reqsz
, o_namesz
, o_padsz
, n_namesz
, n_padsz
;
1012 o_namesz
= strlen(orig_name
);
1013 o_padsz
= (4 - (o_namesz
& 3)) & 3;
1015 n_namesz
= strlen(new_name
);
1016 n_padsz
= (4 - (n_namesz
& 3)) & 3;
1019 4 + o_namesz
+ o_padsz
+
1021 4 + n_namesz
+ n_padsz
;
1023 call
= afs_alloc_flat_call(&afs_RXFSRename
, reqsz
, (21 + 21 + 6) * 4);
1028 call
->reply
= orig_dvnode
;
1029 call
->reply2
= new_dvnode
;
1030 call
->service_id
= FS_SERVICE
;
1031 call
->port
= htons(AFS_FS_PORT
);
1033 /* marshall the parameters */
1035 *bp
++ = htonl(FSRENAME
);
1036 *bp
++ = htonl(orig_dvnode
->fid
.vid
);
1037 *bp
++ = htonl(orig_dvnode
->fid
.vnode
);
1038 *bp
++ = htonl(orig_dvnode
->fid
.unique
);
1039 *bp
++ = htonl(o_namesz
);
1040 memcpy(bp
, orig_name
, o_namesz
);
1041 bp
= (void *) bp
+ o_namesz
;
1043 memset(bp
, 0, o_padsz
);
1044 bp
= (void *) bp
+ o_padsz
;
1047 *bp
++ = htonl(new_dvnode
->fid
.vid
);
1048 *bp
++ = htonl(new_dvnode
->fid
.vnode
);
1049 *bp
++ = htonl(new_dvnode
->fid
.unique
);
1050 *bp
++ = htonl(n_namesz
);
1051 memcpy(bp
, new_name
, n_namesz
);
1052 bp
= (void *) bp
+ n_namesz
;
1054 memset(bp
, 0, n_padsz
);
1055 bp
= (void *) bp
+ n_padsz
;
1058 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1062 * deliver reply data to an FS.StoreData
1064 static int afs_deliver_fs_store_data(struct afs_call
*call
)
1066 struct afs_vnode
*vnode
= call
->reply
;
1072 ret
= afs_transfer_reply(call
);
1076 /* unmarshall the reply once we've received all of it */
1078 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
,
1079 &call
->store_version
);
1080 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1082 afs_pages_written_back(vnode
, call
);
1084 _leave(" = 0 [done]");
1089 * FS.StoreData operation type
1091 static const struct afs_call_type afs_RXFSStoreData
= {
1092 .name
= "FS.StoreData",
1093 .deliver
= afs_deliver_fs_store_data
,
1094 .abort_to_error
= afs_abort_to_error
,
1095 .destructor
= afs_flat_call_destructor
,
1098 static const struct afs_call_type afs_RXFSStoreData64
= {
1099 .name
= "FS.StoreData64",
1100 .deliver
= afs_deliver_fs_store_data
,
1101 .abort_to_error
= afs_abort_to_error
,
1102 .destructor
= afs_flat_call_destructor
,
1106 * store a set of pages to a very large file
1108 static int afs_fs_store_data64(struct afs_server
*server
,
1109 struct afs_writeback
*wb
,
1110 pgoff_t first
, pgoff_t last
,
1111 unsigned offset
, unsigned to
,
1112 loff_t size
, loff_t pos
, loff_t i_size
,
1113 const struct afs_wait_mode
*wait_mode
)
1115 struct afs_vnode
*vnode
= wb
->vnode
;
1116 struct afs_call
*call
;
1119 _enter(",%x,{%x:%u},,",
1120 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1122 call
= afs_alloc_flat_call(&afs_RXFSStoreData64
,
1123 (4 + 6 + 3 * 2) * 4,
1129 call
->key
= wb
->key
;
1130 call
->reply
= vnode
;
1131 call
->service_id
= FS_SERVICE
;
1132 call
->port
= htons(AFS_FS_PORT
);
1133 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1134 call
->first
= first
;
1136 call
->first_offset
= offset
;
1138 call
->send_pages
= true;
1139 call
->store_version
= vnode
->status
.data_version
+ 1;
1141 /* marshall the parameters */
1143 *bp
++ = htonl(FSSTOREDATA64
);
1144 *bp
++ = htonl(vnode
->fid
.vid
);
1145 *bp
++ = htonl(vnode
->fid
.vnode
);
1146 *bp
++ = htonl(vnode
->fid
.unique
);
1148 *bp
++ = 0; /* mask */
1149 *bp
++ = 0; /* mtime */
1150 *bp
++ = 0; /* owner */
1151 *bp
++ = 0; /* group */
1152 *bp
++ = 0; /* unix mode */
1153 *bp
++ = 0; /* segment size */
1155 *bp
++ = htonl(pos
>> 32);
1156 *bp
++ = htonl((u32
) pos
);
1157 *bp
++ = htonl(size
>> 32);
1158 *bp
++ = htonl((u32
) size
);
1159 *bp
++ = htonl(i_size
>> 32);
1160 *bp
++ = htonl((u32
) i_size
);
1162 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1166 * store a set of pages
1168 int afs_fs_store_data(struct afs_server
*server
, struct afs_writeback
*wb
,
1169 pgoff_t first
, pgoff_t last
,
1170 unsigned offset
, unsigned to
,
1171 const struct afs_wait_mode
*wait_mode
)
1173 struct afs_vnode
*vnode
= wb
->vnode
;
1174 struct afs_call
*call
;
1175 loff_t size
, pos
, i_size
;
1178 _enter(",%x,{%x:%u},,",
1179 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1183 size
+= (loff_t
)(last
- first
) << PAGE_SHIFT
;
1184 pos
= (loff_t
)first
<< PAGE_SHIFT
;
1187 i_size
= i_size_read(&vnode
->vfs_inode
);
1188 if (pos
+ size
> i_size
)
1189 i_size
= size
+ pos
;
1191 _debug("size %llx, at %llx, i_size %llx",
1192 (unsigned long long) size
, (unsigned long long) pos
,
1193 (unsigned long long) i_size
);
1195 if (pos
>> 32 || i_size
>> 32 || size
>> 32 || (pos
+ size
) >> 32)
1196 return afs_fs_store_data64(server
, wb
, first
, last
, offset
, to
,
1197 size
, pos
, i_size
, wait_mode
);
1199 call
= afs_alloc_flat_call(&afs_RXFSStoreData
,
1206 call
->key
= wb
->key
;
1207 call
->reply
= vnode
;
1208 call
->service_id
= FS_SERVICE
;
1209 call
->port
= htons(AFS_FS_PORT
);
1210 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1211 call
->first
= first
;
1213 call
->first_offset
= offset
;
1215 call
->send_pages
= true;
1216 call
->store_version
= vnode
->status
.data_version
+ 1;
1218 /* marshall the parameters */
1220 *bp
++ = htonl(FSSTOREDATA
);
1221 *bp
++ = htonl(vnode
->fid
.vid
);
1222 *bp
++ = htonl(vnode
->fid
.vnode
);
1223 *bp
++ = htonl(vnode
->fid
.unique
);
1225 *bp
++ = 0; /* mask */
1226 *bp
++ = 0; /* mtime */
1227 *bp
++ = 0; /* owner */
1228 *bp
++ = 0; /* group */
1229 *bp
++ = 0; /* unix mode */
1230 *bp
++ = 0; /* segment size */
1233 *bp
++ = htonl(size
);
1234 *bp
++ = htonl(i_size
);
1236 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1240 * deliver reply data to an FS.StoreStatus
1242 static int afs_deliver_fs_store_status(struct afs_call
*call
)
1244 afs_dataversion_t
*store_version
;
1245 struct afs_vnode
*vnode
= call
->reply
;
1251 ret
= afs_transfer_reply(call
);
1255 /* unmarshall the reply once we've received all of it */
1256 store_version
= NULL
;
1257 if (call
->operation_ID
== FSSTOREDATA
)
1258 store_version
= &call
->store_version
;
1261 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, store_version
);
1262 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1264 _leave(" = 0 [done]");
1269 * FS.StoreStatus operation type
1271 static const struct afs_call_type afs_RXFSStoreStatus
= {
1272 .name
= "FS.StoreStatus",
1273 .deliver
= afs_deliver_fs_store_status
,
1274 .abort_to_error
= afs_abort_to_error
,
1275 .destructor
= afs_flat_call_destructor
,
1278 static const struct afs_call_type afs_RXFSStoreData_as_Status
= {
1279 .name
= "FS.StoreData",
1280 .deliver
= afs_deliver_fs_store_status
,
1281 .abort_to_error
= afs_abort_to_error
,
1282 .destructor
= afs_flat_call_destructor
,
1285 static const struct afs_call_type afs_RXFSStoreData64_as_Status
= {
1286 .name
= "FS.StoreData64",
1287 .deliver
= afs_deliver_fs_store_status
,
1288 .abort_to_error
= afs_abort_to_error
,
1289 .destructor
= afs_flat_call_destructor
,
1293 * set the attributes on a very large file, using FS.StoreData rather than
1294 * FS.StoreStatus so as to alter the file size also
1296 static int afs_fs_setattr_size64(struct afs_server
*server
, struct key
*key
,
1297 struct afs_vnode
*vnode
, struct iattr
*attr
,
1298 const struct afs_wait_mode
*wait_mode
)
1300 struct afs_call
*call
;
1303 _enter(",%x,{%x:%u},,",
1304 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1306 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1308 call
= afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status
,
1309 (4 + 6 + 3 * 2) * 4,
1315 call
->reply
= vnode
;
1316 call
->service_id
= FS_SERVICE
;
1317 call
->port
= htons(AFS_FS_PORT
);
1318 call
->store_version
= vnode
->status
.data_version
+ 1;
1319 call
->operation_ID
= FSSTOREDATA
;
1321 /* marshall the parameters */
1323 *bp
++ = htonl(FSSTOREDATA64
);
1324 *bp
++ = htonl(vnode
->fid
.vid
);
1325 *bp
++ = htonl(vnode
->fid
.vnode
);
1326 *bp
++ = htonl(vnode
->fid
.unique
);
1328 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1330 *bp
++ = 0; /* position of start of write */
1332 *bp
++ = 0; /* size of write */
1334 *bp
++ = htonl(attr
->ia_size
>> 32); /* new file length */
1335 *bp
++ = htonl((u32
) attr
->ia_size
);
1337 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1341 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1342 * so as to alter the file size also
1344 static int afs_fs_setattr_size(struct afs_server
*server
, struct key
*key
,
1345 struct afs_vnode
*vnode
, struct iattr
*attr
,
1346 const struct afs_wait_mode
*wait_mode
)
1348 struct afs_call
*call
;
1351 _enter(",%x,{%x:%u},,",
1352 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1354 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1355 if (attr
->ia_size
>> 32)
1356 return afs_fs_setattr_size64(server
, key
, vnode
, attr
,
1359 call
= afs_alloc_flat_call(&afs_RXFSStoreData_as_Status
,
1366 call
->reply
= vnode
;
1367 call
->service_id
= FS_SERVICE
;
1368 call
->port
= htons(AFS_FS_PORT
);
1369 call
->store_version
= vnode
->status
.data_version
+ 1;
1370 call
->operation_ID
= FSSTOREDATA
;
1372 /* marshall the parameters */
1374 *bp
++ = htonl(FSSTOREDATA
);
1375 *bp
++ = htonl(vnode
->fid
.vid
);
1376 *bp
++ = htonl(vnode
->fid
.vnode
);
1377 *bp
++ = htonl(vnode
->fid
.unique
);
1379 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1381 *bp
++ = 0; /* position of start of write */
1382 *bp
++ = 0; /* size of write */
1383 *bp
++ = htonl(attr
->ia_size
); /* new file length */
1385 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1389 * set the attributes on a file, using FS.StoreData if there's a change in file
1390 * size, and FS.StoreStatus otherwise
1392 int afs_fs_setattr(struct afs_server
*server
, struct key
*key
,
1393 struct afs_vnode
*vnode
, struct iattr
*attr
,
1394 const struct afs_wait_mode
*wait_mode
)
1396 struct afs_call
*call
;
1399 if (attr
->ia_valid
& ATTR_SIZE
)
1400 return afs_fs_setattr_size(server
, key
, vnode
, attr
,
1403 _enter(",%x,{%x:%u},,",
1404 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1406 call
= afs_alloc_flat_call(&afs_RXFSStoreStatus
,
1413 call
->reply
= vnode
;
1414 call
->service_id
= FS_SERVICE
;
1415 call
->port
= htons(AFS_FS_PORT
);
1416 call
->operation_ID
= FSSTORESTATUS
;
1418 /* marshall the parameters */
1420 *bp
++ = htonl(FSSTORESTATUS
);
1421 *bp
++ = htonl(vnode
->fid
.vid
);
1422 *bp
++ = htonl(vnode
->fid
.vnode
);
1423 *bp
++ = htonl(vnode
->fid
.unique
);
1425 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1427 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1431 * deliver reply data to an FS.GetVolumeStatus
1433 static int afs_deliver_fs_get_volume_status(struct afs_call
*call
)
1439 _enter("{%u}", call
->unmarshall
);
1441 switch (call
->unmarshall
) {
1446 /* extract the returned status record */
1448 _debug("extract status");
1449 ret
= afs_extract_data(call
, call
->buffer
,
1455 xdr_decode_AFSFetchVolumeStatus(&bp
, call
->reply2
);
1459 /* extract the volume name length */
1461 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
1465 call
->count
= ntohl(call
->tmp
);
1466 _debug("volname length: %u", call
->count
);
1467 if (call
->count
>= AFSNAMEMAX
)
1472 /* extract the volume name */
1474 _debug("extract volname");
1475 if (call
->count
> 0) {
1476 ret
= afs_extract_data(call
, call
->reply3
,
1484 _debug("volname '%s'", p
);
1489 /* extract the volume name padding */
1490 if ((call
->count
& 3) == 0) {
1492 goto no_volname_padding
;
1494 call
->count
= 4 - (call
->count
& 3);
1497 ret
= afs_extract_data(call
, call
->buffer
,
1506 /* extract the offline message length */
1508 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
1512 call
->count
= ntohl(call
->tmp
);
1513 _debug("offline msg length: %u", call
->count
);
1514 if (call
->count
>= AFSNAMEMAX
)
1519 /* extract the offline message */
1521 _debug("extract offline");
1522 if (call
->count
> 0) {
1523 ret
= afs_extract_data(call
, call
->reply3
,
1531 _debug("offline '%s'", p
);
1536 /* extract the offline message padding */
1537 if ((call
->count
& 3) == 0) {
1539 goto no_offline_padding
;
1541 call
->count
= 4 - (call
->count
& 3);
1544 ret
= afs_extract_data(call
, call
->buffer
,
1553 /* extract the message of the day length */
1555 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
1559 call
->count
= ntohl(call
->tmp
);
1560 _debug("motd length: %u", call
->count
);
1561 if (call
->count
>= AFSNAMEMAX
)
1566 /* extract the message of the day */
1568 _debug("extract motd");
1569 if (call
->count
> 0) {
1570 ret
= afs_extract_data(call
, call
->reply3
,
1578 _debug("motd '%s'", p
);
1583 /* extract the message of the day padding */
1584 call
->count
= (4 - (call
->count
& 3)) & 3;
1587 ret
= afs_extract_data(call
, call
->buffer
,
1588 call
->count
, false);
1598 _leave(" = 0 [done]");
1603 * destroy an FS.GetVolumeStatus call
1605 static void afs_get_volume_status_call_destructor(struct afs_call
*call
)
1607 kfree(call
->reply3
);
1608 call
->reply3
= NULL
;
1609 afs_flat_call_destructor(call
);
1613 * FS.GetVolumeStatus operation type
1615 static const struct afs_call_type afs_RXFSGetVolumeStatus
= {
1616 .name
= "FS.GetVolumeStatus",
1617 .deliver
= afs_deliver_fs_get_volume_status
,
1618 .abort_to_error
= afs_abort_to_error
,
1619 .destructor
= afs_get_volume_status_call_destructor
,
1623 * fetch the status of a volume
1625 int afs_fs_get_volume_status(struct afs_server
*server
,
1627 struct afs_vnode
*vnode
,
1628 struct afs_volume_status
*vs
,
1629 const struct afs_wait_mode
*wait_mode
)
1631 struct afs_call
*call
;
1637 tmpbuf
= kmalloc(AFSOPAQUEMAX
, GFP_KERNEL
);
1641 call
= afs_alloc_flat_call(&afs_RXFSGetVolumeStatus
, 2 * 4, 12 * 4);
1648 call
->reply
= vnode
;
1650 call
->reply3
= tmpbuf
;
1651 call
->service_id
= FS_SERVICE
;
1652 call
->port
= htons(AFS_FS_PORT
);
1654 /* marshall the parameters */
1656 bp
[0] = htonl(FSGETVOLUMESTATUS
);
1657 bp
[1] = htonl(vnode
->fid
.vid
);
1659 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1663 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1665 static int afs_deliver_fs_xxxx_lock(struct afs_call
*call
)
1670 _enter("{%u}", call
->unmarshall
);
1672 ret
= afs_transfer_reply(call
);
1676 /* unmarshall the reply once we've received all of it */
1678 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1680 _leave(" = 0 [done]");
1685 * FS.SetLock operation type
1687 static const struct afs_call_type afs_RXFSSetLock
= {
1688 .name
= "FS.SetLock",
1689 .deliver
= afs_deliver_fs_xxxx_lock
,
1690 .abort_to_error
= afs_abort_to_error
,
1691 .destructor
= afs_flat_call_destructor
,
1695 * FS.ExtendLock operation type
1697 static const struct afs_call_type afs_RXFSExtendLock
= {
1698 .name
= "FS.ExtendLock",
1699 .deliver
= afs_deliver_fs_xxxx_lock
,
1700 .abort_to_error
= afs_abort_to_error
,
1701 .destructor
= afs_flat_call_destructor
,
1705 * FS.ReleaseLock operation type
1707 static const struct afs_call_type afs_RXFSReleaseLock
= {
1708 .name
= "FS.ReleaseLock",
1709 .deliver
= afs_deliver_fs_xxxx_lock
,
1710 .abort_to_error
= afs_abort_to_error
,
1711 .destructor
= afs_flat_call_destructor
,
1715 * get a lock on a file
1717 int afs_fs_set_lock(struct afs_server
*server
,
1719 struct afs_vnode
*vnode
,
1720 afs_lock_type_t type
,
1721 const struct afs_wait_mode
*wait_mode
)
1723 struct afs_call
*call
;
1728 call
= afs_alloc_flat_call(&afs_RXFSSetLock
, 5 * 4, 6 * 4);
1733 call
->reply
= vnode
;
1734 call
->service_id
= FS_SERVICE
;
1735 call
->port
= htons(AFS_FS_PORT
);
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 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1749 * extend a lock on a file
1751 int afs_fs_extend_lock(struct afs_server
*server
,
1753 struct afs_vnode
*vnode
,
1754 const struct afs_wait_mode
*wait_mode
)
1756 struct afs_call
*call
;
1761 call
= afs_alloc_flat_call(&afs_RXFSExtendLock
, 4 * 4, 6 * 4);
1766 call
->reply
= vnode
;
1767 call
->service_id
= FS_SERVICE
;
1768 call
->port
= htons(AFS_FS_PORT
);
1770 /* marshall the parameters */
1772 *bp
++ = htonl(FSEXTENDLOCK
);
1773 *bp
++ = htonl(vnode
->fid
.vid
);
1774 *bp
++ = htonl(vnode
->fid
.vnode
);
1775 *bp
++ = htonl(vnode
->fid
.unique
);
1777 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1781 * release a lock on a file
1783 int afs_fs_release_lock(struct afs_server
*server
,
1785 struct afs_vnode
*vnode
,
1786 const struct afs_wait_mode
*wait_mode
)
1788 struct afs_call
*call
;
1793 call
= afs_alloc_flat_call(&afs_RXFSReleaseLock
, 4 * 4, 6 * 4);
1798 call
->reply
= vnode
;
1799 call
->service_id
= FS_SERVICE
;
1800 call
->port
= htons(AFS_FS_PORT
);
1802 /* marshall the parameters */
1804 *bp
++ = htonl(FSRELEASELOCK
);
1805 *bp
++ = htonl(vnode
->fid
.vid
);
1806 *bp
++ = htonl(vnode
->fid
.vnode
);
1807 *bp
++ = htonl(vnode
->fid
.unique
);
1809 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);