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 * We need somewhere to discard into in case the server helpfully returns more
21 * than we asked for in FS.FetchData{,64}.
23 static u8 afs_discard_buffer
[64];
26 * decode an AFSFid block
28 static void xdr_decode_AFSFid(const __be32
**_bp
, struct afs_fid
*fid
)
30 const __be32
*bp
= *_bp
;
32 fid
->vid
= ntohl(*bp
++);
33 fid
->vnode
= ntohl(*bp
++);
34 fid
->unique
= ntohl(*bp
++);
39 * decode an AFSFetchStatus block
41 static void xdr_decode_AFSFetchStatus(const __be32
**_bp
,
42 struct afs_file_status
*status
,
43 struct afs_vnode
*vnode
,
44 afs_dataversion_t
*store_version
)
46 afs_dataversion_t expected_version
;
47 const __be32
*bp
= *_bp
;
49 u64 data_version
, size
;
50 u32 changed
= 0; /* becomes non-zero if ctime-type changes seen */
54 #define EXTRACT(DST) \
56 u32 x = ntohl(*bp++); \
61 status
->if_version
= ntohl(*bp
++);
62 EXTRACT(status
->type
);
63 EXTRACT(status
->nlink
);
65 data_version
= ntohl(*bp
++);
66 EXTRACT(status
->author
);
67 owner
= make_kuid(&init_user_ns
, ntohl(*bp
++));
68 changed
|= !uid_eq(owner
, status
->owner
);
69 status
->owner
= owner
;
70 EXTRACT(status
->caller_access
); /* call ticket dependent */
71 EXTRACT(status
->anon_access
);
72 EXTRACT(status
->mode
);
73 EXTRACT(status
->parent
.vnode
);
74 EXTRACT(status
->parent
.unique
);
76 status
->mtime_client
= ntohl(*bp
++);
77 status
->mtime_server
= ntohl(*bp
++);
78 group
= make_kgid(&init_user_ns
, ntohl(*bp
++));
79 changed
|= !gid_eq(group
, status
->group
);
80 status
->group
= group
;
81 bp
++; /* sync counter */
82 data_version
|= (u64
) ntohl(*bp
++) << 32;
83 EXTRACT(status
->lock_count
);
84 size
|= (u64
) ntohl(*bp
++) << 32;
88 if (size
!= status
->size
) {
92 status
->mode
&= S_IALLUGO
;
94 _debug("vnode time %lx, %lx",
95 status
->mtime_client
, status
->mtime_server
);
98 status
->parent
.vid
= vnode
->fid
.vid
;
99 if (changed
&& !test_bit(AFS_VNODE_UNSET
, &vnode
->flags
)) {
100 _debug("vnode changed");
101 i_size_write(&vnode
->vfs_inode
, size
);
102 vnode
->vfs_inode
.i_uid
= status
->owner
;
103 vnode
->vfs_inode
.i_gid
= status
->group
;
104 vnode
->vfs_inode
.i_generation
= vnode
->fid
.unique
;
105 set_nlink(&vnode
->vfs_inode
, status
->nlink
);
107 mode
= vnode
->vfs_inode
.i_mode
;
109 mode
|= status
->mode
;
111 vnode
->vfs_inode
.i_mode
= mode
;
114 vnode
->vfs_inode
.i_ctime
.tv_sec
= status
->mtime_client
;
115 vnode
->vfs_inode
.i_mtime
= vnode
->vfs_inode
.i_ctime
;
116 vnode
->vfs_inode
.i_atime
= vnode
->vfs_inode
.i_ctime
;
117 vnode
->vfs_inode
.i_version
= data_version
;
120 expected_version
= status
->data_version
;
122 expected_version
= *store_version
;
124 if (expected_version
!= data_version
) {
125 status
->data_version
= data_version
;
126 if (vnode
&& !test_bit(AFS_VNODE_UNSET
, &vnode
->flags
)) {
127 _debug("vnode modified %llx on {%x:%u}",
128 (unsigned long long) data_version
,
129 vnode
->fid
.vid
, vnode
->fid
.vnode
);
130 set_bit(AFS_VNODE_MODIFIED
, &vnode
->flags
);
131 set_bit(AFS_VNODE_ZAP_DATA
, &vnode
->flags
);
133 } else if (store_version
) {
134 status
->data_version
= data_version
;
139 * decode an AFSCallBack block
141 static void xdr_decode_AFSCallBack(const __be32
**_bp
, struct afs_vnode
*vnode
)
143 const __be32
*bp
= *_bp
;
145 vnode
->cb_version
= ntohl(*bp
++);
146 vnode
->cb_expiry
= ntohl(*bp
++);
147 vnode
->cb_type
= ntohl(*bp
++);
148 vnode
->cb_expires
= vnode
->cb_expiry
+ ktime_get_real_seconds();
152 static void xdr_decode_AFSCallBack_raw(const __be32
**_bp
,
153 struct afs_callback
*cb
)
155 const __be32
*bp
= *_bp
;
157 cb
->version
= ntohl(*bp
++);
158 cb
->expiry
= ntohl(*bp
++);
159 cb
->type
= ntohl(*bp
++);
164 * decode an AFSVolSync block
166 static void xdr_decode_AFSVolSync(const __be32
**_bp
,
167 struct afs_volsync
*volsync
)
169 const __be32
*bp
= *_bp
;
171 volsync
->creation
= ntohl(*bp
++);
181 * encode the requested attributes into an AFSStoreStatus block
183 static void xdr_encode_AFS_StoreStatus(__be32
**_bp
, struct iattr
*attr
)
186 u32 mask
= 0, mtime
= 0, owner
= 0, group
= 0, mode
= 0;
189 if (attr
->ia_valid
& ATTR_MTIME
) {
190 mask
|= AFS_SET_MTIME
;
191 mtime
= attr
->ia_mtime
.tv_sec
;
194 if (attr
->ia_valid
& ATTR_UID
) {
195 mask
|= AFS_SET_OWNER
;
196 owner
= from_kuid(&init_user_ns
, attr
->ia_uid
);
199 if (attr
->ia_valid
& ATTR_GID
) {
200 mask
|= AFS_SET_GROUP
;
201 group
= from_kgid(&init_user_ns
, attr
->ia_gid
);
204 if (attr
->ia_valid
& ATTR_MODE
) {
205 mask
|= AFS_SET_MODE
;
206 mode
= attr
->ia_mode
& S_IALLUGO
;
210 *bp
++ = htonl(mtime
);
211 *bp
++ = htonl(owner
);
212 *bp
++ = htonl(group
);
214 *bp
++ = 0; /* segment size */
219 * decode an AFSFetchVolumeStatus block
221 static void xdr_decode_AFSFetchVolumeStatus(const __be32
**_bp
,
222 struct afs_volume_status
*vs
)
224 const __be32
*bp
= *_bp
;
226 vs
->vid
= ntohl(*bp
++);
227 vs
->parent_id
= ntohl(*bp
++);
228 vs
->online
= ntohl(*bp
++);
229 vs
->in_service
= ntohl(*bp
++);
230 vs
->blessed
= ntohl(*bp
++);
231 vs
->needs_salvage
= ntohl(*bp
++);
232 vs
->type
= ntohl(*bp
++);
233 vs
->min_quota
= ntohl(*bp
++);
234 vs
->max_quota
= ntohl(*bp
++);
235 vs
->blocks_in_use
= ntohl(*bp
++);
236 vs
->part_blocks_avail
= ntohl(*bp
++);
237 vs
->part_max_blocks
= ntohl(*bp
++);
242 * deliver reply data to an FS.FetchStatus
244 static int afs_deliver_fs_fetch_status(struct afs_call
*call
)
246 struct afs_vnode
*vnode
= call
->reply
;
252 ret
= afs_transfer_reply(call
);
256 /* unmarshall the reply once we've received all of it */
258 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
259 xdr_decode_AFSCallBack(&bp
, vnode
);
261 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
263 _leave(" = 0 [done]");
268 * FS.FetchStatus operation type
270 static const struct afs_call_type afs_RXFSFetchStatus
= {
271 .name
= "FS.FetchStatus",
272 .deliver
= afs_deliver_fs_fetch_status
,
273 .abort_to_error
= afs_abort_to_error
,
274 .destructor
= afs_flat_call_destructor
,
278 * fetch the status information for a file
280 int afs_fs_fetch_file_status(struct afs_server
*server
,
282 struct afs_vnode
*vnode
,
283 struct afs_volsync
*volsync
,
286 struct afs_call
*call
;
289 _enter(",%x,{%x:%u},,",
290 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
292 call
= afs_alloc_flat_call(&afs_RXFSFetchStatus
, 16, (21 + 3 + 6) * 4);
298 call
->reply2
= volsync
;
299 call
->service_id
= FS_SERVICE
;
300 call
->port
= htons(AFS_FS_PORT
);
302 /* marshall the parameters */
304 bp
[0] = htonl(FSFETCHSTATUS
);
305 bp
[1] = htonl(vnode
->fid
.vid
);
306 bp
[2] = htonl(vnode
->fid
.vnode
);
307 bp
[3] = htonl(vnode
->fid
.unique
);
309 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
313 * deliver reply data to an FS.FetchData
315 static int afs_deliver_fs_fetch_data(struct afs_call
*call
)
317 struct afs_vnode
*vnode
= call
->reply
;
318 struct afs_read
*req
= call
->reply3
;
324 _enter("{%u,%zu/%u;%llu/%llu}",
325 call
->unmarshall
, call
->offset
, call
->count
,
326 req
->remain
, req
->actual_len
);
328 switch (call
->unmarshall
) {
333 if (call
->operation_ID
!= FSFETCHDATA64
) {
338 /* extract the upper part of the returned data length of an
339 * FSFETCHDATA64 op (which should always be 0 using this
342 _debug("extract data length (MSW)");
343 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
347 req
->actual_len
= ntohl(call
->tmp
);
348 req
->actual_len
<<= 32;
353 /* extract the returned data length */
355 _debug("extract data length");
356 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
360 req
->actual_len
|= ntohl(call
->tmp
);
361 _debug("DATA length: %llu", req
->actual_len
);
363 req
->remain
= req
->actual_len
;
364 call
->offset
= req
->pos
& (PAGE_SIZE
- 1);
366 if (req
->actual_len
== 0)
371 ASSERTCMP(req
->index
, <, req
->nr_pages
);
372 if (req
->remain
> PAGE_SIZE
- call
->offset
)
373 size
= PAGE_SIZE
- call
->offset
;
376 call
->count
= call
->offset
+ size
;
377 ASSERTCMP(call
->count
, <=, PAGE_SIZE
);
380 /* extract the returned data */
382 _debug("extract data %llu/%llu %zu/%u",
383 req
->remain
, req
->actual_len
, call
->offset
, call
->count
);
385 buffer
= kmap(req
->pages
[req
->index
]);
386 ret
= afs_extract_data(call
, buffer
, call
->count
, true);
387 kunmap(req
->pages
[req
->index
]);
390 if (call
->offset
== PAGE_SIZE
) {
392 req
->page_done(call
, req
);
394 if (req
->remain
> 0) {
396 if (req
->index
>= req
->nr_pages
) {
397 call
->unmarshall
= 4;
405 /* Discard any excess data the server gave us */
408 size
= min_t(loff_t
, sizeof(afs_discard_buffer
), req
->remain
);
410 _debug("extract discard %llu/%llu %zu/%u",
411 req
->remain
, req
->actual_len
, call
->offset
, call
->count
);
414 ret
= afs_extract_data(call
, afs_discard_buffer
, call
->count
, true);
415 req
->remain
-= call
->offset
;
423 call
->unmarshall
= 5;
425 /* extract the metadata */
427 ret
= afs_extract_data(call
, call
->buffer
,
428 (21 + 3 + 6) * 4, false);
433 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
434 xdr_decode_AFSCallBack(&bp
, vnode
);
436 xdr_decode_AFSVolSync(&bp
, call
->reply2
);
445 for (; req
->index
< req
->nr_pages
; req
->index
++) {
446 if (call
->count
< PAGE_SIZE
)
447 zero_user_segment(req
->pages
[req
->index
],
448 call
->count
, PAGE_SIZE
);
450 req
->page_done(call
, req
);
454 _leave(" = 0 [done]");
458 static void afs_fetch_data_destructor(struct afs_call
*call
)
460 struct afs_read
*req
= call
->reply3
;
463 afs_flat_call_destructor(call
);
467 * FS.FetchData operation type
469 static const struct afs_call_type afs_RXFSFetchData
= {
470 .name
= "FS.FetchData",
471 .deliver
= afs_deliver_fs_fetch_data
,
472 .abort_to_error
= afs_abort_to_error
,
473 .destructor
= afs_fetch_data_destructor
,
476 static const struct afs_call_type afs_RXFSFetchData64
= {
477 .name
= "FS.FetchData64",
478 .deliver
= afs_deliver_fs_fetch_data
,
479 .abort_to_error
= afs_abort_to_error
,
480 .destructor
= afs_fetch_data_destructor
,
484 * fetch data from a very large file
486 static int afs_fs_fetch_data64(struct afs_server
*server
,
488 struct afs_vnode
*vnode
,
489 struct afs_read
*req
,
492 struct afs_call
*call
;
497 call
= afs_alloc_flat_call(&afs_RXFSFetchData64
, 32, (21 + 3 + 6) * 4);
503 call
->reply2
= NULL
; /* volsync */
505 call
->service_id
= FS_SERVICE
;
506 call
->port
= htons(AFS_FS_PORT
);
507 call
->operation_ID
= FSFETCHDATA64
;
509 /* marshall the parameters */
511 bp
[0] = htonl(FSFETCHDATA64
);
512 bp
[1] = htonl(vnode
->fid
.vid
);
513 bp
[2] = htonl(vnode
->fid
.vnode
);
514 bp
[3] = htonl(vnode
->fid
.unique
);
515 bp
[4] = htonl(upper_32_bits(req
->pos
));
516 bp
[5] = htonl(lower_32_bits(req
->pos
));
518 bp
[7] = htonl(lower_32_bits(req
->len
));
520 atomic_inc(&req
->usage
);
521 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
525 * fetch data from a file
527 int afs_fs_fetch_data(struct afs_server
*server
,
529 struct afs_vnode
*vnode
,
530 struct afs_read
*req
,
533 struct afs_call
*call
;
536 if (upper_32_bits(req
->pos
) ||
537 upper_32_bits(req
->len
) ||
538 upper_32_bits(req
->pos
+ req
->len
))
539 return afs_fs_fetch_data64(server
, key
, vnode
, req
, async
);
543 call
= afs_alloc_flat_call(&afs_RXFSFetchData
, 24, (21 + 3 + 6) * 4);
549 call
->reply2
= NULL
; /* volsync */
551 call
->service_id
= FS_SERVICE
;
552 call
->port
= htons(AFS_FS_PORT
);
553 call
->operation_ID
= FSFETCHDATA
;
555 /* marshall the parameters */
557 bp
[0] = htonl(FSFETCHDATA
);
558 bp
[1] = htonl(vnode
->fid
.vid
);
559 bp
[2] = htonl(vnode
->fid
.vnode
);
560 bp
[3] = htonl(vnode
->fid
.unique
);
561 bp
[4] = htonl(lower_32_bits(req
->pos
));
562 bp
[5] = htonl(lower_32_bits(req
->len
));
564 atomic_inc(&req
->usage
);
565 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
569 * deliver reply data to an FS.GiveUpCallBacks
571 static int afs_deliver_fs_give_up_callbacks(struct afs_call
*call
)
575 /* shouldn't be any reply data */
576 return afs_extract_data(call
, NULL
, 0, false);
580 * FS.GiveUpCallBacks operation type
582 static const struct afs_call_type afs_RXFSGiveUpCallBacks
= {
583 .name
= "FS.GiveUpCallBacks",
584 .deliver
= afs_deliver_fs_give_up_callbacks
,
585 .abort_to_error
= afs_abort_to_error
,
586 .destructor
= afs_flat_call_destructor
,
590 * give up a set of callbacks
591 * - the callbacks are held in the server->cb_break ring
593 int afs_fs_give_up_callbacks(struct afs_server
*server
,
596 struct afs_call
*call
;
601 ncallbacks
= CIRC_CNT(server
->cb_break_head
, server
->cb_break_tail
,
602 ARRAY_SIZE(server
->cb_break
));
604 _enter("{%zu},", ncallbacks
);
608 if (ncallbacks
> AFSCBMAX
)
609 ncallbacks
= AFSCBMAX
;
611 _debug("break %zu callbacks", ncallbacks
);
613 call
= afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks
,
614 12 + ncallbacks
* 6 * 4, 0);
618 call
->service_id
= FS_SERVICE
;
619 call
->port
= htons(AFS_FS_PORT
);
621 /* marshall the parameters */
623 tp
= bp
+ 2 + ncallbacks
* 3;
624 *bp
++ = htonl(FSGIVEUPCALLBACKS
);
625 *bp
++ = htonl(ncallbacks
);
626 *tp
++ = htonl(ncallbacks
);
628 atomic_sub(ncallbacks
, &server
->cb_break_n
);
629 for (loop
= ncallbacks
; loop
> 0; loop
--) {
630 struct afs_callback
*cb
=
631 &server
->cb_break
[server
->cb_break_tail
];
633 *bp
++ = htonl(cb
->fid
.vid
);
634 *bp
++ = htonl(cb
->fid
.vnode
);
635 *bp
++ = htonl(cb
->fid
.unique
);
636 *tp
++ = htonl(cb
->version
);
637 *tp
++ = htonl(cb
->expiry
);
638 *tp
++ = htonl(cb
->type
);
640 server
->cb_break_tail
=
641 (server
->cb_break_tail
+ 1) &
642 (ARRAY_SIZE(server
->cb_break
) - 1);
645 ASSERT(ncallbacks
> 0);
646 wake_up_nr(&server
->cb_break_waitq
, ncallbacks
);
648 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
652 * deliver reply data to an FS.CreateFile or an FS.MakeDir
654 static int afs_deliver_fs_create_vnode(struct afs_call
*call
)
656 struct afs_vnode
*vnode
= call
->reply
;
660 _enter("{%u}", call
->unmarshall
);
662 ret
= afs_transfer_reply(call
);
666 /* unmarshall the reply once we've received all of it */
668 xdr_decode_AFSFid(&bp
, call
->reply2
);
669 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
670 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
671 xdr_decode_AFSCallBack_raw(&bp
, call
->reply4
);
672 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
674 _leave(" = 0 [done]");
679 * FS.CreateFile and FS.MakeDir operation type
681 static const struct afs_call_type afs_RXFSCreateXXXX
= {
682 .name
= "FS.CreateXXXX",
683 .deliver
= afs_deliver_fs_create_vnode
,
684 .abort_to_error
= afs_abort_to_error
,
685 .destructor
= afs_flat_call_destructor
,
689 * create a file or make a directory
691 int afs_fs_create(struct afs_server
*server
,
693 struct afs_vnode
*vnode
,
696 struct afs_fid
*newfid
,
697 struct afs_file_status
*newstatus
,
698 struct afs_callback
*newcb
,
701 struct afs_call
*call
;
702 size_t namesz
, reqsz
, padsz
;
707 namesz
= strlen(name
);
708 padsz
= (4 - (namesz
& 3)) & 3;
709 reqsz
= (5 * 4) + namesz
+ padsz
+ (6 * 4);
711 call
= afs_alloc_flat_call(&afs_RXFSCreateXXXX
, reqsz
,
712 (3 + 21 + 21 + 3 + 6) * 4);
718 call
->reply2
= newfid
;
719 call
->reply3
= newstatus
;
720 call
->reply4
= newcb
;
721 call
->service_id
= FS_SERVICE
;
722 call
->port
= htons(AFS_FS_PORT
);
724 /* marshall the parameters */
726 *bp
++ = htonl(S_ISDIR(mode
) ? FSMAKEDIR
: FSCREATEFILE
);
727 *bp
++ = htonl(vnode
->fid
.vid
);
728 *bp
++ = htonl(vnode
->fid
.vnode
);
729 *bp
++ = htonl(vnode
->fid
.unique
);
730 *bp
++ = htonl(namesz
);
731 memcpy(bp
, name
, namesz
);
732 bp
= (void *) bp
+ namesz
;
734 memset(bp
, 0, padsz
);
735 bp
= (void *) bp
+ padsz
;
737 *bp
++ = htonl(AFS_SET_MODE
| AFS_SET_MTIME
);
738 *bp
++ = htonl(vnode
->vfs_inode
.i_mtime
.tv_sec
); /* mtime */
739 *bp
++ = 0; /* owner */
740 *bp
++ = 0; /* group */
741 *bp
++ = htonl(mode
& S_IALLUGO
); /* unix mode */
742 *bp
++ = 0; /* segment size */
744 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
748 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
750 static int afs_deliver_fs_remove(struct afs_call
*call
)
752 struct afs_vnode
*vnode
= call
->reply
;
756 _enter("{%u}", call
->unmarshall
);
758 ret
= afs_transfer_reply(call
);
762 /* unmarshall the reply once we've received all of it */
764 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
765 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
767 _leave(" = 0 [done]");
772 * FS.RemoveDir/FS.RemoveFile operation type
774 static const struct afs_call_type afs_RXFSRemoveXXXX
= {
775 .name
= "FS.RemoveXXXX",
776 .deliver
= afs_deliver_fs_remove
,
777 .abort_to_error
= afs_abort_to_error
,
778 .destructor
= afs_flat_call_destructor
,
782 * remove a file or directory
784 int afs_fs_remove(struct afs_server
*server
,
786 struct afs_vnode
*vnode
,
791 struct afs_call
*call
;
792 size_t namesz
, reqsz
, padsz
;
797 namesz
= strlen(name
);
798 padsz
= (4 - (namesz
& 3)) & 3;
799 reqsz
= (5 * 4) + namesz
+ padsz
;
801 call
= afs_alloc_flat_call(&afs_RXFSRemoveXXXX
, reqsz
, (21 + 6) * 4);
807 call
->service_id
= FS_SERVICE
;
808 call
->port
= htons(AFS_FS_PORT
);
810 /* marshall the parameters */
812 *bp
++ = htonl(isdir
? FSREMOVEDIR
: FSREMOVEFILE
);
813 *bp
++ = htonl(vnode
->fid
.vid
);
814 *bp
++ = htonl(vnode
->fid
.vnode
);
815 *bp
++ = htonl(vnode
->fid
.unique
);
816 *bp
++ = htonl(namesz
);
817 memcpy(bp
, name
, namesz
);
818 bp
= (void *) bp
+ namesz
;
820 memset(bp
, 0, padsz
);
821 bp
= (void *) bp
+ padsz
;
824 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
828 * deliver reply data to an FS.Link
830 static int afs_deliver_fs_link(struct afs_call
*call
)
832 struct afs_vnode
*dvnode
= call
->reply
, *vnode
= call
->reply2
;
836 _enter("{%u}", call
->unmarshall
);
838 ret
= afs_transfer_reply(call
);
842 /* unmarshall the reply once we've received all of it */
844 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
845 xdr_decode_AFSFetchStatus(&bp
, &dvnode
->status
, dvnode
, NULL
);
846 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
848 _leave(" = 0 [done]");
853 * FS.Link operation type
855 static const struct afs_call_type afs_RXFSLink
= {
857 .deliver
= afs_deliver_fs_link
,
858 .abort_to_error
= afs_abort_to_error
,
859 .destructor
= afs_flat_call_destructor
,
865 int afs_fs_link(struct afs_server
*server
,
867 struct afs_vnode
*dvnode
,
868 struct afs_vnode
*vnode
,
872 struct afs_call
*call
;
873 size_t namesz
, reqsz
, padsz
;
878 namesz
= strlen(name
);
879 padsz
= (4 - (namesz
& 3)) & 3;
880 reqsz
= (5 * 4) + namesz
+ padsz
+ (3 * 4);
882 call
= afs_alloc_flat_call(&afs_RXFSLink
, reqsz
, (21 + 21 + 6) * 4);
887 call
->reply
= dvnode
;
888 call
->reply2
= vnode
;
889 call
->service_id
= FS_SERVICE
;
890 call
->port
= htons(AFS_FS_PORT
);
892 /* marshall the parameters */
894 *bp
++ = htonl(FSLINK
);
895 *bp
++ = htonl(dvnode
->fid
.vid
);
896 *bp
++ = htonl(dvnode
->fid
.vnode
);
897 *bp
++ = htonl(dvnode
->fid
.unique
);
898 *bp
++ = htonl(namesz
);
899 memcpy(bp
, name
, namesz
);
900 bp
= (void *) bp
+ namesz
;
902 memset(bp
, 0, padsz
);
903 bp
= (void *) bp
+ padsz
;
905 *bp
++ = htonl(vnode
->fid
.vid
);
906 *bp
++ = htonl(vnode
->fid
.vnode
);
907 *bp
++ = htonl(vnode
->fid
.unique
);
909 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
913 * deliver reply data to an FS.Symlink
915 static int afs_deliver_fs_symlink(struct afs_call
*call
)
917 struct afs_vnode
*vnode
= call
->reply
;
921 _enter("{%u}", call
->unmarshall
);
923 ret
= afs_transfer_reply(call
);
927 /* unmarshall the reply once we've received all of it */
929 xdr_decode_AFSFid(&bp
, call
->reply2
);
930 xdr_decode_AFSFetchStatus(&bp
, call
->reply3
, NULL
, NULL
);
931 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, NULL
);
932 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
934 _leave(" = 0 [done]");
939 * FS.Symlink operation type
941 static const struct afs_call_type afs_RXFSSymlink
= {
942 .name
= "FS.Symlink",
943 .deliver
= afs_deliver_fs_symlink
,
944 .abort_to_error
= afs_abort_to_error
,
945 .destructor
= afs_flat_call_destructor
,
949 * create a symbolic link
951 int afs_fs_symlink(struct afs_server
*server
,
953 struct afs_vnode
*vnode
,
955 const char *contents
,
956 struct afs_fid
*newfid
,
957 struct afs_file_status
*newstatus
,
960 struct afs_call
*call
;
961 size_t namesz
, reqsz
, padsz
, c_namesz
, c_padsz
;
966 namesz
= strlen(name
);
967 padsz
= (4 - (namesz
& 3)) & 3;
969 c_namesz
= strlen(contents
);
970 c_padsz
= (4 - (c_namesz
& 3)) & 3;
972 reqsz
= (6 * 4) + namesz
+ padsz
+ c_namesz
+ c_padsz
+ (6 * 4);
974 call
= afs_alloc_flat_call(&afs_RXFSSymlink
, reqsz
,
975 (3 + 21 + 21 + 6) * 4);
981 call
->reply2
= newfid
;
982 call
->reply3
= newstatus
;
983 call
->service_id
= FS_SERVICE
;
984 call
->port
= htons(AFS_FS_PORT
);
986 /* marshall the parameters */
988 *bp
++ = htonl(FSSYMLINK
);
989 *bp
++ = htonl(vnode
->fid
.vid
);
990 *bp
++ = htonl(vnode
->fid
.vnode
);
991 *bp
++ = htonl(vnode
->fid
.unique
);
992 *bp
++ = htonl(namesz
);
993 memcpy(bp
, name
, namesz
);
994 bp
= (void *) bp
+ namesz
;
996 memset(bp
, 0, padsz
);
997 bp
= (void *) bp
+ padsz
;
999 *bp
++ = htonl(c_namesz
);
1000 memcpy(bp
, contents
, c_namesz
);
1001 bp
= (void *) bp
+ c_namesz
;
1003 memset(bp
, 0, c_padsz
);
1004 bp
= (void *) bp
+ c_padsz
;
1006 *bp
++ = htonl(AFS_SET_MODE
| AFS_SET_MTIME
);
1007 *bp
++ = htonl(vnode
->vfs_inode
.i_mtime
.tv_sec
); /* mtime */
1008 *bp
++ = 0; /* owner */
1009 *bp
++ = 0; /* group */
1010 *bp
++ = htonl(S_IRWXUGO
); /* unix mode */
1011 *bp
++ = 0; /* segment size */
1013 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1017 * deliver reply data to an FS.Rename
1019 static int afs_deliver_fs_rename(struct afs_call
*call
)
1021 struct afs_vnode
*orig_dvnode
= call
->reply
, *new_dvnode
= call
->reply2
;
1025 _enter("{%u}", call
->unmarshall
);
1027 ret
= afs_transfer_reply(call
);
1031 /* unmarshall the reply once we've received all of it */
1033 xdr_decode_AFSFetchStatus(&bp
, &orig_dvnode
->status
, orig_dvnode
, NULL
);
1034 if (new_dvnode
!= orig_dvnode
)
1035 xdr_decode_AFSFetchStatus(&bp
, &new_dvnode
->status
, new_dvnode
,
1037 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1039 _leave(" = 0 [done]");
1044 * FS.Rename operation type
1046 static const struct afs_call_type afs_RXFSRename
= {
1047 .name
= "FS.Rename",
1048 .deliver
= afs_deliver_fs_rename
,
1049 .abort_to_error
= afs_abort_to_error
,
1050 .destructor
= afs_flat_call_destructor
,
1054 * create a symbolic link
1056 int afs_fs_rename(struct afs_server
*server
,
1058 struct afs_vnode
*orig_dvnode
,
1059 const char *orig_name
,
1060 struct afs_vnode
*new_dvnode
,
1061 const char *new_name
,
1064 struct afs_call
*call
;
1065 size_t reqsz
, o_namesz
, o_padsz
, n_namesz
, n_padsz
;
1070 o_namesz
= strlen(orig_name
);
1071 o_padsz
= (4 - (o_namesz
& 3)) & 3;
1073 n_namesz
= strlen(new_name
);
1074 n_padsz
= (4 - (n_namesz
& 3)) & 3;
1077 4 + o_namesz
+ o_padsz
+
1079 4 + n_namesz
+ n_padsz
;
1081 call
= afs_alloc_flat_call(&afs_RXFSRename
, reqsz
, (21 + 21 + 6) * 4);
1086 call
->reply
= orig_dvnode
;
1087 call
->reply2
= new_dvnode
;
1088 call
->service_id
= FS_SERVICE
;
1089 call
->port
= htons(AFS_FS_PORT
);
1091 /* marshall the parameters */
1093 *bp
++ = htonl(FSRENAME
);
1094 *bp
++ = htonl(orig_dvnode
->fid
.vid
);
1095 *bp
++ = htonl(orig_dvnode
->fid
.vnode
);
1096 *bp
++ = htonl(orig_dvnode
->fid
.unique
);
1097 *bp
++ = htonl(o_namesz
);
1098 memcpy(bp
, orig_name
, o_namesz
);
1099 bp
= (void *) bp
+ o_namesz
;
1101 memset(bp
, 0, o_padsz
);
1102 bp
= (void *) bp
+ o_padsz
;
1105 *bp
++ = htonl(new_dvnode
->fid
.vid
);
1106 *bp
++ = htonl(new_dvnode
->fid
.vnode
);
1107 *bp
++ = htonl(new_dvnode
->fid
.unique
);
1108 *bp
++ = htonl(n_namesz
);
1109 memcpy(bp
, new_name
, n_namesz
);
1110 bp
= (void *) bp
+ n_namesz
;
1112 memset(bp
, 0, n_padsz
);
1113 bp
= (void *) bp
+ n_padsz
;
1116 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1120 * deliver reply data to an FS.StoreData
1122 static int afs_deliver_fs_store_data(struct afs_call
*call
)
1124 struct afs_vnode
*vnode
= call
->reply
;
1130 ret
= afs_transfer_reply(call
);
1134 /* unmarshall the reply once we've received all of it */
1136 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
,
1137 &call
->store_version
);
1138 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1140 afs_pages_written_back(vnode
, call
);
1142 _leave(" = 0 [done]");
1147 * FS.StoreData operation type
1149 static const struct afs_call_type afs_RXFSStoreData
= {
1150 .name
= "FS.StoreData",
1151 .deliver
= afs_deliver_fs_store_data
,
1152 .abort_to_error
= afs_abort_to_error
,
1153 .destructor
= afs_flat_call_destructor
,
1156 static const struct afs_call_type afs_RXFSStoreData64
= {
1157 .name
= "FS.StoreData64",
1158 .deliver
= afs_deliver_fs_store_data
,
1159 .abort_to_error
= afs_abort_to_error
,
1160 .destructor
= afs_flat_call_destructor
,
1164 * store a set of pages to a very large file
1166 static int afs_fs_store_data64(struct afs_server
*server
,
1167 struct afs_writeback
*wb
,
1168 pgoff_t first
, pgoff_t last
,
1169 unsigned offset
, unsigned to
,
1170 loff_t size
, loff_t pos
, loff_t i_size
,
1173 struct afs_vnode
*vnode
= wb
->vnode
;
1174 struct afs_call
*call
;
1177 _enter(",%x,{%x:%u},,",
1178 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1180 call
= afs_alloc_flat_call(&afs_RXFSStoreData64
,
1181 (4 + 6 + 3 * 2) * 4,
1187 call
->key
= wb
->key
;
1188 call
->reply
= vnode
;
1189 call
->service_id
= FS_SERVICE
;
1190 call
->port
= htons(AFS_FS_PORT
);
1191 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1192 call
->first
= first
;
1194 call
->first_offset
= offset
;
1196 call
->send_pages
= true;
1197 call
->store_version
= vnode
->status
.data_version
+ 1;
1199 /* marshall the parameters */
1201 *bp
++ = htonl(FSSTOREDATA64
);
1202 *bp
++ = htonl(vnode
->fid
.vid
);
1203 *bp
++ = htonl(vnode
->fid
.vnode
);
1204 *bp
++ = htonl(vnode
->fid
.unique
);
1206 *bp
++ = htonl(AFS_SET_MTIME
); /* mask */
1207 *bp
++ = htonl(vnode
->vfs_inode
.i_mtime
.tv_sec
); /* mtime */
1208 *bp
++ = 0; /* owner */
1209 *bp
++ = 0; /* group */
1210 *bp
++ = 0; /* unix mode */
1211 *bp
++ = 0; /* segment size */
1213 *bp
++ = htonl(pos
>> 32);
1214 *bp
++ = htonl((u32
) pos
);
1215 *bp
++ = htonl(size
>> 32);
1216 *bp
++ = htonl((u32
) size
);
1217 *bp
++ = htonl(i_size
>> 32);
1218 *bp
++ = htonl((u32
) i_size
);
1220 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1224 * store a set of pages
1226 int afs_fs_store_data(struct afs_server
*server
, struct afs_writeback
*wb
,
1227 pgoff_t first
, pgoff_t last
,
1228 unsigned offset
, unsigned to
,
1231 struct afs_vnode
*vnode
= wb
->vnode
;
1232 struct afs_call
*call
;
1233 loff_t size
, pos
, i_size
;
1236 _enter(",%x,{%x:%u},,",
1237 key_serial(wb
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1239 size
= (loff_t
)to
- (loff_t
)offset
;
1241 size
+= (loff_t
)(last
- first
) << PAGE_SHIFT
;
1242 pos
= (loff_t
)first
<< PAGE_SHIFT
;
1245 i_size
= i_size_read(&vnode
->vfs_inode
);
1246 if (pos
+ size
> i_size
)
1247 i_size
= size
+ pos
;
1249 _debug("size %llx, at %llx, i_size %llx",
1250 (unsigned long long) size
, (unsigned long long) pos
,
1251 (unsigned long long) i_size
);
1253 if (pos
>> 32 || i_size
>> 32 || size
>> 32 || (pos
+ size
) >> 32)
1254 return afs_fs_store_data64(server
, wb
, first
, last
, offset
, to
,
1255 size
, pos
, i_size
, async
);
1257 call
= afs_alloc_flat_call(&afs_RXFSStoreData
,
1264 call
->key
= wb
->key
;
1265 call
->reply
= vnode
;
1266 call
->service_id
= FS_SERVICE
;
1267 call
->port
= htons(AFS_FS_PORT
);
1268 call
->mapping
= vnode
->vfs_inode
.i_mapping
;
1269 call
->first
= first
;
1271 call
->first_offset
= offset
;
1273 call
->send_pages
= true;
1274 call
->store_version
= vnode
->status
.data_version
+ 1;
1276 /* marshall the parameters */
1278 *bp
++ = htonl(FSSTOREDATA
);
1279 *bp
++ = htonl(vnode
->fid
.vid
);
1280 *bp
++ = htonl(vnode
->fid
.vnode
);
1281 *bp
++ = htonl(vnode
->fid
.unique
);
1283 *bp
++ = htonl(AFS_SET_MTIME
); /* mask */
1284 *bp
++ = htonl(vnode
->vfs_inode
.i_mtime
.tv_sec
); /* mtime */
1285 *bp
++ = 0; /* owner */
1286 *bp
++ = 0; /* group */
1287 *bp
++ = 0; /* unix mode */
1288 *bp
++ = 0; /* segment size */
1291 *bp
++ = htonl(size
);
1292 *bp
++ = htonl(i_size
);
1294 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1298 * deliver reply data to an FS.StoreStatus
1300 static int afs_deliver_fs_store_status(struct afs_call
*call
)
1302 afs_dataversion_t
*store_version
;
1303 struct afs_vnode
*vnode
= call
->reply
;
1309 ret
= afs_transfer_reply(call
);
1313 /* unmarshall the reply once we've received all of it */
1314 store_version
= NULL
;
1315 if (call
->operation_ID
== FSSTOREDATA
)
1316 store_version
= &call
->store_version
;
1319 xdr_decode_AFSFetchStatus(&bp
, &vnode
->status
, vnode
, store_version
);
1320 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1322 _leave(" = 0 [done]");
1327 * FS.StoreStatus operation type
1329 static const struct afs_call_type afs_RXFSStoreStatus
= {
1330 .name
= "FS.StoreStatus",
1331 .deliver
= afs_deliver_fs_store_status
,
1332 .abort_to_error
= afs_abort_to_error
,
1333 .destructor
= afs_flat_call_destructor
,
1336 static const struct afs_call_type afs_RXFSStoreData_as_Status
= {
1337 .name
= "FS.StoreData",
1338 .deliver
= afs_deliver_fs_store_status
,
1339 .abort_to_error
= afs_abort_to_error
,
1340 .destructor
= afs_flat_call_destructor
,
1343 static const struct afs_call_type afs_RXFSStoreData64_as_Status
= {
1344 .name
= "FS.StoreData64",
1345 .deliver
= afs_deliver_fs_store_status
,
1346 .abort_to_error
= afs_abort_to_error
,
1347 .destructor
= afs_flat_call_destructor
,
1351 * set the attributes on a very large file, using FS.StoreData rather than
1352 * FS.StoreStatus so as to alter the file size also
1354 static int afs_fs_setattr_size64(struct afs_server
*server
, struct key
*key
,
1355 struct afs_vnode
*vnode
, struct iattr
*attr
,
1358 struct afs_call
*call
;
1361 _enter(",%x,{%x:%u},,",
1362 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1364 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1366 call
= afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status
,
1367 (4 + 6 + 3 * 2) * 4,
1373 call
->reply
= vnode
;
1374 call
->service_id
= FS_SERVICE
;
1375 call
->port
= htons(AFS_FS_PORT
);
1376 call
->store_version
= vnode
->status
.data_version
+ 1;
1377 call
->operation_ID
= FSSTOREDATA
;
1379 /* marshall the parameters */
1381 *bp
++ = htonl(FSSTOREDATA64
);
1382 *bp
++ = htonl(vnode
->fid
.vid
);
1383 *bp
++ = htonl(vnode
->fid
.vnode
);
1384 *bp
++ = htonl(vnode
->fid
.unique
);
1386 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1388 *bp
++ = 0; /* position of start of write */
1390 *bp
++ = 0; /* size of write */
1392 *bp
++ = htonl(attr
->ia_size
>> 32); /* new file length */
1393 *bp
++ = htonl((u32
) attr
->ia_size
);
1395 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1399 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1400 * so as to alter the file size also
1402 static int afs_fs_setattr_size(struct afs_server
*server
, struct key
*key
,
1403 struct afs_vnode
*vnode
, struct iattr
*attr
,
1406 struct afs_call
*call
;
1409 _enter(",%x,{%x:%u},,",
1410 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1412 ASSERT(attr
->ia_valid
& ATTR_SIZE
);
1413 if (attr
->ia_size
>> 32)
1414 return afs_fs_setattr_size64(server
, key
, vnode
, attr
,
1417 call
= afs_alloc_flat_call(&afs_RXFSStoreData_as_Status
,
1424 call
->reply
= vnode
;
1425 call
->service_id
= FS_SERVICE
;
1426 call
->port
= htons(AFS_FS_PORT
);
1427 call
->store_version
= vnode
->status
.data_version
+ 1;
1428 call
->operation_ID
= FSSTOREDATA
;
1430 /* marshall the parameters */
1432 *bp
++ = htonl(FSSTOREDATA
);
1433 *bp
++ = htonl(vnode
->fid
.vid
);
1434 *bp
++ = htonl(vnode
->fid
.vnode
);
1435 *bp
++ = htonl(vnode
->fid
.unique
);
1437 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1439 *bp
++ = 0; /* position of start of write */
1440 *bp
++ = 0; /* size of write */
1441 *bp
++ = htonl(attr
->ia_size
); /* new file length */
1443 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1447 * set the attributes on a file, using FS.StoreData if there's a change in file
1448 * size, and FS.StoreStatus otherwise
1450 int afs_fs_setattr(struct afs_server
*server
, struct key
*key
,
1451 struct afs_vnode
*vnode
, struct iattr
*attr
,
1454 struct afs_call
*call
;
1457 if (attr
->ia_valid
& ATTR_SIZE
)
1458 return afs_fs_setattr_size(server
, key
, vnode
, attr
,
1461 _enter(",%x,{%x:%u},,",
1462 key_serial(key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1464 call
= afs_alloc_flat_call(&afs_RXFSStoreStatus
,
1471 call
->reply
= vnode
;
1472 call
->service_id
= FS_SERVICE
;
1473 call
->port
= htons(AFS_FS_PORT
);
1474 call
->operation_ID
= FSSTORESTATUS
;
1476 /* marshall the parameters */
1478 *bp
++ = htonl(FSSTORESTATUS
);
1479 *bp
++ = htonl(vnode
->fid
.vid
);
1480 *bp
++ = htonl(vnode
->fid
.vnode
);
1481 *bp
++ = htonl(vnode
->fid
.unique
);
1483 xdr_encode_AFS_StoreStatus(&bp
, attr
);
1485 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1489 * deliver reply data to an FS.GetVolumeStatus
1491 static int afs_deliver_fs_get_volume_status(struct afs_call
*call
)
1497 _enter("{%u}", call
->unmarshall
);
1499 switch (call
->unmarshall
) {
1504 /* extract the returned status record */
1506 _debug("extract status");
1507 ret
= afs_extract_data(call
, call
->buffer
,
1513 xdr_decode_AFSFetchVolumeStatus(&bp
, call
->reply2
);
1517 /* extract the volume name length */
1519 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
1523 call
->count
= ntohl(call
->tmp
);
1524 _debug("volname length: %u", call
->count
);
1525 if (call
->count
>= AFSNAMEMAX
)
1530 /* extract the volume name */
1532 _debug("extract volname");
1533 if (call
->count
> 0) {
1534 ret
= afs_extract_data(call
, call
->reply3
,
1542 _debug("volname '%s'", p
);
1547 /* extract the volume name padding */
1548 if ((call
->count
& 3) == 0) {
1550 goto no_volname_padding
;
1552 call
->count
= 4 - (call
->count
& 3);
1555 ret
= afs_extract_data(call
, call
->buffer
,
1564 /* extract the offline message length */
1566 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
1570 call
->count
= ntohl(call
->tmp
);
1571 _debug("offline msg length: %u", call
->count
);
1572 if (call
->count
>= AFSNAMEMAX
)
1577 /* extract the offline message */
1579 _debug("extract offline");
1580 if (call
->count
> 0) {
1581 ret
= afs_extract_data(call
, call
->reply3
,
1589 _debug("offline '%s'", p
);
1594 /* extract the offline message padding */
1595 if ((call
->count
& 3) == 0) {
1597 goto no_offline_padding
;
1599 call
->count
= 4 - (call
->count
& 3);
1602 ret
= afs_extract_data(call
, call
->buffer
,
1611 /* extract the message of the day length */
1613 ret
= afs_extract_data(call
, &call
->tmp
, 4, true);
1617 call
->count
= ntohl(call
->tmp
);
1618 _debug("motd length: %u", call
->count
);
1619 if (call
->count
>= AFSNAMEMAX
)
1624 /* extract the message of the day */
1626 _debug("extract motd");
1627 if (call
->count
> 0) {
1628 ret
= afs_extract_data(call
, call
->reply3
,
1636 _debug("motd '%s'", p
);
1641 /* extract the message of the day padding */
1642 call
->count
= (4 - (call
->count
& 3)) & 3;
1645 ret
= afs_extract_data(call
, call
->buffer
,
1646 call
->count
, false);
1656 _leave(" = 0 [done]");
1661 * destroy an FS.GetVolumeStatus call
1663 static void afs_get_volume_status_call_destructor(struct afs_call
*call
)
1665 kfree(call
->reply3
);
1666 call
->reply3
= NULL
;
1667 afs_flat_call_destructor(call
);
1671 * FS.GetVolumeStatus operation type
1673 static const struct afs_call_type afs_RXFSGetVolumeStatus
= {
1674 .name
= "FS.GetVolumeStatus",
1675 .deliver
= afs_deliver_fs_get_volume_status
,
1676 .abort_to_error
= afs_abort_to_error
,
1677 .destructor
= afs_get_volume_status_call_destructor
,
1681 * fetch the status of a volume
1683 int afs_fs_get_volume_status(struct afs_server
*server
,
1685 struct afs_vnode
*vnode
,
1686 struct afs_volume_status
*vs
,
1689 struct afs_call
*call
;
1695 tmpbuf
= kmalloc(AFSOPAQUEMAX
, GFP_KERNEL
);
1699 call
= afs_alloc_flat_call(&afs_RXFSGetVolumeStatus
, 2 * 4, 12 * 4);
1706 call
->reply
= vnode
;
1708 call
->reply3
= tmpbuf
;
1709 call
->service_id
= FS_SERVICE
;
1710 call
->port
= htons(AFS_FS_PORT
);
1712 /* marshall the parameters */
1714 bp
[0] = htonl(FSGETVOLUMESTATUS
);
1715 bp
[1] = htonl(vnode
->fid
.vid
);
1717 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1721 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1723 static int afs_deliver_fs_xxxx_lock(struct afs_call
*call
)
1728 _enter("{%u}", call
->unmarshall
);
1730 ret
= afs_transfer_reply(call
);
1734 /* unmarshall the reply once we've received all of it */
1736 /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1738 _leave(" = 0 [done]");
1743 * FS.SetLock operation type
1745 static const struct afs_call_type afs_RXFSSetLock
= {
1746 .name
= "FS.SetLock",
1747 .deliver
= afs_deliver_fs_xxxx_lock
,
1748 .abort_to_error
= afs_abort_to_error
,
1749 .destructor
= afs_flat_call_destructor
,
1753 * FS.ExtendLock operation type
1755 static const struct afs_call_type afs_RXFSExtendLock
= {
1756 .name
= "FS.ExtendLock",
1757 .deliver
= afs_deliver_fs_xxxx_lock
,
1758 .abort_to_error
= afs_abort_to_error
,
1759 .destructor
= afs_flat_call_destructor
,
1763 * FS.ReleaseLock operation type
1765 static const struct afs_call_type afs_RXFSReleaseLock
= {
1766 .name
= "FS.ReleaseLock",
1767 .deliver
= afs_deliver_fs_xxxx_lock
,
1768 .abort_to_error
= afs_abort_to_error
,
1769 .destructor
= afs_flat_call_destructor
,
1773 * get a lock on a file
1775 int afs_fs_set_lock(struct afs_server
*server
,
1777 struct afs_vnode
*vnode
,
1778 afs_lock_type_t type
,
1781 struct afs_call
*call
;
1786 call
= afs_alloc_flat_call(&afs_RXFSSetLock
, 5 * 4, 6 * 4);
1791 call
->reply
= vnode
;
1792 call
->service_id
= FS_SERVICE
;
1793 call
->port
= htons(AFS_FS_PORT
);
1795 /* marshall the parameters */
1797 *bp
++ = htonl(FSSETLOCK
);
1798 *bp
++ = htonl(vnode
->fid
.vid
);
1799 *bp
++ = htonl(vnode
->fid
.vnode
);
1800 *bp
++ = htonl(vnode
->fid
.unique
);
1801 *bp
++ = htonl(type
);
1803 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1807 * extend a lock on a file
1809 int afs_fs_extend_lock(struct afs_server
*server
,
1811 struct afs_vnode
*vnode
,
1814 struct afs_call
*call
;
1819 call
= afs_alloc_flat_call(&afs_RXFSExtendLock
, 4 * 4, 6 * 4);
1824 call
->reply
= vnode
;
1825 call
->service_id
= FS_SERVICE
;
1826 call
->port
= htons(AFS_FS_PORT
);
1828 /* marshall the parameters */
1830 *bp
++ = htonl(FSEXTENDLOCK
);
1831 *bp
++ = htonl(vnode
->fid
.vid
);
1832 *bp
++ = htonl(vnode
->fid
.vnode
);
1833 *bp
++ = htonl(vnode
->fid
.unique
);
1835 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);
1839 * release a lock on a file
1841 int afs_fs_release_lock(struct afs_server
*server
,
1843 struct afs_vnode
*vnode
,
1846 struct afs_call
*call
;
1851 call
= afs_alloc_flat_call(&afs_RXFSReleaseLock
, 4 * 4, 6 * 4);
1856 call
->reply
= vnode
;
1857 call
->service_id
= FS_SERVICE
;
1858 call
->port
= htons(AFS_FS_PORT
);
1860 /* marshall the parameters */
1862 *bp
++ = htonl(FSRELEASELOCK
);
1863 *bp
++ = htonl(vnode
->fid
.vid
);
1864 *bp
++ = htonl(vnode
->fid
.vnode
);
1865 *bp
++ = htonl(vnode
->fid
.unique
);
1867 return afs_make_call(&server
->addr
, call
, GFP_NOFS
, async
);