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
,
239 struct sk_buff
*skb
, bool last
)
241 struct afs_vnode
*vnode
= call
->reply
;
245 _enter(",,%u", last
);
247 ret
= afs_transfer_reply(call
, skb
, last
);
251 /* unmarshall the reply once we've received all of it */
253 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
254 xdr_decode_AFSCallBack(&bp
, vnode
);
256 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
258 _leave(" = 0 [done]");
263 * FS.FetchStatus operation type
265 static const struct afs_call_type afs_RXFSFetchStatus
= {
266 .name
= "FS.FetchStatus",
267 .deliver
= afs_deliver_fs_fetch_status
,
268 .abort_to_error
= afs_abort_to_error
,
269 .destructor
= afs_flat_call_destructor
,
273 * fetch the status information for a file
275 int afs_fs_fetch_file_status(struct afs_server
*server
,
277 struct afs_vnode
*vnode
,
278 struct afs_volsync
*volsync
,
279 const struct afs_wait_mode
*wait_mode
)
281 struct afs_call
*call
;
284 _enter(",%x,{%x:%u},,",
285 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
287 call
= afs_alloc_flat_call(&afs_RXFSFetchStatus
, 16, (21 + 3 + 6) * 4);
293 call
->reply2
= volsync
;
294 call
->service_id
= FS_SERVICE
;
295 call
->port
= htons(AFS_FS_PORT
);
297 /* marshall the parameters */
299 bp
[0] = htonl(FSFETCHSTATUS
);
300 bp
[1] = htonl(vnode
->fid
.vid
);
301 bp
[2] = htonl(vnode
->fid
.vnode
);
302 bp
[3] = htonl(vnode
->fid
.unique
);
304 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
308 * deliver reply data to an FS.FetchData
310 static int afs_deliver_fs_fetch_data(struct afs_call
*call
,
311 struct sk_buff
*skb
, bool last
)
313 struct afs_vnode
*vnode
= call
->reply
;
319 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
321 switch (call
->unmarshall
) {
325 if (call
->operation_ID
!= FSFETCHDATA64
) {
330 /* extract the upper part of the returned data length of an
331 * FSFETCHDATA64 op (which should always be 0 using this
334 _debug("extract data length (MSW)");
335 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
339 call
->count
= ntohl(call
->tmp
);
340 _debug("DATA length MSW: %u", call
->count
);
347 /* extract the returned data length */
349 _debug("extract data length");
350 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
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
);
367 ret
= afs_extract_data(call
, skb
, last
, buffer
,
369 kunmap_atomic(buffer
);
377 /* extract the metadata */
379 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
385 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
386 xdr_decode_AFSCallBack(&bp
, vnode
);
388 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
394 ret
= afs_data_complete(call
, skb
, last
);
400 if (call
->count
< PAGE_SIZE
) {
403 buffer
= kmap_atomic(page
);
404 memset(buffer
+ call
->count
, 0, PAGE_SIZE
- call
->count
);
405 kunmap_atomic(buffer
);
408 _leave(" = 0 [done]");
413 * FS.FetchData operation type
415 static const struct afs_call_type afs_RXFSFetchData
= {
416 .name
= "FS.FetchData",
417 .deliver
= afs_deliver_fs_fetch_data
,
418 .abort_to_error
= afs_abort_to_error
,
419 .destructor
= afs_flat_call_destructor
,
422 static const struct afs_call_type afs_RXFSFetchData64
= {
423 .name
= "FS.FetchData64",
424 .deliver
= afs_deliver_fs_fetch_data
,
425 .abort_to_error
= afs_abort_to_error
,
426 .destructor
= afs_flat_call_destructor
,
430 * fetch data from a very large file
432 static int afs_fs_fetch_data64(struct afs_server
*server
,
434 struct afs_vnode
*vnode
,
435 off_t offset
, size_t length
,
437 const struct afs_wait_mode
*wait_mode
)
439 struct afs_call
*call
;
444 ASSERTCMP(length
, <, ULONG_MAX
);
446 call
= afs_alloc_flat_call(&afs_RXFSFetchData64
, 32, (21 + 3 + 6) * 4);
452 call
->reply2
= NULL
; /* volsync */
453 call
->reply3
= buffer
;
454 call
->service_id
= FS_SERVICE
;
455 call
->port
= htons(AFS_FS_PORT
);
456 call
->operation_ID
= FSFETCHDATA64
;
458 /* marshall the parameters */
460 bp
[0] = htonl(FSFETCHDATA64
);
461 bp
[1] = htonl(vnode
->fid
.vid
);
462 bp
[2] = htonl(vnode
->fid
.vnode
);
463 bp
[3] = htonl(vnode
->fid
.unique
);
464 bp
[4] = htonl(upper_32_bits(offset
));
465 bp
[5] = htonl((u32
) offset
);
467 bp
[7] = htonl((u32
) length
);
469 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
473 * fetch data from a file
475 int afs_fs_fetch_data(struct afs_server
*server
,
477 struct afs_vnode
*vnode
,
478 off_t offset
, size_t length
,
480 const struct afs_wait_mode
*wait_mode
)
482 struct afs_call
*call
;
485 if (upper_32_bits(offset
) || upper_32_bits(offset
+ length
))
486 return afs_fs_fetch_data64(server
, key
, vnode
, offset
, length
,
491 call
= afs_alloc_flat_call(&afs_RXFSFetchData
, 24, (21 + 3 + 6) * 4);
497 call
->reply2
= NULL
; /* volsync */
498 call
->reply3
= buffer
;
499 call
->service_id
= FS_SERVICE
;
500 call
->port
= htons(AFS_FS_PORT
);
501 call
->operation_ID
= FSFETCHDATA
;
503 /* marshall the parameters */
505 bp
[0] = htonl(FSFETCHDATA
);
506 bp
[1] = htonl(vnode
->fid
.vid
);
507 bp
[2] = htonl(vnode
->fid
.vnode
);
508 bp
[3] = htonl(vnode
->fid
.unique
);
509 bp
[4] = htonl(offset
);
510 bp
[5] = htonl(length
);
512 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
516 * deliver reply data to an FS.GiveUpCallBacks
518 static int afs_deliver_fs_give_up_callbacks(struct afs_call
*call
,
519 struct sk_buff
*skb
, bool last
)
521 _enter(",{%u},%d", skb
->len
, last
);
523 /* shouldn't be any reply data */
524 return afs_data_complete(call
, skb
, last
);
528 * FS.GiveUpCallBacks operation type
530 static const struct afs_call_type afs_RXFSGiveUpCallBacks
= {
531 .name
= "FS.GiveUpCallBacks",
532 .deliver
= afs_deliver_fs_give_up_callbacks
,
533 .abort_to_error
= afs_abort_to_error
,
534 .destructor
= afs_flat_call_destructor
,
538 * give up a set of callbacks
539 * - the callbacks are held in the server->cb_break ring
541 int afs_fs_give_up_callbacks(struct afs_server
*server
,
542 const struct afs_wait_mode
*wait_mode
)
544 struct afs_call
*call
;
549 ncallbacks
= CIRC_CNT(server
->cb_break_head
, server
->cb_break_tail
,
550 ARRAY_SIZE(server
->cb_break
));
552 _enter("{%zu},", ncallbacks
);
556 if (ncallbacks
> AFSCBMAX
)
557 ncallbacks
= AFSCBMAX
;
559 _debug("break %zu callbacks", ncallbacks
);
561 call
= afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks
,
562 12 + ncallbacks
* 6 * 4, 0);
566 call
->service_id
= FS_SERVICE
;
567 call
->port
= htons(AFS_FS_PORT
);
569 /* marshall the parameters */
571 tp
= bp
+ 2 + ncallbacks
* 3;
572 *bp
++ = htonl(FSGIVEUPCALLBACKS
);
573 *bp
++ = htonl(ncallbacks
);
574 *tp
++ = htonl(ncallbacks
);
576 atomic_sub(ncallbacks
, &server
->cb_break_n
);
577 for (loop
= ncallbacks
; loop
> 0; loop
--) {
578 struct afs_callback
*cb
=
579 &server
->cb_break
[server
->cb_break_tail
];
581 *bp
++ = htonl(cb
->fid
.vid
);
582 *bp
++ = htonl(cb
->fid
.vnode
);
583 *bp
++ = htonl(cb
->fid
.unique
);
584 *tp
++ = htonl(cb
->version
);
585 *tp
++ = htonl(cb
->expiry
);
586 *tp
++ = htonl(cb
->type
);
588 server
->cb_break_tail
=
589 (server
->cb_break_tail
+ 1) &
590 (ARRAY_SIZE(server
->cb_break
) - 1);
593 ASSERT(ncallbacks
> 0);
594 wake_up_nr(&server
->cb_break_waitq
, ncallbacks
);
596 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
600 * deliver reply data to an FS.CreateFile or an FS.MakeDir
602 static int afs_deliver_fs_create_vnode(struct afs_call
*call
,
603 struct sk_buff
*skb
, bool last
)
605 struct afs_vnode
*vnode
= call
->reply
;
609 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
611 ret
= afs_transfer_reply(call
, skb
, last
);
615 /* unmarshall the reply once we've received all of it */
617 xdr_decode_AFSFid(&bp
, call
->reply2
);
618 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
619 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
620 xdr_decode_AFSCallBack_raw(&bp
, call
->reply4
);
621 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
623 _leave(" = 0 [done]");
628 * FS.CreateFile and FS.MakeDir operation type
630 static const struct afs_call_type afs_RXFSCreateXXXX
= {
631 .name
= "FS.CreateXXXX",
632 .deliver
= afs_deliver_fs_create_vnode
,
633 .abort_to_error
= afs_abort_to_error
,
634 .destructor
= afs_flat_call_destructor
,
638 * create a file or make a directory
640 int afs_fs_create(struct afs_server
*server
,
642 struct afs_vnode
*vnode
,
645 struct afs_fid
*newfid
,
646 struct afs_file_status
*newstatus
,
647 struct afs_callback
*newcb
,
648 const struct afs_wait_mode
*wait_mode
)
650 struct afs_call
*call
;
651 size_t namesz
, reqsz
, padsz
;
656 namesz
= strlen(name
);
657 padsz
= (4 - (namesz
& 3)) & 3;
658 reqsz
= (5 * 4) + namesz
+ padsz
+ (6 * 4);
660 call
= afs_alloc_flat_call(&afs_RXFSCreateXXXX
, reqsz
,
661 (3 + 21 + 21 + 3 + 6) * 4);
667 call
->reply2
= newfid
;
668 call
->reply3
= newstatus
;
669 call
->reply4
= newcb
;
670 call
->service_id
= FS_SERVICE
;
671 call
->port
= htons(AFS_FS_PORT
);
673 /* marshall the parameters */
675 *bp
++ = htonl(S_ISDIR(mode
) ? FSMAKEDIR
: FSCREATEFILE
);
676 *bp
++ = htonl(vnode
->fid
.vid
);
677 *bp
++ = htonl(vnode
->fid
.vnode
);
678 *bp
++ = htonl(vnode
->fid
.unique
);
679 *bp
++ = htonl(namesz
);
680 memcpy(bp
, name
, namesz
);
681 bp
= (void *) bp
+ namesz
;
683 memset(bp
, 0, padsz
);
684 bp
= (void *) bp
+ padsz
;
686 *bp
++ = htonl(AFS_SET_MODE
);
687 *bp
++ = 0; /* mtime */
688 *bp
++ = 0; /* owner */
689 *bp
++ = 0; /* group */
690 *bp
++ = htonl(mode
& S_IALLUGO
); /* unix mode */
691 *bp
++ = 0; /* segment size */
693 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
697 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
699 static int afs_deliver_fs_remove(struct afs_call
*call
,
700 struct sk_buff
*skb
, bool last
)
702 struct afs_vnode
*vnode
= call
->reply
;
706 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
708 ret
= afs_transfer_reply(call
, skb
, last
);
712 /* unmarshall the reply once we've received all of it */
714 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
715 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
717 _leave(" = 0 [done]");
722 * FS.RemoveDir/FS.RemoveFile operation type
724 static const struct afs_call_type afs_RXFSRemoveXXXX
= {
725 .name
= "FS.RemoveXXXX",
726 .deliver
= afs_deliver_fs_remove
,
727 .abort_to_error
= afs_abort_to_error
,
728 .destructor
= afs_flat_call_destructor
,
732 * remove a file or directory
734 int afs_fs_remove(struct afs_server
*server
,
736 struct afs_vnode
*vnode
,
739 const struct afs_wait_mode
*wait_mode
)
741 struct afs_call
*call
;
742 size_t namesz
, reqsz
, padsz
;
747 namesz
= strlen(name
);
748 padsz
= (4 - (namesz
& 3)) & 3;
749 reqsz
= (5 * 4) + namesz
+ padsz
;
751 call
= afs_alloc_flat_call(&afs_RXFSRemoveXXXX
, reqsz
, (21 + 6) * 4);
757 call
->service_id
= FS_SERVICE
;
758 call
->port
= htons(AFS_FS_PORT
);
760 /* marshall the parameters */
762 *bp
++ = htonl(isdir
? FSREMOVEDIR
: FSREMOVEFILE
);
763 *bp
++ = htonl(vnode
->fid
.vid
);
764 *bp
++ = htonl(vnode
->fid
.vnode
);
765 *bp
++ = htonl(vnode
->fid
.unique
);
766 *bp
++ = htonl(namesz
);
767 memcpy(bp
, name
, namesz
);
768 bp
= (void *) bp
+ namesz
;
770 memset(bp
, 0, padsz
);
771 bp
= (void *) bp
+ padsz
;
774 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
778 * deliver reply data to an FS.Link
780 static int afs_deliver_fs_link(struct afs_call
*call
,
781 struct sk_buff
*skb
, bool last
)
783 struct afs_vnode
*dvnode
= call
->reply
, *vnode
= call
->reply2
;
787 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
789 ret
= afs_transfer_reply(call
, skb
, last
);
793 /* unmarshall the reply once we've received all of it */
795 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
796 xdr_decode_AFSFetchStatus(&bp
, &dvnode
->status
, dvnode
, NULL
);
797 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
799 _leave(" = 0 [done]");
804 * FS.Link operation type
806 static const struct afs_call_type afs_RXFSLink
= {
808 .deliver
= afs_deliver_fs_link
,
809 .abort_to_error
= afs_abort_to_error
,
810 .destructor
= afs_flat_call_destructor
,
816 int afs_fs_link(struct afs_server
*server
,
818 struct afs_vnode
*dvnode
,
819 struct afs_vnode
*vnode
,
821 const struct afs_wait_mode
*wait_mode
)
823 struct afs_call
*call
;
824 size_t namesz
, reqsz
, padsz
;
829 namesz
= strlen(name
);
830 padsz
= (4 - (namesz
& 3)) & 3;
831 reqsz
= (5 * 4) + namesz
+ padsz
+ (3 * 4);
833 call
= afs_alloc_flat_call(&afs_RXFSLink
, reqsz
, (21 + 21 + 6) * 4);
838 call
->reply
= dvnode
;
839 call
->reply2
= vnode
;
840 call
->service_id
= FS_SERVICE
;
841 call
->port
= htons(AFS_FS_PORT
);
843 /* marshall the parameters */
845 *bp
++ = htonl(FSLINK
);
846 *bp
++ = htonl(dvnode
->fid
.vid
);
847 *bp
++ = htonl(dvnode
->fid
.vnode
);
848 *bp
++ = htonl(dvnode
->fid
.unique
);
849 *bp
++ = htonl(namesz
);
850 memcpy(bp
, name
, namesz
);
851 bp
= (void *) bp
+ namesz
;
853 memset(bp
, 0, padsz
);
854 bp
= (void *) bp
+ padsz
;
856 *bp
++ = htonl(vnode
->fid
.vid
);
857 *bp
++ = htonl(vnode
->fid
.vnode
);
858 *bp
++ = htonl(vnode
->fid
.unique
);
860 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
864 * deliver reply data to an FS.Symlink
866 static int afs_deliver_fs_symlink(struct afs_call
*call
,
867 struct sk_buff
*skb
, bool last
)
869 struct afs_vnode
*vnode
= call
->reply
;
873 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
875 ret
= afs_transfer_reply(call
, skb
, last
);
879 /* unmarshall the reply once we've received all of it */
881 xdr_decode_AFSFid(&bp
, call
->reply2
);
882 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
883 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
884 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
886 _leave(" = 0 [done]");
891 * FS.Symlink operation type
893 static const struct afs_call_type afs_RXFSSymlink
= {
894 .name
= "FS.Symlink",
895 .deliver
= afs_deliver_fs_symlink
,
896 .abort_to_error
= afs_abort_to_error
,
897 .destructor
= afs_flat_call_destructor
,
901 * create a symbolic link
903 int afs_fs_symlink(struct afs_server
*server
,
905 struct afs_vnode
*vnode
,
907 const char *contents
,
908 struct afs_fid
*newfid
,
909 struct afs_file_status
*newstatus
,
910 const struct afs_wait_mode
*wait_mode
)
912 struct afs_call
*call
;
913 size_t namesz
, reqsz
, padsz
, c_namesz
, c_padsz
;
918 namesz
= strlen(name
);
919 padsz
= (4 - (namesz
& 3)) & 3;
921 c_namesz
= strlen(contents
);
922 c_padsz
= (4 - (c_namesz
& 3)) & 3;
924 reqsz
= (6 * 4) + namesz
+ padsz
+ c_namesz
+ c_padsz
+ (6 * 4);
926 call
= afs_alloc_flat_call(&afs_RXFSSymlink
, reqsz
,
927 (3 + 21 + 21 + 6) * 4);
933 call
->reply2
= newfid
;
934 call
->reply3
= newstatus
;
935 call
->service_id
= FS_SERVICE
;
936 call
->port
= htons(AFS_FS_PORT
);
938 /* marshall the parameters */
940 *bp
++ = htonl(FSSYMLINK
);
941 *bp
++ = htonl(vnode
->fid
.vid
);
942 *bp
++ = htonl(vnode
->fid
.vnode
);
943 *bp
++ = htonl(vnode
->fid
.unique
);
944 *bp
++ = htonl(namesz
);
945 memcpy(bp
, name
, namesz
);
946 bp
= (void *) bp
+ namesz
;
948 memset(bp
, 0, padsz
);
949 bp
= (void *) bp
+ padsz
;
951 *bp
++ = htonl(c_namesz
);
952 memcpy(bp
, contents
, c_namesz
);
953 bp
= (void *) bp
+ c_namesz
;
955 memset(bp
, 0, c_padsz
);
956 bp
= (void *) bp
+ c_padsz
;
958 *bp
++ = htonl(AFS_SET_MODE
);
959 *bp
++ = 0; /* mtime */
960 *bp
++ = 0; /* owner */
961 *bp
++ = 0; /* group */
962 *bp
++ = htonl(S_IRWXUGO
); /* unix mode */
963 *bp
++ = 0; /* segment size */
965 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
969 * deliver reply data to an FS.Rename
971 static int afs_deliver_fs_rename(struct afs_call
*call
,
972 struct sk_buff
*skb
, bool last
)
974 struct afs_vnode
*orig_dvnode
= call
->reply
, *new_dvnode
= call
->reply2
;
978 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
980 ret
= afs_transfer_reply(call
, skb
, last
);
984 /* unmarshall the reply once we've received all of it */
986 xdr_decode_AFSFetchStatus(&bp
, &orig_dvnode
->status
, orig_dvnode
, NULL
);
987 if (new_dvnode
!= orig_dvnode
)
988 xdr_decode_AFSFetchStatus(&bp
, &new_dvnode
->status
, new_dvnode
,
990 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
992 _leave(" = 0 [done]");
997 * FS.Rename operation type
999 static const struct afs_call_type afs_RXFSRename
= {
1000 .name
= "FS.Rename",
1001 .deliver
= afs_deliver_fs_rename
,
1002 .abort_to_error
= afs_abort_to_error
,
1003 .destructor
= afs_flat_call_destructor
,
1007 * create a symbolic link
1009 int afs_fs_rename(struct afs_server
*server
,
1011 struct afs_vnode
*orig_dvnode
,
1012 const char *orig_name
,
1013 struct afs_vnode
*new_dvnode
,
1014 const char *new_name
,
1015 const struct afs_wait_mode
*wait_mode
)
1017 struct afs_call
*call
;
1018 size_t reqsz
, o_namesz
, o_padsz
, n_namesz
, n_padsz
;
1023 o_namesz
= strlen(orig_name
);
1024 o_padsz
= (4 - (o_namesz
& 3)) & 3;
1026 n_namesz
= strlen(new_name
);
1027 n_padsz
= (4 - (n_namesz
& 3)) & 3;
1030 4 + o_namesz
+ o_padsz
+
1032 4 + n_namesz
+ n_padsz
;
1034 call
= afs_alloc_flat_call(&afs_RXFSRename
, reqsz
, (21 + 21 + 6) * 4);
1039 call
->reply
= orig_dvnode
;
1040 call
->reply2
= new_dvnode
;
1041 call
->service_id
= FS_SERVICE
;
1042 call
->port
= htons(AFS_FS_PORT
);
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 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1073 * deliver reply data to an FS.StoreData
1075 static int afs_deliver_fs_store_data(struct afs_call
*call
,
1076 struct sk_buff
*skb
, bool last
)
1078 struct afs_vnode
*vnode
= call
->reply
;
1082 _enter(",,%u", last
);
1084 ret
= afs_transfer_reply(call
, skb
, last
);
1088 /* unmarshall the reply once we've received all of it */
1090 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
,
1091 &call
->store_version
);
1092 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1094 afs_pages_written_back(vnode
, call
);
1096 _leave(" = 0 [done]");
1101 * FS.StoreData operation type
1103 static const struct afs_call_type afs_RXFSStoreData
= {
1104 .name
= "FS.StoreData",
1105 .deliver
= afs_deliver_fs_store_data
,
1106 .abort_to_error
= afs_abort_to_error
,
1107 .destructor
= afs_flat_call_destructor
,
1110 static const struct afs_call_type afs_RXFSStoreData64
= {
1111 .name
= "FS.StoreData64",
1112 .deliver
= afs_deliver_fs_store_data
,
1113 .abort_to_error
= afs_abort_to_error
,
1114 .destructor
= afs_flat_call_destructor
,
1118 * store a set of pages to a very large file
1120 static int afs_fs_store_data64(struct afs_server
*server
,
1121 struct afs_writeback
*wb
,
1122 pgoff_t first
, pgoff_t last
,
1123 unsigned offset
, unsigned to
,
1124 loff_t size
, loff_t pos
, loff_t i_size
,
1125 const struct afs_wait_mode
*wait_mode
)
1127 struct afs_vnode
*vnode
= wb
->vnode
;
1128 struct afs_call
*call
;
1131 _enter(",%x,{%x:%u},,",
1132 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1134 call
= afs_alloc_flat_call(&afs_RXFSStoreData64
,
1135 (4 + 6 + 3 * 2) * 4,
1141 call
->key
= wb
->key
;
1142 call
->reply
= vnode
;
1143 call
->service_id
= FS_SERVICE
;
1144 call
->port
= htons(AFS_FS_PORT
);
1145 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1146 call
->first
= first
;
1148 call
->first_offset
= offset
;
1150 call
->send_pages
= true;
1151 call
->store_version
= vnode
->status
.data_version
+ 1;
1153 /* marshall the parameters */
1155 *bp
++ = htonl(FSSTOREDATA64
);
1156 *bp
++ = htonl(vnode
->fid
.vid
);
1157 *bp
++ = htonl(vnode
->fid
.vnode
);
1158 *bp
++ = htonl(vnode
->fid
.unique
);
1160 *bp
++ = 0; /* mask */
1161 *bp
++ = 0; /* mtime */
1162 *bp
++ = 0; /* owner */
1163 *bp
++ = 0; /* group */
1164 *bp
++ = 0; /* unix mode */
1165 *bp
++ = 0; /* segment size */
1167 *bp
++ = htonl(pos
>> 32);
1168 *bp
++ = htonl((u32
) pos
);
1169 *bp
++ = htonl(size
>> 32);
1170 *bp
++ = htonl((u32
) size
);
1171 *bp
++ = htonl(i_size
>> 32);
1172 *bp
++ = htonl((u32
) i_size
);
1174 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1178 * store a set of pages
1180 int afs_fs_store_data(struct afs_server
*server
, struct afs_writeback
*wb
,
1181 pgoff_t first
, pgoff_t last
,
1182 unsigned offset
, unsigned to
,
1183 const struct afs_wait_mode
*wait_mode
)
1185 struct afs_vnode
*vnode
= wb
->vnode
;
1186 struct afs_call
*call
;
1187 loff_t size
, pos
, i_size
;
1190 _enter(",%x,{%x:%u},,",
1191 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1195 size
+= (loff_t
)(last
- first
) << PAGE_SHIFT
;
1196 pos
= (loff_t
)first
<< PAGE_SHIFT
;
1199 i_size
= i_size_read(&vnode
->vfs_inode
);
1200 if (pos
+ size
> i_size
)
1201 i_size
= size
+ pos
;
1203 _debug("size %llx, at %llx, i_size %llx",
1204 (unsigned long long) size
, (unsigned long long) pos
,
1205 (unsigned long long) i_size
);
1207 if (pos
>> 32 || i_size
>> 32 || size
>> 32 || (pos
+ size
) >> 32)
1208 return afs_fs_store_data64(server
, wb
, first
, last
, offset
, to
,
1209 size
, pos
, i_size
, wait_mode
);
1211 call
= afs_alloc_flat_call(&afs_RXFSStoreData
,
1218 call
->key
= wb
->key
;
1219 call
->reply
= vnode
;
1220 call
->service_id
= FS_SERVICE
;
1221 call
->port
= htons(AFS_FS_PORT
);
1222 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1223 call
->first
= first
;
1225 call
->first_offset
= offset
;
1227 call
->send_pages
= true;
1228 call
->store_version
= vnode
->status
.data_version
+ 1;
1230 /* marshall the parameters */
1232 *bp
++ = htonl(FSSTOREDATA
);
1233 *bp
++ = htonl(vnode
->fid
.vid
);
1234 *bp
++ = htonl(vnode
->fid
.vnode
);
1235 *bp
++ = htonl(vnode
->fid
.unique
);
1237 *bp
++ = 0; /* mask */
1238 *bp
++ = 0; /* mtime */
1239 *bp
++ = 0; /* owner */
1240 *bp
++ = 0; /* group */
1241 *bp
++ = 0; /* unix mode */
1242 *bp
++ = 0; /* segment size */
1245 *bp
++ = htonl(size
);
1246 *bp
++ = htonl(i_size
);
1248 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1252 * deliver reply data to an FS.StoreStatus
1254 static int afs_deliver_fs_store_status(struct afs_call
*call
,
1255 struct sk_buff
*skb
, bool last
)
1257 afs_dataversion_t
*store_version
;
1258 struct afs_vnode
*vnode
= call
->reply
;
1262 _enter(",,%u", last
);
1264 ret
= afs_transfer_reply(call
, skb
, last
);
1268 /* unmarshall the reply once we've received all of it */
1269 store_version
= NULL
;
1270 if (call
->operation_ID
== FSSTOREDATA
)
1271 store_version
= &call
->store_version
;
1274 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, store_version
);
1275 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1277 _leave(" = 0 [done]");
1282 * FS.StoreStatus operation type
1284 static const struct afs_call_type afs_RXFSStoreStatus
= {
1285 .name
= "FS.StoreStatus",
1286 .deliver
= afs_deliver_fs_store_status
,
1287 .abort_to_error
= afs_abort_to_error
,
1288 .destructor
= afs_flat_call_destructor
,
1291 static const struct afs_call_type afs_RXFSStoreData_as_Status
= {
1292 .name
= "FS.StoreData",
1293 .deliver
= afs_deliver_fs_store_status
,
1294 .abort_to_error
= afs_abort_to_error
,
1295 .destructor
= afs_flat_call_destructor
,
1298 static const struct afs_call_type afs_RXFSStoreData64_as_Status
= {
1299 .name
= "FS.StoreData64",
1300 .deliver
= afs_deliver_fs_store_status
,
1301 .abort_to_error
= afs_abort_to_error
,
1302 .destructor
= afs_flat_call_destructor
,
1306 * set the attributes on a very large file, using FS.StoreData rather than
1307 * FS.StoreStatus so as to alter the file size also
1309 static int afs_fs_setattr_size64(struct afs_server
*server
, struct key
*key
,
1310 struct afs_vnode
*vnode
, struct iattr
*attr
,
1311 const struct afs_wait_mode
*wait_mode
)
1313 struct afs_call
*call
;
1316 _enter(",%x,{%x:%u},,",
1317 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1319 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1321 call
= afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status
,
1322 (4 + 6 + 3 * 2) * 4,
1328 call
->reply
= vnode
;
1329 call
->service_id
= FS_SERVICE
;
1330 call
->port
= htons(AFS_FS_PORT
);
1331 call
->store_version
= vnode
->status
.data_version
+ 1;
1332 call
->operation_ID
= FSSTOREDATA
;
1334 /* marshall the parameters */
1336 *bp
++ = htonl(FSSTOREDATA64
);
1337 *bp
++ = htonl(vnode
->fid
.vid
);
1338 *bp
++ = htonl(vnode
->fid
.vnode
);
1339 *bp
++ = htonl(vnode
->fid
.unique
);
1341 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1343 *bp
++ = 0; /* position of start of write */
1345 *bp
++ = 0; /* size of write */
1347 *bp
++ = htonl(attr
->ia_size
>> 32); /* new file length */
1348 *bp
++ = htonl((u32
) attr
->ia_size
);
1350 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1354 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1355 * so as to alter the file size also
1357 static int afs_fs_setattr_size(struct afs_server
*server
, struct key
*key
,
1358 struct afs_vnode
*vnode
, struct iattr
*attr
,
1359 const struct afs_wait_mode
*wait_mode
)
1361 struct afs_call
*call
;
1364 _enter(",%x,{%x:%u},,",
1365 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1367 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1368 if (attr
->ia_size
>> 32)
1369 return afs_fs_setattr_size64(server
, key
, vnode
, attr
,
1372 call
= afs_alloc_flat_call(&afs_RXFSStoreData_as_Status
,
1379 call
->reply
= vnode
;
1380 call
->service_id
= FS_SERVICE
;
1381 call
->port
= htons(AFS_FS_PORT
);
1382 call
->store_version
= vnode
->status
.data_version
+ 1;
1383 call
->operation_ID
= FSSTOREDATA
;
1385 /* marshall the parameters */
1387 *bp
++ = htonl(FSSTOREDATA
);
1388 *bp
++ = htonl(vnode
->fid
.vid
);
1389 *bp
++ = htonl(vnode
->fid
.vnode
);
1390 *bp
++ = htonl(vnode
->fid
.unique
);
1392 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1394 *bp
++ = 0; /* position of start of write */
1395 *bp
++ = 0; /* size of write */
1396 *bp
++ = htonl(attr
->ia_size
); /* new file length */
1398 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1402 * set the attributes on a file, using FS.StoreData if there's a change in file
1403 * size, and FS.StoreStatus otherwise
1405 int afs_fs_setattr(struct afs_server
*server
, struct key
*key
,
1406 struct afs_vnode
*vnode
, struct iattr
*attr
,
1407 const struct afs_wait_mode
*wait_mode
)
1409 struct afs_call
*call
;
1412 if (attr
->ia_valid
& ATTR_SIZE
)
1413 return afs_fs_setattr_size(server
, key
, vnode
, attr
,
1416 _enter(",%x,{%x:%u},,",
1417 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1419 call
= afs_alloc_flat_call(&afs_RXFSStoreStatus
,
1426 call
->reply
= vnode
;
1427 call
->service_id
= FS_SERVICE
;
1428 call
->port
= htons(AFS_FS_PORT
);
1429 call
->operation_ID
= FSSTORESTATUS
;
1431 /* marshall the parameters */
1433 *bp
++ = htonl(FSSTORESTATUS
);
1434 *bp
++ = htonl(vnode
->fid
.vid
);
1435 *bp
++ = htonl(vnode
->fid
.vnode
);
1436 *bp
++ = htonl(vnode
->fid
.unique
);
1438 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1440 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1444 * deliver reply data to an FS.GetVolumeStatus
1446 static int afs_deliver_fs_get_volume_status(struct afs_call
*call
,
1447 struct sk_buff
*skb
, bool last
)
1453 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
1455 switch (call
->unmarshall
) {
1460 /* extract the returned status record */
1462 _debug("extract status");
1463 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1469 xdr_decode_AFSFetchVolumeStatus(&bp
, call
->reply2
);
1473 /* extract the volume name length */
1475 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
1479 call
->count
= ntohl(call
->tmp
);
1480 _debug("volname length: %u", call
->count
);
1481 if (call
->count
>= AFSNAMEMAX
)
1486 /* extract the volume name */
1488 _debug("extract volname");
1489 if (call
->count
> 0) {
1490 ret
= afs_extract_data(call
, skb
, last
, call
->reply3
,
1498 _debug("volname '%s'", p
);
1503 /* extract the volume name padding */
1504 if ((call
->count
& 3) == 0) {
1506 goto no_volname_padding
;
1508 call
->count
= 4 - (call
->count
& 3);
1511 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1520 /* extract the offline message length */
1522 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
1526 call
->count
= ntohl(call
->tmp
);
1527 _debug("offline msg length: %u", call
->count
);
1528 if (call
->count
>= AFSNAMEMAX
)
1533 /* extract the offline message */
1535 _debug("extract offline");
1536 if (call
->count
> 0) {
1537 ret
= afs_extract_data(call
, skb
, last
, call
->reply3
,
1545 _debug("offline '%s'", p
);
1550 /* extract the offline message padding */
1551 if ((call
->count
& 3) == 0) {
1553 goto no_offline_padding
;
1555 call
->count
= 4 - (call
->count
& 3);
1558 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1567 /* extract the message of the day length */
1569 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
1573 call
->count
= ntohl(call
->tmp
);
1574 _debug("motd length: %u", call
->count
);
1575 if (call
->count
>= AFSNAMEMAX
)
1580 /* extract the message of the day */
1582 _debug("extract motd");
1583 if (call
->count
> 0) {
1584 ret
= afs_extract_data(call
, skb
, last
, call
->reply3
,
1592 _debug("motd '%s'", p
);
1597 /* extract the message of the day padding */
1598 if ((call
->count
& 3) == 0) {
1600 goto no_motd_padding
;
1602 call
->count
= 4 - (call
->count
& 3);
1605 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1615 ret
= afs_data_complete(call
, skb
, last
);
1621 _leave(" = 0 [done]");
1626 * destroy an FS.GetVolumeStatus call
1628 static void afs_get_volume_status_call_destructor(struct afs_call
*call
)
1630 kfree(call
->reply3
);
1631 call
->reply3
= NULL
;
1632 afs_flat_call_destructor(call
);
1636 * FS.GetVolumeStatus operation type
1638 static const struct afs_call_type afs_RXFSGetVolumeStatus
= {
1639 .name
= "FS.GetVolumeStatus",
1640 .deliver
= afs_deliver_fs_get_volume_status
,
1641 .abort_to_error
= afs_abort_to_error
,
1642 .destructor
= afs_get_volume_status_call_destructor
,
1646 * fetch the status of a volume
1648 int afs_fs_get_volume_status(struct afs_server
*server
,
1650 struct afs_vnode
*vnode
,
1651 struct afs_volume_status
*vs
,
1652 const struct afs_wait_mode
*wait_mode
)
1654 struct afs_call
*call
;
1660 tmpbuf
= kmalloc(AFSOPAQUEMAX
, GFP_KERNEL
);
1664 call
= afs_alloc_flat_call(&afs_RXFSGetVolumeStatus
, 2 * 4, 12 * 4);
1671 call
->reply
= vnode
;
1673 call
->reply3
= tmpbuf
;
1674 call
->service_id
= FS_SERVICE
;
1675 call
->port
= htons(AFS_FS_PORT
);
1677 /* marshall the parameters */
1679 bp
[0] = htonl(FSGETVOLUMESTATUS
);
1680 bp
[1] = htonl(vnode
->fid
.vid
);
1682 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1686 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1688 static int afs_deliver_fs_xxxx_lock(struct afs_call
*call
,
1689 struct sk_buff
*skb
, bool last
)
1694 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
1696 ret
= afs_transfer_reply(call
, skb
, last
);
1700 /* unmarshall the reply once we've received all of it */
1702 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1704 _leave(" = 0 [done]");
1709 * FS.SetLock operation type
1711 static const struct afs_call_type afs_RXFSSetLock
= {
1712 .name
= "FS.SetLock",
1713 .deliver
= afs_deliver_fs_xxxx_lock
,
1714 .abort_to_error
= afs_abort_to_error
,
1715 .destructor
= afs_flat_call_destructor
,
1719 * FS.ExtendLock operation type
1721 static const struct afs_call_type afs_RXFSExtendLock
= {
1722 .name
= "FS.ExtendLock",
1723 .deliver
= afs_deliver_fs_xxxx_lock
,
1724 .abort_to_error
= afs_abort_to_error
,
1725 .destructor
= afs_flat_call_destructor
,
1729 * FS.ReleaseLock operation type
1731 static const struct afs_call_type afs_RXFSReleaseLock
= {
1732 .name
= "FS.ReleaseLock",
1733 .deliver
= afs_deliver_fs_xxxx_lock
,
1734 .abort_to_error
= afs_abort_to_error
,
1735 .destructor
= afs_flat_call_destructor
,
1739 * get a lock on a file
1741 int afs_fs_set_lock(struct afs_server
*server
,
1743 struct afs_vnode
*vnode
,
1744 afs_lock_type_t type
,
1745 const struct afs_wait_mode
*wait_mode
)
1747 struct afs_call
*call
;
1752 call
= afs_alloc_flat_call(&afs_RXFSSetLock
, 5 * 4, 6 * 4);
1757 call
->reply
= vnode
;
1758 call
->service_id
= FS_SERVICE
;
1759 call
->port
= htons(AFS_FS_PORT
);
1761 /* marshall the parameters */
1763 *bp
++ = htonl(FSSETLOCK
);
1764 *bp
++ = htonl(vnode
->fid
.vid
);
1765 *bp
++ = htonl(vnode
->fid
.vnode
);
1766 *bp
++ = htonl(vnode
->fid
.unique
);
1767 *bp
++ = htonl(type
);
1769 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1773 * extend a lock on a file
1775 int afs_fs_extend_lock(struct afs_server
*server
,
1777 struct afs_vnode
*vnode
,
1778 const struct afs_wait_mode
*wait_mode
)
1780 struct afs_call
*call
;
1785 call
= afs_alloc_flat_call(&afs_RXFSExtendLock
, 4 * 4, 6 * 4);
1790 call
->reply
= vnode
;
1791 call
->service_id
= FS_SERVICE
;
1792 call
->port
= htons(AFS_FS_PORT
);
1794 /* marshall the parameters */
1796 *bp
++ = htonl(FSEXTENDLOCK
);
1797 *bp
++ = htonl(vnode
->fid
.vid
);
1798 *bp
++ = htonl(vnode
->fid
.vnode
);
1799 *bp
++ = htonl(vnode
->fid
.unique
);
1801 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1805 * release a lock on a file
1807 int afs_fs_release_lock(struct afs_server
*server
,
1809 struct afs_vnode
*vnode
,
1810 const struct afs_wait_mode
*wait_mode
)
1812 struct afs_call
*call
;
1817 call
= afs_alloc_flat_call(&afs_RXFSReleaseLock
, 4 * 4, 6 * 4);
1822 call
->reply
= vnode
;
1823 call
->service_id
= FS_SERVICE
;
1824 call
->port
= htons(AFS_FS_PORT
);
1826 /* marshall the parameters */
1828 *bp
++ = htonl(FSRELEASELOCK
);
1829 *bp
++ = htonl(vnode
->fid
.vid
);
1830 *bp
++ = htonl(vnode
->fid
.vnode
);
1831 *bp
++ = htonl(vnode
->fid
.unique
);
1833 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);