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 */
46 #define EXTRACT(DST) \
48 u32 x = ntohl(*bp++); \
53 status
->if_version
= ntohl(*bp
++);
54 EXTRACT(status
->type
);
55 EXTRACT(status
->nlink
);
57 data_version
= ntohl(*bp
++);
58 EXTRACT(status
->author
);
59 EXTRACT(status
->owner
);
60 EXTRACT(status
->caller_access
); /* call ticket dependent */
61 EXTRACT(status
->anon_access
);
62 EXTRACT(status
->mode
);
63 EXTRACT(status
->parent
.vnode
);
64 EXTRACT(status
->parent
.unique
);
66 status
->mtime_client
= ntohl(*bp
++);
67 status
->mtime_server
= ntohl(*bp
++);
68 EXTRACT(status
->group
);
69 bp
++; /* sync counter */
70 data_version
|= (u64
) ntohl(*bp
++) << 32;
71 EXTRACT(status
->lock_count
);
72 size
|= (u64
) ntohl(*bp
++) << 32;
76 if (size
!= status
->size
) {
80 status
->mode
&= S_IALLUGO
;
82 _debug("vnode time %lx, %lx",
83 status
->mtime_client
, status
->mtime_server
);
86 status
->parent
.vid
= vnode
->fid
.vid
;
87 if (changed
&& !test_bit(AFS_VNODE_UNSET
, &vnode
->flags
)) {
88 _debug("vnode changed");
89 i_size_write(&vnode
->vfs_inode
, size
);
90 vnode
->vfs_inode
.i_uid
= status
->owner
;
91 vnode
->vfs_inode
.i_gid
= status
->group
;
92 vnode
->vfs_inode
.i_generation
= vnode
->fid
.unique
;
93 set_nlink(&vnode
->vfs_inode
, status
->nlink
);
95 mode
= vnode
->vfs_inode
.i_mode
;
99 vnode
->vfs_inode
.i_mode
= mode
;
102 vnode
->vfs_inode
.i_ctime
.tv_sec
= status
->mtime_server
;
103 vnode
->vfs_inode
.i_mtime
= vnode
->vfs_inode
.i_ctime
;
104 vnode
->vfs_inode
.i_atime
= vnode
->vfs_inode
.i_ctime
;
105 vnode
->vfs_inode
.i_version
= data_version
;
108 expected_version
= status
->data_version
;
110 expected_version
= *store_version
;
112 if (expected_version
!= data_version
) {
113 status
->data_version
= data_version
;
114 if (vnode
&& !test_bit(AFS_VNODE_UNSET
, &vnode
->flags
)) {
115 _debug("vnode modified %llx on {%x:%u}",
116 (unsigned long long) data_version
,
117 vnode
->fid
.vid
, vnode
->fid
.vnode
);
118 set_bit(AFS_VNODE_MODIFIED
, &vnode
->flags
);
119 set_bit(AFS_VNODE_ZAP_DATA
, &vnode
->flags
);
121 } else if (store_version
) {
122 status
->data_version
= data_version
;
127 * decode an AFSCallBack block
129 static void xdr_decode_AFSCallBack(const __be32
**_bp
, struct afs_vnode
*vnode
)
131 const __be32
*bp
= *_bp
;
133 vnode
->cb_version
= ntohl(*bp
++);
134 vnode
->cb_expiry
= ntohl(*bp
++);
135 vnode
->cb_type
= ntohl(*bp
++);
136 vnode
->cb_expires
= vnode
->cb_expiry
+ get_seconds();
140 static void xdr_decode_AFSCallBack_raw(const __be32
**_bp
,
141 struct afs_callback
*cb
)
143 const __be32
*bp
= *_bp
;
145 cb
->version
= ntohl(*bp
++);
146 cb
->expiry
= ntohl(*bp
++);
147 cb
->type
= ntohl(*bp
++);
152 * decode an AFSVolSync block
154 static void xdr_decode_AFSVolSync(const __be32
**_bp
,
155 struct afs_volsync
*volsync
)
157 const __be32
*bp
= *_bp
;
159 volsync
->creation
= ntohl(*bp
++);
169 * encode the requested attributes into an AFSStoreStatus block
171 static void xdr_encode_AFS_StoreStatus(__be32
**_bp
, struct iattr
*attr
)
174 u32 mask
= 0, mtime
= 0, owner
= 0, group
= 0, mode
= 0;
177 if (attr
->ia_valid
& ATTR_MTIME
) {
178 mask
|= AFS_SET_MTIME
;
179 mtime
= attr
->ia_mtime
.tv_sec
;
182 if (attr
->ia_valid
& ATTR_UID
) {
183 mask
|= AFS_SET_OWNER
;
184 owner
= attr
->ia_uid
;
187 if (attr
->ia_valid
& ATTR_GID
) {
188 mask
|= AFS_SET_GROUP
;
189 group
= attr
->ia_gid
;
192 if (attr
->ia_valid
& ATTR_MODE
) {
193 mask
|= AFS_SET_MODE
;
194 mode
= attr
->ia_mode
& S_IALLUGO
;
198 *bp
++ = htonl(mtime
);
199 *bp
++ = htonl(owner
);
200 *bp
++ = htonl(group
);
202 *bp
++ = 0; /* segment size */
207 * decode an AFSFetchVolumeStatus block
209 static void xdr_decode_AFSFetchVolumeStatus(const __be32
**_bp
,
210 struct afs_volume_status
*vs
)
212 const __be32
*bp
= *_bp
;
214 vs
->vid
= ntohl(*bp
++);
215 vs
->parent_id
= ntohl(*bp
++);
216 vs
->online
= ntohl(*bp
++);
217 vs
->in_service
= ntohl(*bp
++);
218 vs
->blessed
= ntohl(*bp
++);
219 vs
->needs_salvage
= ntohl(*bp
++);
220 vs
->type
= ntohl(*bp
++);
221 vs
->min_quota
= ntohl(*bp
++);
222 vs
->max_quota
= ntohl(*bp
++);
223 vs
->blocks_in_use
= ntohl(*bp
++);
224 vs
->part_blocks_avail
= ntohl(*bp
++);
225 vs
->part_max_blocks
= ntohl(*bp
++);
230 * deliver reply data to an FS.FetchStatus
232 static int afs_deliver_fs_fetch_status(struct afs_call
*call
,
233 struct sk_buff
*skb
, bool last
)
235 struct afs_vnode
*vnode
= call
->reply
;
238 _enter(",,%u", last
);
240 afs_transfer_reply(call
, skb
);
244 if (call
->reply_size
!= call
->reply_max
)
247 /* unmarshall the reply once we've received all of it */
249 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
250 xdr_decode_AFSCallBack(&bp
, vnode
);
252 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
254 _leave(" = 0 [done]");
259 * FS.FetchStatus operation type
261 static const struct afs_call_type afs_RXFSFetchStatus
= {
262 .name
= "FS.FetchStatus",
263 .deliver
= afs_deliver_fs_fetch_status
,
264 .abort_to_error
= afs_abort_to_error
,
265 .destructor
= afs_flat_call_destructor
,
269 * fetch the status information for a file
271 int afs_fs_fetch_file_status(struct afs_server
*server
,
273 struct afs_vnode
*vnode
,
274 struct afs_volsync
*volsync
,
275 const struct afs_wait_mode
*wait_mode
)
277 struct afs_call
*call
;
280 _enter(",%x,{%x:%u},,",
281 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
283 call
= afs_alloc_flat_call(&afs_RXFSFetchStatus
, 16, (21 + 3 + 6) * 4);
289 call
->reply2
= volsync
;
290 call
->service_id
= FS_SERVICE
;
291 call
->port
= htons(AFS_FS_PORT
);
293 /* marshall the parameters */
295 bp
[0] = htonl(FSFETCHSTATUS
);
296 bp
[1] = htonl(vnode
->fid
.vid
);
297 bp
[2] = htonl(vnode
->fid
.vnode
);
298 bp
[3] = htonl(vnode
->fid
.unique
);
300 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
304 * deliver reply data to an FS.FetchData
306 static int afs_deliver_fs_fetch_data(struct afs_call
*call
,
307 struct sk_buff
*skb
, bool last
)
309 struct afs_vnode
*vnode
= call
->reply
;
315 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
317 switch (call
->unmarshall
) {
321 if (call
->operation_ID
!= FSFETCHDATA64
) {
326 /* extract the upper part of the returned data length of an
327 * FSFETCHDATA64 op (which should always be 0 using this
330 _debug("extract data length (MSW)");
331 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
334 case -EAGAIN
: return 0;
338 call
->count
= ntohl(call
->tmp
);
339 _debug("DATA length MSW: %u", call
->count
);
346 /* extract the returned data length */
348 _debug("extract data length");
349 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
352 case -EAGAIN
: return 0;
356 call
->count
= ntohl(call
->tmp
);
357 _debug("DATA length: %u", call
->count
);
358 if (call
->count
> PAGE_SIZE
)
363 /* extract the returned data */
365 _debug("extract data");
366 if (call
->count
> 0) {
368 buffer
= kmap_atomic(page
);
369 ret
= afs_extract_data(call
, skb
, last
, buffer
,
371 kunmap_atomic(buffer
);
374 case -EAGAIN
: return 0;
382 /* extract the metadata */
384 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
388 case -EAGAIN
: return 0;
393 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
394 xdr_decode_AFSCallBack(&bp
, vnode
);
396 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
411 if (call
->count
< PAGE_SIZE
) {
414 buffer
= kmap_atomic(page
);
415 memset(buffer
+ call
->count
, 0, PAGE_SIZE
- call
->count
);
416 kunmap_atomic(buffer
);
419 _leave(" = 0 [done]");
424 * FS.FetchData operation type
426 static const struct afs_call_type afs_RXFSFetchData
= {
427 .name
= "FS.FetchData",
428 .deliver
= afs_deliver_fs_fetch_data
,
429 .abort_to_error
= afs_abort_to_error
,
430 .destructor
= afs_flat_call_destructor
,
433 static const struct afs_call_type afs_RXFSFetchData64
= {
434 .name
= "FS.FetchData64",
435 .deliver
= afs_deliver_fs_fetch_data
,
436 .abort_to_error
= afs_abort_to_error
,
437 .destructor
= afs_flat_call_destructor
,
441 * fetch data from a very large file
443 static int afs_fs_fetch_data64(struct afs_server
*server
,
445 struct afs_vnode
*vnode
,
446 off_t offset
, size_t length
,
448 const struct afs_wait_mode
*wait_mode
)
450 struct afs_call
*call
;
455 ASSERTCMP(length
, <, ULONG_MAX
);
457 call
= afs_alloc_flat_call(&afs_RXFSFetchData64
, 32, (21 + 3 + 6) * 4);
463 call
->reply2
= NULL
; /* volsync */
464 call
->reply3
= buffer
;
465 call
->service_id
= FS_SERVICE
;
466 call
->port
= htons(AFS_FS_PORT
);
467 call
->operation_ID
= FSFETCHDATA64
;
469 /* marshall the parameters */
471 bp
[0] = htonl(FSFETCHDATA64
);
472 bp
[1] = htonl(vnode
->fid
.vid
);
473 bp
[2] = htonl(vnode
->fid
.vnode
);
474 bp
[3] = htonl(vnode
->fid
.unique
);
475 bp
[4] = htonl(upper_32_bits(offset
));
476 bp
[5] = htonl((u32
) offset
);
478 bp
[7] = htonl((u32
) length
);
480 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
484 * fetch data from a file
486 int afs_fs_fetch_data(struct afs_server
*server
,
488 struct afs_vnode
*vnode
,
489 off_t offset
, size_t length
,
491 const struct afs_wait_mode
*wait_mode
)
493 struct afs_call
*call
;
496 if (upper_32_bits(offset
) || upper_32_bits(offset
+ length
))
497 return afs_fs_fetch_data64(server
, key
, vnode
, offset
, length
,
502 call
= afs_alloc_flat_call(&afs_RXFSFetchData
, 24, (21 + 3 + 6) * 4);
508 call
->reply2
= NULL
; /* volsync */
509 call
->reply3
= buffer
;
510 call
->service_id
= FS_SERVICE
;
511 call
->port
= htons(AFS_FS_PORT
);
512 call
->operation_ID
= FSFETCHDATA
;
514 /* marshall the parameters */
516 bp
[0] = htonl(FSFETCHDATA
);
517 bp
[1] = htonl(vnode
->fid
.vid
);
518 bp
[2] = htonl(vnode
->fid
.vnode
);
519 bp
[3] = htonl(vnode
->fid
.unique
);
520 bp
[4] = htonl(offset
);
521 bp
[5] = htonl(length
);
523 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
527 * deliver reply data to an FS.GiveUpCallBacks
529 static int afs_deliver_fs_give_up_callbacks(struct afs_call
*call
,
530 struct sk_buff
*skb
, bool last
)
532 _enter(",{%u},%d", skb
->len
, last
);
535 return -EBADMSG
; /* shouldn't be any reply data */
540 * FS.GiveUpCallBacks operation type
542 static const struct afs_call_type afs_RXFSGiveUpCallBacks
= {
543 .name
= "FS.GiveUpCallBacks",
544 .deliver
= afs_deliver_fs_give_up_callbacks
,
545 .abort_to_error
= afs_abort_to_error
,
546 .destructor
= afs_flat_call_destructor
,
550 * give up a set of callbacks
551 * - the callbacks are held in the server->cb_break ring
553 int afs_fs_give_up_callbacks(struct afs_server
*server
,
554 const struct afs_wait_mode
*wait_mode
)
556 struct afs_call
*call
;
561 ncallbacks
= CIRC_CNT(server
->cb_break_head
, server
->cb_break_tail
,
562 ARRAY_SIZE(server
->cb_break
));
564 _enter("{%zu},", ncallbacks
);
568 if (ncallbacks
> AFSCBMAX
)
569 ncallbacks
= AFSCBMAX
;
571 _debug("break %zu callbacks", ncallbacks
);
573 call
= afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks
,
574 12 + ncallbacks
* 6 * 4, 0);
578 call
->service_id
= FS_SERVICE
;
579 call
->port
= htons(AFS_FS_PORT
);
581 /* marshall the parameters */
583 tp
= bp
+ 2 + ncallbacks
* 3;
584 *bp
++ = htonl(FSGIVEUPCALLBACKS
);
585 *bp
++ = htonl(ncallbacks
);
586 *tp
++ = htonl(ncallbacks
);
588 atomic_sub(ncallbacks
, &server
->cb_break_n
);
589 for (loop
= ncallbacks
; loop
> 0; loop
--) {
590 struct afs_callback
*cb
=
591 &server
->cb_break
[server
->cb_break_tail
];
593 *bp
++ = htonl(cb
->fid
.vid
);
594 *bp
++ = htonl(cb
->fid
.vnode
);
595 *bp
++ = htonl(cb
->fid
.unique
);
596 *tp
++ = htonl(cb
->version
);
597 *tp
++ = htonl(cb
->expiry
);
598 *tp
++ = htonl(cb
->type
);
600 server
->cb_break_tail
=
601 (server
->cb_break_tail
+ 1) &
602 (ARRAY_SIZE(server
->cb_break
) - 1);
605 ASSERT(ncallbacks
> 0);
606 wake_up_nr(&server
->cb_break_waitq
, ncallbacks
);
608 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
612 * deliver reply data to an FS.CreateFile or an FS.MakeDir
614 static int afs_deliver_fs_create_vnode(struct afs_call
*call
,
615 struct sk_buff
*skb
, bool last
)
617 struct afs_vnode
*vnode
= call
->reply
;
620 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
622 afs_transfer_reply(call
, skb
);
626 if (call
->reply_size
!= call
->reply_max
)
629 /* unmarshall the reply once we've received all of it */
631 xdr_decode_AFSFid(&bp
, call
->reply2
);
632 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
633 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
634 xdr_decode_AFSCallBack_raw(&bp
, call
->reply4
);
635 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
637 _leave(" = 0 [done]");
642 * FS.CreateFile and FS.MakeDir operation type
644 static const struct afs_call_type afs_RXFSCreateXXXX
= {
645 .name
= "FS.CreateXXXX",
646 .deliver
= afs_deliver_fs_create_vnode
,
647 .abort_to_error
= afs_abort_to_error
,
648 .destructor
= afs_flat_call_destructor
,
652 * create a file or make a directory
654 int afs_fs_create(struct afs_server
*server
,
656 struct afs_vnode
*vnode
,
659 struct afs_fid
*newfid
,
660 struct afs_file_status
*newstatus
,
661 struct afs_callback
*newcb
,
662 const struct afs_wait_mode
*wait_mode
)
664 struct afs_call
*call
;
665 size_t namesz
, reqsz
, padsz
;
670 namesz
= strlen(name
);
671 padsz
= (4 - (namesz
& 3)) & 3;
672 reqsz
= (5 * 4) + namesz
+ padsz
+ (6 * 4);
674 call
= afs_alloc_flat_call(&afs_RXFSCreateXXXX
, reqsz
,
675 (3 + 21 + 21 + 3 + 6) * 4);
681 call
->reply2
= newfid
;
682 call
->reply3
= newstatus
;
683 call
->reply4
= newcb
;
684 call
->service_id
= FS_SERVICE
;
685 call
->port
= htons(AFS_FS_PORT
);
687 /* marshall the parameters */
689 *bp
++ = htonl(S_ISDIR(mode
) ? FSMAKEDIR
: FSCREATEFILE
);
690 *bp
++ = htonl(vnode
->fid
.vid
);
691 *bp
++ = htonl(vnode
->fid
.vnode
);
692 *bp
++ = htonl(vnode
->fid
.unique
);
693 *bp
++ = htonl(namesz
);
694 memcpy(bp
, name
, namesz
);
695 bp
= (void *) bp
+ namesz
;
697 memset(bp
, 0, padsz
);
698 bp
= (void *) bp
+ padsz
;
700 *bp
++ = htonl(AFS_SET_MODE
);
701 *bp
++ = 0; /* mtime */
702 *bp
++ = 0; /* owner */
703 *bp
++ = 0; /* group */
704 *bp
++ = htonl(mode
& S_IALLUGO
); /* unix mode */
705 *bp
++ = 0; /* segment size */
707 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
711 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
713 static int afs_deliver_fs_remove(struct afs_call
*call
,
714 struct sk_buff
*skb
, bool last
)
716 struct afs_vnode
*vnode
= call
->reply
;
719 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
721 afs_transfer_reply(call
, skb
);
725 if (call
->reply_size
!= call
->reply_max
)
728 /* unmarshall the reply once we've received all of it */
730 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
731 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
733 _leave(" = 0 [done]");
738 * FS.RemoveDir/FS.RemoveFile operation type
740 static const struct afs_call_type afs_RXFSRemoveXXXX
= {
741 .name
= "FS.RemoveXXXX",
742 .deliver
= afs_deliver_fs_remove
,
743 .abort_to_error
= afs_abort_to_error
,
744 .destructor
= afs_flat_call_destructor
,
748 * remove a file or directory
750 int afs_fs_remove(struct afs_server
*server
,
752 struct afs_vnode
*vnode
,
755 const struct afs_wait_mode
*wait_mode
)
757 struct afs_call
*call
;
758 size_t namesz
, reqsz
, padsz
;
763 namesz
= strlen(name
);
764 padsz
= (4 - (namesz
& 3)) & 3;
765 reqsz
= (5 * 4) + namesz
+ padsz
;
767 call
= afs_alloc_flat_call(&afs_RXFSRemoveXXXX
, reqsz
, (21 + 6) * 4);
773 call
->service_id
= FS_SERVICE
;
774 call
->port
= htons(AFS_FS_PORT
);
776 /* marshall the parameters */
778 *bp
++ = htonl(isdir
? FSREMOVEDIR
: FSREMOVEFILE
);
779 *bp
++ = htonl(vnode
->fid
.vid
);
780 *bp
++ = htonl(vnode
->fid
.vnode
);
781 *bp
++ = htonl(vnode
->fid
.unique
);
782 *bp
++ = htonl(namesz
);
783 memcpy(bp
, name
, namesz
);
784 bp
= (void *) bp
+ namesz
;
786 memset(bp
, 0, padsz
);
787 bp
= (void *) bp
+ padsz
;
790 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
794 * deliver reply data to an FS.Link
796 static int afs_deliver_fs_link(struct afs_call
*call
,
797 struct sk_buff
*skb
, bool last
)
799 struct afs_vnode
*dvnode
= call
->reply
, *vnode
= call
->reply2
;
802 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
804 afs_transfer_reply(call
, skb
);
808 if (call
->reply_size
!= call
->reply_max
)
811 /* unmarshall the reply once we've received all of it */
813 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
814 xdr_decode_AFSFetchStatus(&bp
, &dvnode
->status
, dvnode
, NULL
);
815 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
817 _leave(" = 0 [done]");
822 * FS.Link operation type
824 static const struct afs_call_type afs_RXFSLink
= {
826 .deliver
= afs_deliver_fs_link
,
827 .abort_to_error
= afs_abort_to_error
,
828 .destructor
= afs_flat_call_destructor
,
834 int afs_fs_link(struct afs_server
*server
,
836 struct afs_vnode
*dvnode
,
837 struct afs_vnode
*vnode
,
839 const struct afs_wait_mode
*wait_mode
)
841 struct afs_call
*call
;
842 size_t namesz
, reqsz
, padsz
;
847 namesz
= strlen(name
);
848 padsz
= (4 - (namesz
& 3)) & 3;
849 reqsz
= (5 * 4) + namesz
+ padsz
+ (3 * 4);
851 call
= afs_alloc_flat_call(&afs_RXFSLink
, reqsz
, (21 + 21 + 6) * 4);
856 call
->reply
= dvnode
;
857 call
->reply2
= vnode
;
858 call
->service_id
= FS_SERVICE
;
859 call
->port
= htons(AFS_FS_PORT
);
861 /* marshall the parameters */
863 *bp
++ = htonl(FSLINK
);
864 *bp
++ = htonl(dvnode
->fid
.vid
);
865 *bp
++ = htonl(dvnode
->fid
.vnode
);
866 *bp
++ = htonl(dvnode
->fid
.unique
);
867 *bp
++ = htonl(namesz
);
868 memcpy(bp
, name
, namesz
);
869 bp
= (void *) bp
+ namesz
;
871 memset(bp
, 0, padsz
);
872 bp
= (void *) bp
+ padsz
;
874 *bp
++ = htonl(vnode
->fid
.vid
);
875 *bp
++ = htonl(vnode
->fid
.vnode
);
876 *bp
++ = htonl(vnode
->fid
.unique
);
878 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
882 * deliver reply data to an FS.Symlink
884 static int afs_deliver_fs_symlink(struct afs_call
*call
,
885 struct sk_buff
*skb
, bool last
)
887 struct afs_vnode
*vnode
= call
->reply
;
890 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
892 afs_transfer_reply(call
, skb
);
896 if (call
->reply_size
!= call
->reply_max
)
899 /* unmarshall the reply once we've received all of it */
901 xdr_decode_AFSFid(&bp
, call
->reply2
);
902 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
903 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
904 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
906 _leave(" = 0 [done]");
911 * FS.Symlink operation type
913 static const struct afs_call_type afs_RXFSSymlink
= {
914 .name
= "FS.Symlink",
915 .deliver
= afs_deliver_fs_symlink
,
916 .abort_to_error
= afs_abort_to_error
,
917 .destructor
= afs_flat_call_destructor
,
921 * create a symbolic link
923 int afs_fs_symlink(struct afs_server
*server
,
925 struct afs_vnode
*vnode
,
927 const char *contents
,
928 struct afs_fid
*newfid
,
929 struct afs_file_status
*newstatus
,
930 const struct afs_wait_mode
*wait_mode
)
932 struct afs_call
*call
;
933 size_t namesz
, reqsz
, padsz
, c_namesz
, c_padsz
;
938 namesz
= strlen(name
);
939 padsz
= (4 - (namesz
& 3)) & 3;
941 c_namesz
= strlen(contents
);
942 c_padsz
= (4 - (c_namesz
& 3)) & 3;
944 reqsz
= (6 * 4) + namesz
+ padsz
+ c_namesz
+ c_padsz
+ (6 * 4);
946 call
= afs_alloc_flat_call(&afs_RXFSSymlink
, reqsz
,
947 (3 + 21 + 21 + 6) * 4);
953 call
->reply2
= newfid
;
954 call
->reply3
= newstatus
;
955 call
->service_id
= FS_SERVICE
;
956 call
->port
= htons(AFS_FS_PORT
);
958 /* marshall the parameters */
960 *bp
++ = htonl(FSSYMLINK
);
961 *bp
++ = htonl(vnode
->fid
.vid
);
962 *bp
++ = htonl(vnode
->fid
.vnode
);
963 *bp
++ = htonl(vnode
->fid
.unique
);
964 *bp
++ = htonl(namesz
);
965 memcpy(bp
, name
, namesz
);
966 bp
= (void *) bp
+ namesz
;
968 memset(bp
, 0, padsz
);
969 bp
= (void *) bp
+ padsz
;
971 *bp
++ = htonl(c_namesz
);
972 memcpy(bp
, contents
, c_namesz
);
973 bp
= (void *) bp
+ c_namesz
;
975 memset(bp
, 0, c_padsz
);
976 bp
= (void *) bp
+ c_padsz
;
978 *bp
++ = htonl(AFS_SET_MODE
);
979 *bp
++ = 0; /* mtime */
980 *bp
++ = 0; /* owner */
981 *bp
++ = 0; /* group */
982 *bp
++ = htonl(S_IRWXUGO
); /* unix mode */
983 *bp
++ = 0; /* segment size */
985 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
989 * deliver reply data to an FS.Rename
991 static int afs_deliver_fs_rename(struct afs_call
*call
,
992 struct sk_buff
*skb
, bool last
)
994 struct afs_vnode
*orig_dvnode
= call
->reply
, *new_dvnode
= call
->reply2
;
997 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
999 afs_transfer_reply(call
, skb
);
1003 if (call
->reply_size
!= call
->reply_max
)
1006 /* unmarshall the reply once we've received all of it */
1008 xdr_decode_AFSFetchStatus(&bp
, &orig_dvnode
->status
, orig_dvnode
, NULL
);
1009 if (new_dvnode
!= orig_dvnode
)
1010 xdr_decode_AFSFetchStatus(&bp
, &new_dvnode
->status
, new_dvnode
,
1012 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1014 _leave(" = 0 [done]");
1019 * FS.Rename operation type
1021 static const struct afs_call_type afs_RXFSRename
= {
1022 .name
= "FS.Rename",
1023 .deliver
= afs_deliver_fs_rename
,
1024 .abort_to_error
= afs_abort_to_error
,
1025 .destructor
= afs_flat_call_destructor
,
1029 * create a symbolic link
1031 int afs_fs_rename(struct afs_server
*server
,
1033 struct afs_vnode
*orig_dvnode
,
1034 const char *orig_name
,
1035 struct afs_vnode
*new_dvnode
,
1036 const char *new_name
,
1037 const struct afs_wait_mode
*wait_mode
)
1039 struct afs_call
*call
;
1040 size_t reqsz
, o_namesz
, o_padsz
, n_namesz
, n_padsz
;
1045 o_namesz
= strlen(orig_name
);
1046 o_padsz
= (4 - (o_namesz
& 3)) & 3;
1048 n_namesz
= strlen(new_name
);
1049 n_padsz
= (4 - (n_namesz
& 3)) & 3;
1052 4 + o_namesz
+ o_padsz
+
1054 4 + n_namesz
+ n_padsz
;
1056 call
= afs_alloc_flat_call(&afs_RXFSRename
, reqsz
, (21 + 21 + 6) * 4);
1061 call
->reply
= orig_dvnode
;
1062 call
->reply2
= new_dvnode
;
1063 call
->service_id
= FS_SERVICE
;
1064 call
->port
= htons(AFS_FS_PORT
);
1066 /* marshall the parameters */
1068 *bp
++ = htonl(FSRENAME
);
1069 *bp
++ = htonl(orig_dvnode
->fid
.vid
);
1070 *bp
++ = htonl(orig_dvnode
->fid
.vnode
);
1071 *bp
++ = htonl(orig_dvnode
->fid
.unique
);
1072 *bp
++ = htonl(o_namesz
);
1073 memcpy(bp
, orig_name
, o_namesz
);
1074 bp
= (void *) bp
+ o_namesz
;
1076 memset(bp
, 0, o_padsz
);
1077 bp
= (void *) bp
+ o_padsz
;
1080 *bp
++ = htonl(new_dvnode
->fid
.vid
);
1081 *bp
++ = htonl(new_dvnode
->fid
.vnode
);
1082 *bp
++ = htonl(new_dvnode
->fid
.unique
);
1083 *bp
++ = htonl(n_namesz
);
1084 memcpy(bp
, new_name
, n_namesz
);
1085 bp
= (void *) bp
+ n_namesz
;
1087 memset(bp
, 0, n_padsz
);
1088 bp
= (void *) bp
+ n_padsz
;
1091 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1095 * deliver reply data to an FS.StoreData
1097 static int afs_deliver_fs_store_data(struct afs_call
*call
,
1098 struct sk_buff
*skb
, bool last
)
1100 struct afs_vnode
*vnode
= call
->reply
;
1103 _enter(",,%u", last
);
1105 afs_transfer_reply(call
, skb
);
1107 _leave(" = 0 [more]");
1111 if (call
->reply_size
!= call
->reply_max
) {
1112 _leave(" = -EBADMSG [%u != %u]",
1113 call
->reply_size
, call
->reply_max
);
1117 /* unmarshall the reply once we've received all of it */
1119 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
,
1120 &call
->store_version
);
1121 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1123 afs_pages_written_back(vnode
, call
);
1125 _leave(" = 0 [done]");
1130 * FS.StoreData operation type
1132 static const struct afs_call_type afs_RXFSStoreData
= {
1133 .name
= "FS.StoreData",
1134 .deliver
= afs_deliver_fs_store_data
,
1135 .abort_to_error
= afs_abort_to_error
,
1136 .destructor
= afs_flat_call_destructor
,
1139 static const struct afs_call_type afs_RXFSStoreData64
= {
1140 .name
= "FS.StoreData64",
1141 .deliver
= afs_deliver_fs_store_data
,
1142 .abort_to_error
= afs_abort_to_error
,
1143 .destructor
= afs_flat_call_destructor
,
1147 * store a set of pages to a very large file
1149 static int afs_fs_store_data64(struct afs_server
*server
,
1150 struct afs_writeback
*wb
,
1151 pgoff_t first
, pgoff_t last
,
1152 unsigned offset
, unsigned to
,
1153 loff_t size
, loff_t pos
, loff_t i_size
,
1154 const struct afs_wait_mode
*wait_mode
)
1156 struct afs_vnode
*vnode
= wb
->vnode
;
1157 struct afs_call
*call
;
1160 _enter(",%x,{%x:%u},,",
1161 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1163 call
= afs_alloc_flat_call(&afs_RXFSStoreData64
,
1164 (4 + 6 + 3 * 2) * 4,
1170 call
->key
= wb
->key
;
1171 call
->reply
= vnode
;
1172 call
->service_id
= FS_SERVICE
;
1173 call
->port
= htons(AFS_FS_PORT
);
1174 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1175 call
->first
= first
;
1177 call
->first_offset
= offset
;
1179 call
->send_pages
= true;
1180 call
->store_version
= vnode
->status
.data_version
+ 1;
1182 /* marshall the parameters */
1184 *bp
++ = htonl(FSSTOREDATA64
);
1185 *bp
++ = htonl(vnode
->fid
.vid
);
1186 *bp
++ = htonl(vnode
->fid
.vnode
);
1187 *bp
++ = htonl(vnode
->fid
.unique
);
1189 *bp
++ = 0; /* mask */
1190 *bp
++ = 0; /* mtime */
1191 *bp
++ = 0; /* owner */
1192 *bp
++ = 0; /* group */
1193 *bp
++ = 0; /* unix mode */
1194 *bp
++ = 0; /* segment size */
1196 *bp
++ = htonl(pos
>> 32);
1197 *bp
++ = htonl((u32
) pos
);
1198 *bp
++ = htonl(size
>> 32);
1199 *bp
++ = htonl((u32
) size
);
1200 *bp
++ = htonl(i_size
>> 32);
1201 *bp
++ = htonl((u32
) i_size
);
1203 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1207 * store a set of pages
1209 int afs_fs_store_data(struct afs_server
*server
, struct afs_writeback
*wb
,
1210 pgoff_t first
, pgoff_t last
,
1211 unsigned offset
, unsigned to
,
1212 const struct afs_wait_mode
*wait_mode
)
1214 struct afs_vnode
*vnode
= wb
->vnode
;
1215 struct afs_call
*call
;
1216 loff_t size
, pos
, i_size
;
1219 _enter(",%x,{%x:%u},,",
1220 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1224 size
+= (loff_t
)(last
- first
) << PAGE_SHIFT
;
1225 pos
= (loff_t
)first
<< PAGE_SHIFT
;
1228 i_size
= i_size_read(&vnode
->vfs_inode
);
1229 if (pos
+ size
> i_size
)
1230 i_size
= size
+ pos
;
1232 _debug("size %llx, at %llx, i_size %llx",
1233 (unsigned long long) size
, (unsigned long long) pos
,
1234 (unsigned long long) i_size
);
1236 if (pos
>> 32 || i_size
>> 32 || size
>> 32 || (pos
+ size
) >> 32)
1237 return afs_fs_store_data64(server
, wb
, first
, last
, offset
, to
,
1238 size
, pos
, i_size
, wait_mode
);
1240 call
= afs_alloc_flat_call(&afs_RXFSStoreData
,
1247 call
->key
= wb
->key
;
1248 call
->reply
= vnode
;
1249 call
->service_id
= FS_SERVICE
;
1250 call
->port
= htons(AFS_FS_PORT
);
1251 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1252 call
->first
= first
;
1254 call
->first_offset
= offset
;
1256 call
->send_pages
= true;
1257 call
->store_version
= vnode
->status
.data_version
+ 1;
1259 /* marshall the parameters */
1261 *bp
++ = htonl(FSSTOREDATA
);
1262 *bp
++ = htonl(vnode
->fid
.vid
);
1263 *bp
++ = htonl(vnode
->fid
.vnode
);
1264 *bp
++ = htonl(vnode
->fid
.unique
);
1266 *bp
++ = 0; /* mask */
1267 *bp
++ = 0; /* mtime */
1268 *bp
++ = 0; /* owner */
1269 *bp
++ = 0; /* group */
1270 *bp
++ = 0; /* unix mode */
1271 *bp
++ = 0; /* segment size */
1274 *bp
++ = htonl(size
);
1275 *bp
++ = htonl(i_size
);
1277 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1281 * deliver reply data to an FS.StoreStatus
1283 static int afs_deliver_fs_store_status(struct afs_call
*call
,
1284 struct sk_buff
*skb
, bool last
)
1286 afs_dataversion_t
*store_version
;
1287 struct afs_vnode
*vnode
= call
->reply
;
1290 _enter(",,%u", last
);
1292 afs_transfer_reply(call
, skb
);
1294 _leave(" = 0 [more]");
1298 if (call
->reply_size
!= call
->reply_max
) {
1299 _leave(" = -EBADMSG [%u != %u]",
1300 call
->reply_size
, call
->reply_max
);
1304 /* unmarshall the reply once we've received all of it */
1305 store_version
= NULL
;
1306 if (call
->operation_ID
== FSSTOREDATA
)
1307 store_version
= &call
->store_version
;
1310 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, store_version
);
1311 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1313 _leave(" = 0 [done]");
1318 * FS.StoreStatus operation type
1320 static const struct afs_call_type afs_RXFSStoreStatus
= {
1321 .name
= "FS.StoreStatus",
1322 .deliver
= afs_deliver_fs_store_status
,
1323 .abort_to_error
= afs_abort_to_error
,
1324 .destructor
= afs_flat_call_destructor
,
1327 static const struct afs_call_type afs_RXFSStoreData_as_Status
= {
1328 .name
= "FS.StoreData",
1329 .deliver
= afs_deliver_fs_store_status
,
1330 .abort_to_error
= afs_abort_to_error
,
1331 .destructor
= afs_flat_call_destructor
,
1334 static const struct afs_call_type afs_RXFSStoreData64_as_Status
= {
1335 .name
= "FS.StoreData64",
1336 .deliver
= afs_deliver_fs_store_status
,
1337 .abort_to_error
= afs_abort_to_error
,
1338 .destructor
= afs_flat_call_destructor
,
1342 * set the attributes on a very large file, using FS.StoreData rather than
1343 * FS.StoreStatus so as to alter the file size also
1345 static int afs_fs_setattr_size64(struct afs_server
*server
, struct key
*key
,
1346 struct afs_vnode
*vnode
, struct iattr
*attr
,
1347 const struct afs_wait_mode
*wait_mode
)
1349 struct afs_call
*call
;
1352 _enter(",%x,{%x:%u},,",
1353 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1355 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1357 call
= afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status
,
1358 (4 + 6 + 3 * 2) * 4,
1364 call
->reply
= vnode
;
1365 call
->service_id
= FS_SERVICE
;
1366 call
->port
= htons(AFS_FS_PORT
);
1367 call
->store_version
= vnode
->status
.data_version
+ 1;
1368 call
->operation_ID
= FSSTOREDATA
;
1370 /* marshall the parameters */
1372 *bp
++ = htonl(FSSTOREDATA64
);
1373 *bp
++ = htonl(vnode
->fid
.vid
);
1374 *bp
++ = htonl(vnode
->fid
.vnode
);
1375 *bp
++ = htonl(vnode
->fid
.unique
);
1377 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1379 *bp
++ = 0; /* position of start of write */
1381 *bp
++ = 0; /* size of write */
1383 *bp
++ = htonl(attr
->ia_size
>> 32); /* new file length */
1384 *bp
++ = htonl((u32
) attr
->ia_size
);
1386 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1390 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1391 * so as to alter the file size also
1393 static int afs_fs_setattr_size(struct afs_server
*server
, struct key
*key
,
1394 struct afs_vnode
*vnode
, struct iattr
*attr
,
1395 const struct afs_wait_mode
*wait_mode
)
1397 struct afs_call
*call
;
1400 _enter(",%x,{%x:%u},,",
1401 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1403 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1404 if (attr
->ia_size
>> 32)
1405 return afs_fs_setattr_size64(server
, key
, vnode
, attr
,
1408 call
= afs_alloc_flat_call(&afs_RXFSStoreData_as_Status
,
1415 call
->reply
= vnode
;
1416 call
->service_id
= FS_SERVICE
;
1417 call
->port
= htons(AFS_FS_PORT
);
1418 call
->store_version
= vnode
->status
.data_version
+ 1;
1419 call
->operation_ID
= FSSTOREDATA
;
1421 /* marshall the parameters */
1423 *bp
++ = htonl(FSSTOREDATA
);
1424 *bp
++ = htonl(vnode
->fid
.vid
);
1425 *bp
++ = htonl(vnode
->fid
.vnode
);
1426 *bp
++ = htonl(vnode
->fid
.unique
);
1428 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1430 *bp
++ = 0; /* position of start of write */
1431 *bp
++ = 0; /* size of write */
1432 *bp
++ = htonl(attr
->ia_size
); /* new file length */
1434 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1438 * set the attributes on a file, using FS.StoreData if there's a change in file
1439 * size, and FS.StoreStatus otherwise
1441 int afs_fs_setattr(struct afs_server
*server
, struct key
*key
,
1442 struct afs_vnode
*vnode
, struct iattr
*attr
,
1443 const struct afs_wait_mode
*wait_mode
)
1445 struct afs_call
*call
;
1448 if (attr
->ia_valid
& ATTR_SIZE
)
1449 return afs_fs_setattr_size(server
, key
, vnode
, attr
,
1452 _enter(",%x,{%x:%u},,",
1453 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1455 call
= afs_alloc_flat_call(&afs_RXFSStoreStatus
,
1462 call
->reply
= vnode
;
1463 call
->service_id
= FS_SERVICE
;
1464 call
->port
= htons(AFS_FS_PORT
);
1465 call
->operation_ID
= FSSTORESTATUS
;
1467 /* marshall the parameters */
1469 *bp
++ = htonl(FSSTORESTATUS
);
1470 *bp
++ = htonl(vnode
->fid
.vid
);
1471 *bp
++ = htonl(vnode
->fid
.vnode
);
1472 *bp
++ = htonl(vnode
->fid
.unique
);
1474 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1476 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1480 * deliver reply data to an FS.GetVolumeStatus
1482 static int afs_deliver_fs_get_volume_status(struct afs_call
*call
,
1483 struct sk_buff
*skb
, bool last
)
1489 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
1491 switch (call
->unmarshall
) {
1496 /* extract the returned status record */
1498 _debug("extract status");
1499 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1503 case -EAGAIN
: return 0;
1504 default: return ret
;
1508 xdr_decode_AFSFetchVolumeStatus(&bp
, call
->reply2
);
1512 /* extract the volume name length */
1514 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
1517 case -EAGAIN
: return 0;
1518 default: return ret
;
1521 call
->count
= ntohl(call
->tmp
);
1522 _debug("volname length: %u", call
->count
);
1523 if (call
->count
>= AFSNAMEMAX
)
1528 /* extract the volume name */
1530 _debug("extract volname");
1531 if (call
->count
> 0) {
1532 ret
= afs_extract_data(call
, skb
, last
, call
->reply3
,
1536 case -EAGAIN
: return 0;
1537 default: return ret
;
1543 _debug("volname '%s'", p
);
1548 /* extract the volume name padding */
1549 if ((call
->count
& 3) == 0) {
1551 goto no_volname_padding
;
1553 call
->count
= 4 - (call
->count
& 3);
1556 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1560 case -EAGAIN
: return 0;
1561 default: return ret
;
1568 /* extract the offline message length */
1570 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
1573 case -EAGAIN
: return 0;
1574 default: return ret
;
1577 call
->count
= ntohl(call
->tmp
);
1578 _debug("offline msg length: %u", call
->count
);
1579 if (call
->count
>= AFSNAMEMAX
)
1584 /* extract the offline message */
1586 _debug("extract offline");
1587 if (call
->count
> 0) {
1588 ret
= afs_extract_data(call
, skb
, last
, call
->reply3
,
1592 case -EAGAIN
: return 0;
1593 default: return ret
;
1599 _debug("offline '%s'", p
);
1604 /* extract the offline message padding */
1605 if ((call
->count
& 3) == 0) {
1607 goto no_offline_padding
;
1609 call
->count
= 4 - (call
->count
& 3);
1612 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1616 case -EAGAIN
: return 0;
1617 default: return ret
;
1624 /* extract the message of the day length */
1626 ret
= afs_extract_data(call
, skb
, last
, &call
->tmp
, 4);
1629 case -EAGAIN
: return 0;
1630 default: return ret
;
1633 call
->count
= ntohl(call
->tmp
);
1634 _debug("motd length: %u", call
->count
);
1635 if (call
->count
>= AFSNAMEMAX
)
1640 /* extract the message of the day */
1642 _debug("extract motd");
1643 if (call
->count
> 0) {
1644 ret
= afs_extract_data(call
, skb
, last
, call
->reply3
,
1648 case -EAGAIN
: return 0;
1649 default: return ret
;
1655 _debug("motd '%s'", p
);
1660 /* extract the message of the day padding */
1661 if ((call
->count
& 3) == 0) {
1663 goto no_motd_padding
;
1665 call
->count
= 4 - (call
->count
& 3);
1668 ret
= afs_extract_data(call
, skb
, last
, call
->buffer
,
1672 case -EAGAIN
: return 0;
1673 default: return ret
;
1681 _debug("trailer %d", skb
->len
);
1690 _leave(" = 0 [done]");
1695 * destroy an FS.GetVolumeStatus call
1697 static void afs_get_volume_status_call_destructor(struct afs_call
*call
)
1699 kfree(call
->reply3
);
1700 call
->reply3
= NULL
;
1701 afs_flat_call_destructor(call
);
1705 * FS.GetVolumeStatus operation type
1707 static const struct afs_call_type afs_RXFSGetVolumeStatus
= {
1708 .name
= "FS.GetVolumeStatus",
1709 .deliver
= afs_deliver_fs_get_volume_status
,
1710 .abort_to_error
= afs_abort_to_error
,
1711 .destructor
= afs_get_volume_status_call_destructor
,
1715 * fetch the status of a volume
1717 int afs_fs_get_volume_status(struct afs_server
*server
,
1719 struct afs_vnode
*vnode
,
1720 struct afs_volume_status
*vs
,
1721 const struct afs_wait_mode
*wait_mode
)
1723 struct afs_call
*call
;
1729 tmpbuf
= kmalloc(AFSOPAQUEMAX
, GFP_KERNEL
);
1733 call
= afs_alloc_flat_call(&afs_RXFSGetVolumeStatus
, 2 * 4, 12 * 4);
1740 call
->reply
= vnode
;
1742 call
->reply3
= tmpbuf
;
1743 call
->service_id
= FS_SERVICE
;
1744 call
->port
= htons(AFS_FS_PORT
);
1746 /* marshall the parameters */
1748 bp
[0] = htonl(FSGETVOLUMESTATUS
);
1749 bp
[1] = htonl(vnode
->fid
.vid
);
1751 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1755 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1757 static int afs_deliver_fs_xxxx_lock(struct afs_call
*call
,
1758 struct sk_buff
*skb
, bool last
)
1762 _enter("{%u},{%u},%d", call
->unmarshall
, skb
->len
, last
);
1764 afs_transfer_reply(call
, skb
);
1768 if (call
->reply_size
!= call
->reply_max
)
1771 /* unmarshall the reply once we've received all of it */
1773 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1775 _leave(" = 0 [done]");
1780 * FS.SetLock operation type
1782 static const struct afs_call_type afs_RXFSSetLock
= {
1783 .name
= "FS.SetLock",
1784 .deliver
= afs_deliver_fs_xxxx_lock
,
1785 .abort_to_error
= afs_abort_to_error
,
1786 .destructor
= afs_flat_call_destructor
,
1790 * FS.ExtendLock operation type
1792 static const struct afs_call_type afs_RXFSExtendLock
= {
1793 .name
= "FS.ExtendLock",
1794 .deliver
= afs_deliver_fs_xxxx_lock
,
1795 .abort_to_error
= afs_abort_to_error
,
1796 .destructor
= afs_flat_call_destructor
,
1800 * FS.ReleaseLock operation type
1802 static const struct afs_call_type afs_RXFSReleaseLock
= {
1803 .name
= "FS.ReleaseLock",
1804 .deliver
= afs_deliver_fs_xxxx_lock
,
1805 .abort_to_error
= afs_abort_to_error
,
1806 .destructor
= afs_flat_call_destructor
,
1810 * get a lock on a file
1812 int afs_fs_set_lock(struct afs_server
*server
,
1814 struct afs_vnode
*vnode
,
1815 afs_lock_type_t type
,
1816 const struct afs_wait_mode
*wait_mode
)
1818 struct afs_call
*call
;
1823 call
= afs_alloc_flat_call(&afs_RXFSSetLock
, 5 * 4, 6 * 4);
1828 call
->reply
= vnode
;
1829 call
->service_id
= FS_SERVICE
;
1830 call
->port
= htons(AFS_FS_PORT
);
1832 /* marshall the parameters */
1834 *bp
++ = htonl(FSSETLOCK
);
1835 *bp
++ = htonl(vnode
->fid
.vid
);
1836 *bp
++ = htonl(vnode
->fid
.vnode
);
1837 *bp
++ = htonl(vnode
->fid
.unique
);
1838 *bp
++ = htonl(type
);
1840 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1844 * extend a lock on a file
1846 int afs_fs_extend_lock(struct afs_server
*server
,
1848 struct afs_vnode
*vnode
,
1849 const struct afs_wait_mode
*wait_mode
)
1851 struct afs_call
*call
;
1856 call
= afs_alloc_flat_call(&afs_RXFSExtendLock
, 4 * 4, 6 * 4);
1861 call
->reply
= vnode
;
1862 call
->service_id
= FS_SERVICE
;
1863 call
->port
= htons(AFS_FS_PORT
);
1865 /* marshall the parameters */
1867 *bp
++ = htonl(FSEXTENDLOCK
);
1868 *bp
++ = htonl(vnode
->fid
.vid
);
1869 *bp
++ = htonl(vnode
->fid
.vnode
);
1870 *bp
++ = htonl(vnode
->fid
.unique
);
1872 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);
1876 * release a lock on a file
1878 int afs_fs_release_lock(struct afs_server
*server
,
1880 struct afs_vnode
*vnode
,
1881 const struct afs_wait_mode
*wait_mode
)
1883 struct afs_call
*call
;
1888 call
= afs_alloc_flat_call(&afs_RXFSReleaseLock
, 4 * 4, 6 * 4);
1893 call
->reply
= vnode
;
1894 call
->service_id
= FS_SERVICE
;
1895 call
->port
= htons(AFS_FS_PORT
);
1897 /* marshall the parameters */
1899 *bp
++ = htonl(FSRELEASELOCK
);
1900 *bp
++ = htonl(vnode
->fid
.vid
);
1901 *bp
++ = htonl(vnode
->fid
.vnode
);
1902 *bp
++ = htonl(vnode
->fid
.unique
);
1904 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, wait_mode
);