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
);