1 /* YFS File Server client stubs
3 * Copyright (C) 2018 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 Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, 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>
16 #include <linux/iversion.h>
20 #include "protocol_yfs.h"
22 static const struct afs_fid afs_zero_fid
;
24 static inline void afs_use_fs_server(struct afs_call
*call
, struct afs_cb_interest
*cbi
)
26 call
->cbi
= afs_get_cb_interest(cbi
);
29 #define xdr_size(x) (sizeof(*x) / sizeof(__be32))
31 static void xdr_decode_YFSFid(const __be32
**_bp
, struct afs_fid
*fid
)
33 const struct yfs_xdr_YFSFid
*x
= (const void *)*_bp
;
35 fid
->vid
= xdr_to_u64(x
->volume
);
36 fid
->vnode
= xdr_to_u64(x
->vnode
.lo
);
37 fid
->vnode_hi
= ntohl(x
->vnode
.hi
);
38 fid
->unique
= ntohl(x
->vnode
.unique
);
42 static __be32
*xdr_encode_u32(__be32
*bp
, u32 n
)
48 static __be32
*xdr_encode_u64(__be32
*bp
, u64 n
)
50 struct yfs_xdr_u64
*x
= (void *)bp
;
53 return bp
+ xdr_size(x
);
56 static __be32
*xdr_encode_YFSFid(__be32
*bp
, struct afs_fid
*fid
)
58 struct yfs_xdr_YFSFid
*x
= (void *)bp
;
60 x
->volume
= u64_to_xdr(fid
->vid
);
61 x
->vnode
.lo
= u64_to_xdr(fid
->vnode
);
62 x
->vnode
.hi
= htonl(fid
->vnode_hi
);
63 x
->vnode
.unique
= htonl(fid
->unique
);
64 return bp
+ xdr_size(x
);
67 static size_t xdr_strlen(unsigned int len
)
69 return sizeof(__be32
) + round_up(len
, sizeof(__be32
));
72 static __be32
*xdr_encode_string(__be32
*bp
, const char *p
, unsigned int len
)
74 bp
= xdr_encode_u32(bp
, len
);
75 bp
= memcpy(bp
, p
, len
);
77 unsigned int pad
= 4 - (len
& 3);
79 memset((u8
*)bp
+ len
, 0, pad
);
83 return bp
+ len
/ sizeof(__be32
);
86 static s64
linux_to_yfs_time(const struct timespec64
*t
)
88 /* Convert to 100ns intervals. */
89 return (u64
)t
->tv_sec
* 10000000 + t
->tv_nsec
/100;
92 static __be32
*xdr_encode_YFSStoreStatus_mode(__be32
*bp
, mode_t mode
)
94 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
96 x
->mask
= htonl(AFS_SET_MODE
);
97 x
->mode
= htonl(mode
& S_IALLUGO
);
98 x
->mtime_client
= u64_to_xdr(0);
99 x
->owner
= u64_to_xdr(0);
100 x
->group
= u64_to_xdr(0);
101 return bp
+ xdr_size(x
);
104 static __be32
*xdr_encode_YFSStoreStatus_mtime(__be32
*bp
, const struct timespec64
*t
)
106 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
107 s64 mtime
= linux_to_yfs_time(t
);
109 x
->mask
= htonl(AFS_SET_MTIME
);
111 x
->mtime_client
= u64_to_xdr(mtime
);
112 x
->owner
= u64_to_xdr(0);
113 x
->group
= u64_to_xdr(0);
114 return bp
+ xdr_size(x
);
118 * Convert a signed 100ns-resolution 64-bit time into a timespec.
120 static struct timespec64
yfs_time_to_linux(s64 t
)
122 struct timespec64 ts
;
126 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
127 * the alternative, do_div, does not work with negative numbers so have
128 * to special case them
132 ts
.tv_nsec
= (time64_t
)(do_div(abs_t
, 10000000) * 100);
133 ts
.tv_nsec
= -ts
.tv_nsec
;
137 ts
.tv_nsec
= (time64_t
)do_div(abs_t
, 10000000) * 100;
144 static struct timespec64
xdr_to_time(const struct yfs_xdr_u64 xdr
)
146 s64 t
= xdr_to_u64(xdr
);
148 return yfs_time_to_linux(t
);
151 static void yfs_check_req(struct afs_call
*call
, __be32
*bp
)
153 size_t len
= (void *)bp
- call
->request
;
155 if (len
> call
->request_size
)
156 pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
157 call
->type
->name
, len
, call
->request_size
);
158 else if (len
< call
->request_size
)
159 pr_warning("kAFS: %s: Request buffer underflow (%zu<%u)\n",
160 call
->type
->name
, len
, call
->request_size
);
164 * Dump a bad file status record.
166 static void xdr_dump_bad(const __be32
*bp
)
171 pr_notice("YFS XDR: Bad status record\n");
172 for (i
= 0; i
< 5 * 4 * 4; i
+= 16) {
175 pr_notice("%03x: %08x %08x %08x %08x\n",
176 i
, ntohl(x
[0]), ntohl(x
[1]), ntohl(x
[2]), ntohl(x
[3]));
180 pr_notice("0x50: %08x\n", ntohl(x
[0]));
184 * Decode a YFSFetchStatus block
186 static int xdr_decode_YFSFetchStatus(struct afs_call
*call
,
188 struct afs_file_status
*status
,
189 struct afs_vnode
*vnode
,
190 const afs_dataversion_t
*expected_version
,
191 struct afs_read
*read_req
)
193 const struct yfs_xdr_YFSFetchStatus
*xdr
= (const void *)*_bp
;
197 status
->abort_code
= ntohl(xdr
->abort_code
);
198 if (status
->abort_code
!= 0) {
199 if (vnode
&& status
->abort_code
== VNOVNODE
) {
200 set_bit(AFS_VNODE_DELETED
, &vnode
->flags
);
202 __afs_break_callback(vnode
);
207 type
= ntohl(xdr
->type
);
211 case AFS_FTYPE_SYMLINK
:
212 if (type
!= status
->type
&&
214 !test_bit(AFS_VNODE_UNSET
, &vnode
->flags
)) {
215 pr_warning("Vnode %llx:%llx:%x changed type %u to %u\n",
228 #define EXTRACT_M4(FIELD) \
230 u32 x = ntohl(xdr->FIELD); \
231 if (status->FIELD != x) { \
232 flags |= AFS_VNODE_META_CHANGED; \
237 #define EXTRACT_M8(FIELD) \
239 u64 x = xdr_to_u64(xdr->FIELD); \
240 if (status->FIELD != x) { \
241 flags |= AFS_VNODE_META_CHANGED; \
246 #define EXTRACT_D8(FIELD) \
248 u64 x = xdr_to_u64(xdr->FIELD); \
249 if (status->FIELD != x) { \
250 flags |= AFS_VNODE_DATA_CHANGED; \
257 EXTRACT_D8(data_version
);
262 EXTRACT_M4(caller_access
); /* call ticket dependent */
263 EXTRACT_M4(anon_access
);
265 status
->mtime_client
= xdr_to_time(xdr
->mtime_client
);
266 status
->mtime_server
= xdr_to_time(xdr
->mtime_server
);
267 status
->lock_count
= ntohl(xdr
->lock_count
);
270 read_req
->data_version
= status
->data_version
;
271 read_req
->file_size
= status
->size
;
274 *_bp
+= xdr_size(xdr
);
277 if (test_bit(AFS_VNODE_UNSET
, &vnode
->flags
))
278 flags
|= AFS_VNODE_NOT_YET_SET
;
279 afs_update_inode_from_status(vnode
, status
, expected_version
,
287 return afs_protocol_error(call
, -EBADMSG
, afs_eproto_bad_status
);
291 * Decode the file status. We need to lock the target vnode if we're going to
292 * update its status so that stat() sees the attributes update atomically.
294 static int yfs_decode_status(struct afs_call
*call
,
296 struct afs_file_status
*status
,
297 struct afs_vnode
*vnode
,
298 const afs_dataversion_t
*expected_version
,
299 struct afs_read
*read_req
)
304 return xdr_decode_YFSFetchStatus(call
, _bp
, status
, vnode
,
305 expected_version
, read_req
);
307 write_seqlock(&vnode
->cb_lock
);
308 ret
= xdr_decode_YFSFetchStatus(call
, _bp
, status
, vnode
,
309 expected_version
, read_req
);
310 write_sequnlock(&vnode
->cb_lock
);
315 * Decode a YFSCallBack block
317 static void xdr_decode_YFSCallBack(struct afs_call
*call
,
318 struct afs_vnode
*vnode
,
321 struct yfs_xdr_YFSCallBack
*xdr
= (void *)*_bp
;
322 struct afs_cb_interest
*old
, *cbi
= call
->cbi
;
325 write_seqlock(&vnode
->cb_lock
);
327 if (!afs_cb_is_broken(call
->cb_break
, vnode
, cbi
)) {
328 cb_expiry
= xdr_to_u64(xdr
->expiration_time
);
329 do_div(cb_expiry
, 10 * 1000 * 1000);
330 vnode
->cb_version
= ntohl(xdr
->version
);
331 vnode
->cb_type
= ntohl(xdr
->type
);
332 vnode
->cb_expires_at
= cb_expiry
+ ktime_get_real_seconds();
333 old
= vnode
->cb_interest
;
334 if (old
!= call
->cbi
) {
335 vnode
->cb_interest
= cbi
;
338 set_bit(AFS_VNODE_CB_PROMISED
, &vnode
->flags
);
341 write_sequnlock(&vnode
->cb_lock
);
343 *_bp
+= xdr_size(xdr
);
346 static void xdr_decode_YFSCallBack_raw(const __be32
**_bp
,
347 struct afs_callback
*cb
)
349 struct yfs_xdr_YFSCallBack
*x
= (void *)*_bp
;
352 cb_expiry
= xdr_to_u64(x
->expiration_time
);
353 do_div(cb_expiry
, 10 * 1000 * 1000);
354 cb
->version
= ntohl(x
->version
);
355 cb
->type
= ntohl(x
->type
);
356 cb
->expires_at
= cb_expiry
+ ktime_get_real_seconds();
362 * Decode a YFSVolSync block
364 static void xdr_decode_YFSVolSync(const __be32
**_bp
,
365 struct afs_volsync
*volsync
)
367 struct yfs_xdr_YFSVolSync
*x
= (void *)*_bp
;
371 creation
= xdr_to_u64(x
->vol_creation_date
);
372 do_div(creation
, 10 * 1000 * 1000);
373 volsync
->creation
= creation
;
380 * Encode the requested attributes into a YFSStoreStatus block
382 static __be32
*xdr_encode_YFS_StoreStatus(__be32
*bp
, struct iattr
*attr
)
384 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
385 s64 mtime
= 0, owner
= 0, group
= 0;
386 u32 mask
= 0, mode
= 0;
389 if (attr
->ia_valid
& ATTR_MTIME
) {
390 mask
|= AFS_SET_MTIME
;
391 mtime
= linux_to_yfs_time(&attr
->ia_mtime
);
394 if (attr
->ia_valid
& ATTR_UID
) {
395 mask
|= AFS_SET_OWNER
;
396 owner
= from_kuid(&init_user_ns
, attr
->ia_uid
);
399 if (attr
->ia_valid
& ATTR_GID
) {
400 mask
|= AFS_SET_GROUP
;
401 group
= from_kgid(&init_user_ns
, attr
->ia_gid
);
404 if (attr
->ia_valid
& ATTR_MODE
) {
405 mask
|= AFS_SET_MODE
;
406 mode
= attr
->ia_mode
& S_IALLUGO
;
409 x
->mask
= htonl(mask
);
410 x
->mode
= htonl(mode
);
411 x
->mtime_client
= u64_to_xdr(mtime
);
412 x
->owner
= u64_to_xdr(owner
);
413 x
->group
= u64_to_xdr(group
);
414 return bp
+ xdr_size(x
);
418 * Decode a YFSFetchVolumeStatus block.
420 static void xdr_decode_YFSFetchVolumeStatus(const __be32
**_bp
,
421 struct afs_volume_status
*vs
)
423 const struct yfs_xdr_YFSFetchVolumeStatus
*x
= (const void *)*_bp
;
426 vs
->vid
= xdr_to_u64(x
->vid
);
427 vs
->parent_id
= xdr_to_u64(x
->parent_id
);
428 flags
= ntohl(x
->flags
);
429 vs
->online
= flags
& yfs_FVSOnline
;
430 vs
->in_service
= flags
& yfs_FVSInservice
;
431 vs
->blessed
= flags
& yfs_FVSBlessed
;
432 vs
->needs_salvage
= flags
& yfs_FVSNeedsSalvage
;
433 vs
->type
= ntohl(x
->type
);
435 vs
->max_quota
= xdr_to_u64(x
->max_quota
);
436 vs
->blocks_in_use
= xdr_to_u64(x
->blocks_in_use
);
437 vs
->part_blocks_avail
= xdr_to_u64(x
->part_blocks_avail
);
438 vs
->part_max_blocks
= xdr_to_u64(x
->part_max_blocks
);
439 vs
->vol_copy_date
= xdr_to_u64(x
->vol_copy_date
);
440 vs
->vol_backup_date
= xdr_to_u64(x
->vol_backup_date
);
441 *_bp
+= sizeof(*x
) / sizeof(__be32
);
445 * deliver reply data to an FS.FetchStatus
447 static int yfs_deliver_fs_fetch_status_vnode(struct afs_call
*call
)
449 struct afs_vnode
*vnode
= call
->reply
[0];
453 ret
= afs_transfer_reply(call
);
457 _enter("{%llx:%llu}", vnode
->fid
.vid
, vnode
->fid
.vnode
);
459 /* unmarshall the reply once we've received all of it */
461 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
,
462 &call
->expected_version
, NULL
);
465 xdr_decode_YFSCallBack(call
, vnode
, &bp
);
466 xdr_decode_YFSVolSync(&bp
, call
->reply
[1]);
468 _leave(" = 0 [done]");
473 * YFS.FetchStatus operation type
475 static const struct afs_call_type yfs_RXYFSFetchStatus_vnode
= {
476 .name
= "YFS.FetchStatus(vnode)",
477 .op
= yfs_FS_FetchStatus
,
478 .deliver
= yfs_deliver_fs_fetch_status_vnode
,
479 .destructor
= afs_flat_call_destructor
,
483 * Fetch the status information for a file.
485 int yfs_fs_fetch_file_status(struct afs_fs_cursor
*fc
, struct afs_volsync
*volsync
,
488 struct afs_vnode
*vnode
= fc
->vnode
;
489 struct afs_call
*call
;
490 struct afs_net
*net
= afs_v2net(vnode
);
493 _enter(",%x,{%llx:%llu},,",
494 key_serial(fc
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
496 call
= afs_alloc_flat_call(net
, &yfs_RXYFSFetchStatus_vnode
,
498 sizeof(struct yfs_xdr_YFSFid
),
499 sizeof(struct yfs_xdr_YFSFetchStatus
) +
500 sizeof(struct yfs_xdr_YFSCallBack
) +
501 sizeof(struct yfs_xdr_YFSVolSync
));
503 fc
->ac
.error
= -ENOMEM
;
508 call
->reply
[0] = vnode
;
509 call
->reply
[1] = volsync
;
510 call
->expected_version
= new_inode
? 1 : vnode
->status
.data_version
;
512 /* marshall the parameters */
514 bp
= xdr_encode_u32(bp
, YFSFETCHSTATUS
);
515 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
516 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
517 yfs_check_req(call
, bp
);
519 call
->cb_break
= fc
->cb_break
;
520 afs_use_fs_server(call
, fc
->cbi
);
521 trace_afs_make_fs_call(call
, &vnode
->fid
);
522 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
526 * Deliver reply data to an YFS.FetchData64.
528 static int yfs_deliver_fs_fetch_data64(struct afs_call
*call
)
530 struct afs_vnode
*vnode
= call
->reply
[0];
531 struct afs_read
*req
= call
->reply
[2];
536 _enter("{%u,%zu/%llu}",
537 call
->unmarshall
, iov_iter_count(&call
->iter
), req
->actual_len
);
539 switch (call
->unmarshall
) {
543 req
->offset
= req
->pos
& (PAGE_SIZE
- 1);
544 afs_extract_to_tmp64(call
);
547 /* extract the returned data length */
549 _debug("extract data length");
550 ret
= afs_extract_data(call
, true);
554 req
->actual_len
= be64_to_cpu(call
->tmp64
);
555 _debug("DATA length: %llu", req
->actual_len
);
556 req
->remain
= min(req
->len
, req
->actual_len
);
557 if (req
->remain
== 0)
563 ASSERTCMP(req
->index
, <, req
->nr_pages
);
564 if (req
->remain
> PAGE_SIZE
- req
->offset
)
565 size
= PAGE_SIZE
- req
->offset
;
568 call
->bvec
[0].bv_len
= size
;
569 call
->bvec
[0].bv_offset
= req
->offset
;
570 call
->bvec
[0].bv_page
= req
->pages
[req
->index
];
571 iov_iter_bvec(&call
->iter
, READ
, call
->bvec
, 1, size
);
572 ASSERTCMP(size
, <=, PAGE_SIZE
);
574 /* extract the returned data */
576 _debug("extract data %zu/%llu",
577 iov_iter_count(&call
->iter
), req
->remain
);
579 ret
= afs_extract_data(call
, true);
582 req
->remain
-= call
->bvec
[0].bv_len
;
583 req
->offset
+= call
->bvec
[0].bv_len
;
584 ASSERTCMP(req
->offset
, <=, PAGE_SIZE
);
585 if (req
->offset
== PAGE_SIZE
) {
588 req
->page_done(call
, req
);
594 ASSERTCMP(req
->remain
, ==, 0);
595 if (req
->actual_len
<= req
->len
)
598 /* Discard any excess data the server gave us */
599 iov_iter_discard(&call
->iter
, READ
, req
->actual_len
- req
->len
);
600 call
->unmarshall
= 3;
602 _debug("extract discard %zu/%llu",
603 iov_iter_count(&call
->iter
), req
->actual_len
- req
->len
);
605 ret
= afs_extract_data(call
, true);
610 call
->unmarshall
= 4;
611 afs_extract_to_buf(call
,
612 sizeof(struct yfs_xdr_YFSFetchStatus
) +
613 sizeof(struct yfs_xdr_YFSCallBack
) +
614 sizeof(struct yfs_xdr_YFSVolSync
));
616 /* extract the metadata */
618 ret
= afs_extract_data(call
, false);
623 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
,
624 &vnode
->status
.data_version
, req
);
627 xdr_decode_YFSCallBack(call
, vnode
, &bp
);
628 xdr_decode_YFSVolSync(&bp
, call
->reply
[1]);
636 for (; req
->index
< req
->nr_pages
; req
->index
++) {
637 if (req
->offset
< PAGE_SIZE
)
638 zero_user_segment(req
->pages
[req
->index
],
639 req
->offset
, PAGE_SIZE
);
641 req
->page_done(call
, req
);
645 _leave(" = 0 [done]");
649 static void yfs_fetch_data_destructor(struct afs_call
*call
)
651 struct afs_read
*req
= call
->reply
[2];
654 afs_flat_call_destructor(call
);
658 * YFS.FetchData64 operation type
660 static const struct afs_call_type yfs_RXYFSFetchData64
= {
661 .name
= "YFS.FetchData64",
662 .op
= yfs_FS_FetchData64
,
663 .deliver
= yfs_deliver_fs_fetch_data64
,
664 .destructor
= yfs_fetch_data_destructor
,
668 * Fetch data from a file.
670 int yfs_fs_fetch_data(struct afs_fs_cursor
*fc
, struct afs_read
*req
)
672 struct afs_vnode
*vnode
= fc
->vnode
;
673 struct afs_call
*call
;
674 struct afs_net
*net
= afs_v2net(vnode
);
677 _enter(",%x,{%llx:%llu},%llx,%llx",
678 key_serial(fc
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
,
681 call
= afs_alloc_flat_call(net
, &yfs_RXYFSFetchData64
,
683 sizeof(struct yfs_xdr_YFSFid
) +
684 sizeof(struct yfs_xdr_u64
) * 2,
685 sizeof(struct yfs_xdr_YFSFetchStatus
) +
686 sizeof(struct yfs_xdr_YFSCallBack
) +
687 sizeof(struct yfs_xdr_YFSVolSync
));
692 call
->reply
[0] = vnode
;
693 call
->reply
[1] = NULL
; /* volsync */
694 call
->reply
[2] = req
;
695 call
->expected_version
= vnode
->status
.data_version
;
696 call
->want_reply_time
= true;
698 /* marshall the parameters */
700 bp
= xdr_encode_u32(bp
, YFSFETCHDATA64
);
701 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
702 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
703 bp
= xdr_encode_u64(bp
, req
->pos
);
704 bp
= xdr_encode_u64(bp
, req
->len
);
705 yfs_check_req(call
, bp
);
707 refcount_inc(&req
->usage
);
708 call
->cb_break
= fc
->cb_break
;
709 afs_use_fs_server(call
, fc
->cbi
);
710 trace_afs_make_fs_call(call
, &vnode
->fid
);
711 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
715 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
717 static int yfs_deliver_fs_create_vnode(struct afs_call
*call
)
719 struct afs_vnode
*vnode
= call
->reply
[0];
723 _enter("{%u}", call
->unmarshall
);
725 ret
= afs_transfer_reply(call
);
729 /* unmarshall the reply once we've received all of it */
731 xdr_decode_YFSFid(&bp
, call
->reply
[1]);
732 ret
= yfs_decode_status(call
, &bp
, call
->reply
[2], NULL
, NULL
, NULL
);
735 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
,
736 &call
->expected_version
, NULL
);
739 xdr_decode_YFSCallBack_raw(&bp
, call
->reply
[3]);
740 xdr_decode_YFSVolSync(&bp
, NULL
);
742 _leave(" = 0 [done]");
747 * FS.CreateFile and FS.MakeDir operation type
749 static const struct afs_call_type afs_RXFSCreateFile
= {
750 .name
= "YFS.CreateFile",
751 .op
= yfs_FS_CreateFile
,
752 .deliver
= yfs_deliver_fs_create_vnode
,
753 .destructor
= afs_flat_call_destructor
,
759 int yfs_fs_create_file(struct afs_fs_cursor
*fc
,
762 u64 current_data_version
,
763 struct afs_fid
*newfid
,
764 struct afs_file_status
*newstatus
,
765 struct afs_callback
*newcb
)
767 struct afs_vnode
*vnode
= fc
->vnode
;
768 struct afs_call
*call
;
769 struct afs_net
*net
= afs_v2net(vnode
);
770 size_t namesz
, reqsz
, rplsz
;
775 namesz
= strlen(name
);
776 reqsz
= (sizeof(__be32
) +
778 sizeof(struct yfs_xdr_YFSFid
) +
780 sizeof(struct yfs_xdr_YFSStoreStatus
) +
782 rplsz
= (sizeof(struct yfs_xdr_YFSFid
) +
783 sizeof(struct yfs_xdr_YFSFetchStatus
) +
784 sizeof(struct yfs_xdr_YFSFetchStatus
) +
785 sizeof(struct yfs_xdr_YFSCallBack
) +
786 sizeof(struct yfs_xdr_YFSVolSync
));
788 call
= afs_alloc_flat_call(net
, &afs_RXFSCreateFile
, reqsz
, rplsz
);
793 call
->reply
[0] = vnode
;
794 call
->reply
[1] = newfid
;
795 call
->reply
[2] = newstatus
;
796 call
->reply
[3] = newcb
;
797 call
->expected_version
= current_data_version
+ 1;
799 /* marshall the parameters */
801 bp
= xdr_encode_u32(bp
, YFSCREATEFILE
);
802 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
803 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
804 bp
= xdr_encode_string(bp
, name
, namesz
);
805 bp
= xdr_encode_YFSStoreStatus_mode(bp
, mode
);
806 bp
= xdr_encode_u32(bp
, 0); /* ViceLockType */
807 yfs_check_req(call
, bp
);
809 afs_use_fs_server(call
, fc
->cbi
);
810 trace_afs_make_fs_call(call
, &vnode
->fid
);
811 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
814 static const struct afs_call_type yfs_RXFSMakeDir
= {
815 .name
= "YFS.MakeDir",
816 .op
= yfs_FS_MakeDir
,
817 .deliver
= yfs_deliver_fs_create_vnode
,
818 .destructor
= afs_flat_call_destructor
,
824 int yfs_fs_make_dir(struct afs_fs_cursor
*fc
,
827 u64 current_data_version
,
828 struct afs_fid
*newfid
,
829 struct afs_file_status
*newstatus
,
830 struct afs_callback
*newcb
)
832 struct afs_vnode
*vnode
= fc
->vnode
;
833 struct afs_call
*call
;
834 struct afs_net
*net
= afs_v2net(vnode
);
835 size_t namesz
, reqsz
, rplsz
;
840 namesz
= strlen(name
);
841 reqsz
= (sizeof(__be32
) +
842 sizeof(struct yfs_xdr_RPCFlags
) +
843 sizeof(struct yfs_xdr_YFSFid
) +
845 sizeof(struct yfs_xdr_YFSStoreStatus
));
846 rplsz
= (sizeof(struct yfs_xdr_YFSFid
) +
847 sizeof(struct yfs_xdr_YFSFetchStatus
) +
848 sizeof(struct yfs_xdr_YFSFetchStatus
) +
849 sizeof(struct yfs_xdr_YFSCallBack
) +
850 sizeof(struct yfs_xdr_YFSVolSync
));
852 call
= afs_alloc_flat_call(net
, &yfs_RXFSMakeDir
, reqsz
, rplsz
);
857 call
->reply
[0] = vnode
;
858 call
->reply
[1] = newfid
;
859 call
->reply
[2] = newstatus
;
860 call
->reply
[3] = newcb
;
861 call
->expected_version
= current_data_version
+ 1;
863 /* marshall the parameters */
865 bp
= xdr_encode_u32(bp
, YFSMAKEDIR
);
866 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
867 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
868 bp
= xdr_encode_string(bp
, name
, namesz
);
869 bp
= xdr_encode_YFSStoreStatus_mode(bp
, mode
);
870 yfs_check_req(call
, bp
);
872 afs_use_fs_server(call
, fc
->cbi
);
873 trace_afs_make_fs_call(call
, &vnode
->fid
);
874 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
878 * Deliver reply data to a YFS.RemoveFile2 operation.
880 static int yfs_deliver_fs_remove_file2(struct afs_call
*call
)
882 struct afs_vnode
*dvnode
= call
->reply
[0];
883 struct afs_vnode
*vnode
= call
->reply
[1];
888 _enter("{%u}", call
->unmarshall
);
890 ret
= afs_transfer_reply(call
);
894 /* unmarshall the reply once we've received all of it */
896 ret
= yfs_decode_status(call
, &bp
, &dvnode
->status
, dvnode
,
897 &call
->expected_version
, NULL
);
901 xdr_decode_YFSFid(&bp
, &fid
);
902 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
, NULL
, NULL
);
905 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
907 xdr_decode_YFSVolSync(&bp
, NULL
);
912 * YFS.RemoveFile2 operation type.
914 static const struct afs_call_type yfs_RXYFSRemoveFile2
= {
915 .name
= "YFS.RemoveFile2",
916 .op
= yfs_FS_RemoveFile2
,
917 .deliver
= yfs_deliver_fs_remove_file2
,
918 .destructor
= afs_flat_call_destructor
,
922 * Remove a file and retrieve new file status.
924 int yfs_fs_remove_file2(struct afs_fs_cursor
*fc
, struct afs_vnode
*vnode
,
925 const char *name
, u64 current_data_version
)
927 struct afs_vnode
*dvnode
= fc
->vnode
;
928 struct afs_call
*call
;
929 struct afs_net
*net
= afs_v2net(dvnode
);
935 namesz
= strlen(name
);
937 call
= afs_alloc_flat_call(net
, &yfs_RXYFSRemoveFile2
,
939 sizeof(struct yfs_xdr_RPCFlags
) +
940 sizeof(struct yfs_xdr_YFSFid
) +
942 sizeof(struct yfs_xdr_YFSFetchStatus
) +
943 sizeof(struct yfs_xdr_YFSFid
) +
944 sizeof(struct yfs_xdr_YFSFetchStatus
) +
945 sizeof(struct yfs_xdr_YFSVolSync
));
950 call
->reply
[0] = dvnode
;
951 call
->reply
[1] = vnode
;
952 call
->expected_version
= current_data_version
+ 1;
954 /* marshall the parameters */
956 bp
= xdr_encode_u32(bp
, YFSREMOVEFILE2
);
957 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
958 bp
= xdr_encode_YFSFid(bp
, &dvnode
->fid
);
959 bp
= xdr_encode_string(bp
, name
, namesz
);
960 yfs_check_req(call
, bp
);
962 afs_use_fs_server(call
, fc
->cbi
);
963 trace_afs_make_fs_call(call
, &dvnode
->fid
);
964 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
968 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
970 static int yfs_deliver_fs_remove(struct afs_call
*call
)
972 struct afs_vnode
*dvnode
= call
->reply
[0];
976 _enter("{%u}", call
->unmarshall
);
978 ret
= afs_transfer_reply(call
);
982 /* unmarshall the reply once we've received all of it */
984 ret
= yfs_decode_status(call
, &bp
, &dvnode
->status
, dvnode
,
985 &call
->expected_version
, NULL
);
989 xdr_decode_YFSVolSync(&bp
, NULL
);
994 * FS.RemoveDir and FS.RemoveFile operation types.
996 static const struct afs_call_type yfs_RXYFSRemoveFile
= {
997 .name
= "YFS.RemoveFile",
998 .op
= yfs_FS_RemoveFile
,
999 .deliver
= yfs_deliver_fs_remove
,
1000 .destructor
= afs_flat_call_destructor
,
1003 static const struct afs_call_type yfs_RXYFSRemoveDir
= {
1004 .name
= "YFS.RemoveDir",
1005 .op
= yfs_FS_RemoveDir
,
1006 .deliver
= yfs_deliver_fs_remove
,
1007 .destructor
= afs_flat_call_destructor
,
1011 * remove a file or directory
1013 int yfs_fs_remove(struct afs_fs_cursor
*fc
, struct afs_vnode
*vnode
,
1014 const char *name
, bool isdir
, u64 current_data_version
)
1016 struct afs_vnode
*dvnode
= fc
->vnode
;
1017 struct afs_call
*call
;
1018 struct afs_net
*net
= afs_v2net(dvnode
);
1024 namesz
= strlen(name
);
1025 call
= afs_alloc_flat_call(
1026 net
, isdir
? &yfs_RXYFSRemoveDir
: &yfs_RXYFSRemoveFile
,
1028 sizeof(struct yfs_xdr_RPCFlags
) +
1029 sizeof(struct yfs_xdr_YFSFid
) +
1031 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1032 sizeof(struct yfs_xdr_YFSVolSync
));
1036 call
->key
= fc
->key
;
1037 call
->reply
[0] = dvnode
;
1038 call
->reply
[1] = vnode
;
1039 call
->expected_version
= current_data_version
+ 1;
1041 /* marshall the parameters */
1043 bp
= xdr_encode_u32(bp
, isdir
? YFSREMOVEDIR
: YFSREMOVEFILE
);
1044 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1045 bp
= xdr_encode_YFSFid(bp
, &dvnode
->fid
);
1046 bp
= xdr_encode_string(bp
, name
, namesz
);
1047 yfs_check_req(call
, bp
);
1049 afs_use_fs_server(call
, fc
->cbi
);
1050 trace_afs_make_fs_call(call
, &dvnode
->fid
);
1051 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1055 * Deliver reply data to a YFS.Link operation.
1057 static int yfs_deliver_fs_link(struct afs_call
*call
)
1059 struct afs_vnode
*dvnode
= call
->reply
[0], *vnode
= call
->reply
[1];
1063 _enter("{%u}", call
->unmarshall
);
1065 ret
= afs_transfer_reply(call
);
1069 /* unmarshall the reply once we've received all of it */
1071 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
, NULL
, NULL
);
1074 ret
= yfs_decode_status(call
, &bp
, &dvnode
->status
, dvnode
,
1075 &call
->expected_version
, NULL
);
1078 xdr_decode_YFSVolSync(&bp
, NULL
);
1079 _leave(" = 0 [done]");
1084 * YFS.Link operation type.
1086 static const struct afs_call_type yfs_RXYFSLink
= {
1089 .deliver
= yfs_deliver_fs_link
,
1090 .destructor
= afs_flat_call_destructor
,
1096 int yfs_fs_link(struct afs_fs_cursor
*fc
, struct afs_vnode
*vnode
,
1097 const char *name
, u64 current_data_version
)
1099 struct afs_vnode
*dvnode
= fc
->vnode
;
1100 struct afs_call
*call
;
1101 struct afs_net
*net
= afs_v2net(vnode
);
1107 namesz
= strlen(name
);
1108 call
= afs_alloc_flat_call(net
, &yfs_RXYFSLink
,
1110 sizeof(struct yfs_xdr_RPCFlags
) +
1111 sizeof(struct yfs_xdr_YFSFid
) +
1112 xdr_strlen(namesz
) +
1113 sizeof(struct yfs_xdr_YFSFid
),
1114 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1115 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1116 sizeof(struct yfs_xdr_YFSVolSync
));
1120 call
->key
= fc
->key
;
1121 call
->reply
[0] = dvnode
;
1122 call
->reply
[1] = vnode
;
1123 call
->expected_version
= current_data_version
+ 1;
1125 /* marshall the parameters */
1127 bp
= xdr_encode_u32(bp
, YFSLINK
);
1128 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1129 bp
= xdr_encode_YFSFid(bp
, &dvnode
->fid
);
1130 bp
= xdr_encode_string(bp
, name
, namesz
);
1131 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
1132 yfs_check_req(call
, bp
);
1134 afs_use_fs_server(call
, fc
->cbi
);
1135 trace_afs_make_fs_call(call
, &vnode
->fid
);
1136 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1140 * Deliver reply data to a YFS.Symlink operation.
1142 static int yfs_deliver_fs_symlink(struct afs_call
*call
)
1144 struct afs_vnode
*vnode
= call
->reply
[0];
1148 _enter("{%u}", call
->unmarshall
);
1150 ret
= afs_transfer_reply(call
);
1154 /* unmarshall the reply once we've received all of it */
1156 xdr_decode_YFSFid(&bp
, call
->reply
[1]);
1157 ret
= yfs_decode_status(call
, &bp
, call
->reply
[2], NULL
, NULL
, NULL
);
1160 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
,
1161 &call
->expected_version
, NULL
);
1164 xdr_decode_YFSVolSync(&bp
, NULL
);
1166 _leave(" = 0 [done]");
1171 * YFS.Symlink operation type
1173 static const struct afs_call_type yfs_RXYFSSymlink
= {
1174 .name
= "YFS.Symlink",
1175 .op
= yfs_FS_Symlink
,
1176 .deliver
= yfs_deliver_fs_symlink
,
1177 .destructor
= afs_flat_call_destructor
,
1181 * Create a symbolic link.
1183 int yfs_fs_symlink(struct afs_fs_cursor
*fc
,
1185 const char *contents
,
1186 u64 current_data_version
,
1187 struct afs_fid
*newfid
,
1188 struct afs_file_status
*newstatus
)
1190 struct afs_vnode
*dvnode
= fc
->vnode
;
1191 struct afs_call
*call
;
1192 struct afs_net
*net
= afs_v2net(dvnode
);
1193 size_t namesz
, contents_sz
;
1198 namesz
= strlen(name
);
1199 contents_sz
= strlen(contents
);
1200 call
= afs_alloc_flat_call(net
, &yfs_RXYFSSymlink
,
1202 sizeof(struct yfs_xdr_RPCFlags
) +
1203 sizeof(struct yfs_xdr_YFSFid
) +
1204 xdr_strlen(namesz
) +
1205 xdr_strlen(contents_sz
) +
1206 sizeof(struct yfs_xdr_YFSStoreStatus
),
1207 sizeof(struct yfs_xdr_YFSFid
) +
1208 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1209 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1210 sizeof(struct yfs_xdr_YFSVolSync
));
1214 call
->key
= fc
->key
;
1215 call
->reply
[0] = dvnode
;
1216 call
->reply
[1] = newfid
;
1217 call
->reply
[2] = newstatus
;
1218 call
->expected_version
= current_data_version
+ 1;
1220 /* marshall the parameters */
1222 bp
= xdr_encode_u32(bp
, YFSSYMLINK
);
1223 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1224 bp
= xdr_encode_YFSFid(bp
, &dvnode
->fid
);
1225 bp
= xdr_encode_string(bp
, name
, namesz
);
1226 bp
= xdr_encode_string(bp
, contents
, contents_sz
);
1227 bp
= xdr_encode_YFSStoreStatus_mode(bp
, S_IRWXUGO
);
1228 yfs_check_req(call
, bp
);
1230 afs_use_fs_server(call
, fc
->cbi
);
1231 trace_afs_make_fs_call(call
, &dvnode
->fid
);
1232 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1236 * Deliver reply data to a YFS.Rename operation.
1238 static int yfs_deliver_fs_rename(struct afs_call
*call
)
1240 struct afs_vnode
*orig_dvnode
= call
->reply
[0];
1241 struct afs_vnode
*new_dvnode
= call
->reply
[1];
1245 _enter("{%u}", call
->unmarshall
);
1247 ret
= afs_transfer_reply(call
);
1251 /* unmarshall the reply once we've received all of it */
1253 ret
= yfs_decode_status(call
, &bp
, &orig_dvnode
->status
, orig_dvnode
,
1254 &call
->expected_version
, NULL
);
1257 if (new_dvnode
!= orig_dvnode
) {
1258 ret
= yfs_decode_status(call
, &bp
, &new_dvnode
->status
, new_dvnode
,
1259 &call
->expected_version_2
, NULL
);
1264 xdr_decode_YFSVolSync(&bp
, NULL
);
1265 _leave(" = 0 [done]");
1270 * YFS.Rename operation type
1272 static const struct afs_call_type yfs_RXYFSRename
= {
1273 .name
= "FS.Rename",
1274 .op
= yfs_FS_Rename
,
1275 .deliver
= yfs_deliver_fs_rename
,
1276 .destructor
= afs_flat_call_destructor
,
1280 * Rename a file or directory.
1282 int yfs_fs_rename(struct afs_fs_cursor
*fc
,
1283 const char *orig_name
,
1284 struct afs_vnode
*new_dvnode
,
1285 const char *new_name
,
1286 u64 current_orig_data_version
,
1287 u64 current_new_data_version
)
1289 struct afs_vnode
*orig_dvnode
= fc
->vnode
;
1290 struct afs_call
*call
;
1291 struct afs_net
*net
= afs_v2net(orig_dvnode
);
1292 size_t o_namesz
, n_namesz
;
1297 o_namesz
= strlen(orig_name
);
1298 n_namesz
= strlen(new_name
);
1299 call
= afs_alloc_flat_call(net
, &yfs_RXYFSRename
,
1301 sizeof(struct yfs_xdr_RPCFlags
) +
1302 sizeof(struct yfs_xdr_YFSFid
) +
1303 xdr_strlen(o_namesz
) +
1304 sizeof(struct yfs_xdr_YFSFid
) +
1305 xdr_strlen(n_namesz
),
1306 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1307 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1308 sizeof(struct yfs_xdr_YFSVolSync
));
1312 call
->key
= fc
->key
;
1313 call
->reply
[0] = orig_dvnode
;
1314 call
->reply
[1] = new_dvnode
;
1315 call
->expected_version
= current_orig_data_version
+ 1;
1316 call
->expected_version_2
= current_new_data_version
+ 1;
1318 /* marshall the parameters */
1320 bp
= xdr_encode_u32(bp
, YFSRENAME
);
1321 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1322 bp
= xdr_encode_YFSFid(bp
, &orig_dvnode
->fid
);
1323 bp
= xdr_encode_string(bp
, orig_name
, o_namesz
);
1324 bp
= xdr_encode_YFSFid(bp
, &new_dvnode
->fid
);
1325 bp
= xdr_encode_string(bp
, new_name
, n_namesz
);
1326 yfs_check_req(call
, bp
);
1328 afs_use_fs_server(call
, fc
->cbi
);
1329 trace_afs_make_fs_call(call
, &orig_dvnode
->fid
);
1330 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1334 * Deliver reply data to a YFS.StoreData64 operation.
1336 static int yfs_deliver_fs_store_data(struct afs_call
*call
)
1338 struct afs_vnode
*vnode
= call
->reply
[0];
1344 ret
= afs_transfer_reply(call
);
1348 /* unmarshall the reply once we've received all of it */
1350 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
,
1351 &call
->expected_version
, NULL
);
1354 xdr_decode_YFSVolSync(&bp
, NULL
);
1356 afs_pages_written_back(vnode
, call
);
1358 _leave(" = 0 [done]");
1363 * YFS.StoreData64 operation type.
1365 static const struct afs_call_type yfs_RXYFSStoreData64
= {
1366 .name
= "YFS.StoreData64",
1367 .op
= yfs_FS_StoreData64
,
1368 .deliver
= yfs_deliver_fs_store_data
,
1369 .destructor
= afs_flat_call_destructor
,
1373 * Store a set of pages to a large file.
1375 int yfs_fs_store_data(struct afs_fs_cursor
*fc
, struct address_space
*mapping
,
1376 pgoff_t first
, pgoff_t last
,
1377 unsigned offset
, unsigned to
)
1379 struct afs_vnode
*vnode
= fc
->vnode
;
1380 struct afs_call
*call
;
1381 struct afs_net
*net
= afs_v2net(vnode
);
1382 loff_t size
, pos
, i_size
;
1385 _enter(",%x,{%llx:%llu},,",
1386 key_serial(fc
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1388 size
= (loff_t
)to
- (loff_t
)offset
;
1390 size
+= (loff_t
)(last
- first
) << PAGE_SHIFT
;
1391 pos
= (loff_t
)first
<< PAGE_SHIFT
;
1394 i_size
= i_size_read(&vnode
->vfs_inode
);
1395 if (pos
+ size
> i_size
)
1396 i_size
= size
+ pos
;
1398 _debug("size %llx, at %llx, i_size %llx",
1399 (unsigned long long)size
, (unsigned long long)pos
,
1400 (unsigned long long)i_size
);
1402 call
= afs_alloc_flat_call(net
, &yfs_RXYFSStoreData64
,
1405 sizeof(struct yfs_xdr_YFSFid
) +
1406 sizeof(struct yfs_xdr_YFSStoreStatus
) +
1407 sizeof(struct yfs_xdr_u64
) * 3,
1408 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1409 sizeof(struct yfs_xdr_YFSVolSync
));
1413 call
->key
= fc
->key
;
1414 call
->mapping
= mapping
;
1415 call
->reply
[0] = vnode
;
1416 call
->first
= first
;
1418 call
->first_offset
= offset
;
1420 call
->send_pages
= true;
1421 call
->expected_version
= vnode
->status
.data_version
+ 1;
1423 /* marshall the parameters */
1425 bp
= xdr_encode_u32(bp
, YFSSTOREDATA64
);
1426 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1427 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
1428 bp
= xdr_encode_YFSStoreStatus_mtime(bp
, &vnode
->vfs_inode
.i_mtime
);
1429 bp
= xdr_encode_u64(bp
, pos
);
1430 bp
= xdr_encode_u64(bp
, size
);
1431 bp
= xdr_encode_u64(bp
, i_size
);
1432 yfs_check_req(call
, bp
);
1434 afs_use_fs_server(call
, fc
->cbi
);
1435 trace_afs_make_fs_call(call
, &vnode
->fid
);
1436 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1440 * deliver reply data to an FS.StoreStatus
1442 static int yfs_deliver_fs_store_status(struct afs_call
*call
)
1444 struct afs_vnode
*vnode
= call
->reply
[0];
1450 ret
= afs_transfer_reply(call
);
1454 /* unmarshall the reply once we've received all of it */
1456 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
,
1457 &call
->expected_version
, NULL
);
1460 xdr_decode_YFSVolSync(&bp
, NULL
);
1462 _leave(" = 0 [done]");
1467 * YFS.StoreStatus operation type
1469 static const struct afs_call_type yfs_RXYFSStoreStatus
= {
1470 .name
= "YFS.StoreStatus",
1471 .op
= yfs_FS_StoreStatus
,
1472 .deliver
= yfs_deliver_fs_store_status
,
1473 .destructor
= afs_flat_call_destructor
,
1476 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status
= {
1477 .name
= "YFS.StoreData64",
1478 .op
= yfs_FS_StoreData64
,
1479 .deliver
= yfs_deliver_fs_store_status
,
1480 .destructor
= afs_flat_call_destructor
,
1484 * Set the attributes on a file, using YFS.StoreData64 rather than
1485 * YFS.StoreStatus so as to alter the file size also.
1487 static int yfs_fs_setattr_size(struct afs_fs_cursor
*fc
, struct iattr
*attr
)
1489 struct afs_vnode
*vnode
= fc
->vnode
;
1490 struct afs_call
*call
;
1491 struct afs_net
*net
= afs_v2net(vnode
);
1494 _enter(",%x,{%llx:%llu},,",
1495 key_serial(fc
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1497 call
= afs_alloc_flat_call(net
, &yfs_RXYFSStoreData64_as_Status
,
1498 sizeof(__be32
) * 2 +
1499 sizeof(struct yfs_xdr_YFSFid
) +
1500 sizeof(struct yfs_xdr_YFSStoreStatus
) +
1501 sizeof(struct yfs_xdr_u64
) * 3,
1502 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1503 sizeof(struct yfs_xdr_YFSVolSync
));
1507 call
->key
= fc
->key
;
1508 call
->reply
[0] = vnode
;
1509 call
->expected_version
= vnode
->status
.data_version
+ 1;
1511 /* marshall the parameters */
1513 bp
= xdr_encode_u32(bp
, YFSSTOREDATA64
);
1514 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1515 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
1516 bp
= xdr_encode_YFS_StoreStatus(bp
, attr
);
1517 bp
= xdr_encode_u64(bp
, 0); /* position of start of write */
1518 bp
= xdr_encode_u64(bp
, 0); /* size of write */
1519 bp
= xdr_encode_u64(bp
, attr
->ia_size
); /* new file length */
1520 yfs_check_req(call
, bp
);
1522 afs_use_fs_server(call
, fc
->cbi
);
1523 trace_afs_make_fs_call(call
, &vnode
->fid
);
1524 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1528 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1529 * file size, and YFS.StoreStatus otherwise.
1531 int yfs_fs_setattr(struct afs_fs_cursor
*fc
, struct iattr
*attr
)
1533 struct afs_vnode
*vnode
= fc
->vnode
;
1534 struct afs_call
*call
;
1535 struct afs_net
*net
= afs_v2net(vnode
);
1538 if (attr
->ia_valid
& ATTR_SIZE
)
1539 return yfs_fs_setattr_size(fc
, attr
);
1541 _enter(",%x,{%llx:%llu},,",
1542 key_serial(fc
->key
), vnode
->fid
.vid
, vnode
->fid
.vnode
);
1544 call
= afs_alloc_flat_call(net
, &yfs_RXYFSStoreStatus
,
1545 sizeof(__be32
) * 2 +
1546 sizeof(struct yfs_xdr_YFSFid
) +
1547 sizeof(struct yfs_xdr_YFSStoreStatus
),
1548 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1549 sizeof(struct yfs_xdr_YFSVolSync
));
1553 call
->key
= fc
->key
;
1554 call
->reply
[0] = vnode
;
1555 call
->expected_version
= vnode
->status
.data_version
;
1557 /* marshall the parameters */
1559 bp
= xdr_encode_u32(bp
, YFSSTORESTATUS
);
1560 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1561 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
1562 bp
= xdr_encode_YFS_StoreStatus(bp
, attr
);
1563 yfs_check_req(call
, bp
);
1565 afs_use_fs_server(call
, fc
->cbi
);
1566 trace_afs_make_fs_call(call
, &vnode
->fid
);
1567 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1571 * Deliver reply data to a YFS.GetVolumeStatus operation.
1573 static int yfs_deliver_fs_get_volume_status(struct afs_call
*call
)
1580 _enter("{%u}", call
->unmarshall
);
1582 switch (call
->unmarshall
) {
1585 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSFetchVolumeStatus
));
1587 /* extract the returned status record */
1589 _debug("extract status");
1590 ret
= afs_extract_data(call
, true);
1595 xdr_decode_YFSFetchVolumeStatus(&bp
, call
->reply
[1]);
1597 afs_extract_to_tmp(call
);
1599 /* extract the volume name length */
1601 ret
= afs_extract_data(call
, true);
1605 call
->count
= ntohl(call
->tmp
);
1606 _debug("volname length: %u", call
->count
);
1607 if (call
->count
>= AFSNAMEMAX
)
1608 return afs_protocol_error(call
, -EBADMSG
,
1609 afs_eproto_volname_len
);
1610 size
= (call
->count
+ 3) & ~3; /* It's padded */
1611 afs_extract_begin(call
, call
->reply
[2], size
);
1614 /* extract the volume name */
1616 _debug("extract volname");
1617 ret
= afs_extract_data(call
, true);
1623 _debug("volname '%s'", p
);
1624 afs_extract_to_tmp(call
);
1627 /* extract the offline message length */
1629 ret
= afs_extract_data(call
, true);
1633 call
->count
= ntohl(call
->tmp
);
1634 _debug("offline msg length: %u", call
->count
);
1635 if (call
->count
>= AFSNAMEMAX
)
1636 return afs_protocol_error(call
, -EBADMSG
,
1637 afs_eproto_offline_msg_len
);
1638 size
= (call
->count
+ 3) & ~3; /* It's padded */
1639 afs_extract_begin(call
, call
->reply
[2], size
);
1642 /* extract the offline message */
1644 _debug("extract offline");
1645 ret
= afs_extract_data(call
, true);
1651 _debug("offline '%s'", p
);
1653 afs_extract_to_tmp(call
);
1656 /* extract the message of the day length */
1658 ret
= afs_extract_data(call
, true);
1662 call
->count
= ntohl(call
->tmp
);
1663 _debug("motd length: %u", call
->count
);
1664 if (call
->count
>= AFSNAMEMAX
)
1665 return afs_protocol_error(call
, -EBADMSG
,
1666 afs_eproto_motd_len
);
1667 size
= (call
->count
+ 3) & ~3; /* It's padded */
1668 afs_extract_begin(call
, call
->reply
[2], size
);
1671 /* extract the message of the day */
1673 _debug("extract motd");
1674 ret
= afs_extract_data(call
, false);
1680 _debug("motd '%s'", p
);
1688 _leave(" = 0 [done]");
1693 * Destroy a YFS.GetVolumeStatus call.
1695 static void yfs_get_volume_status_call_destructor(struct afs_call
*call
)
1697 kfree(call
->reply
[2]);
1698 call
->reply
[2] = NULL
;
1699 afs_flat_call_destructor(call
);
1703 * YFS.GetVolumeStatus operation type
1705 static const struct afs_call_type yfs_RXYFSGetVolumeStatus
= {
1706 .name
= "YFS.GetVolumeStatus",
1707 .op
= yfs_FS_GetVolumeStatus
,
1708 .deliver
= yfs_deliver_fs_get_volume_status
,
1709 .destructor
= yfs_get_volume_status_call_destructor
,
1713 * fetch the status of a volume
1715 int yfs_fs_get_volume_status(struct afs_fs_cursor
*fc
,
1716 struct afs_volume_status
*vs
)
1718 struct afs_vnode
*vnode
= fc
->vnode
;
1719 struct afs_call
*call
;
1720 struct afs_net
*net
= afs_v2net(vnode
);
1726 tmpbuf
= kmalloc(AFSOPAQUEMAX
, GFP_KERNEL
);
1730 call
= afs_alloc_flat_call(net
, &yfs_RXYFSGetVolumeStatus
,
1731 sizeof(__be32
) * 2 +
1732 sizeof(struct yfs_xdr_u64
),
1733 sizeof(struct yfs_xdr_YFSFetchVolumeStatus
) +
1740 call
->key
= fc
->key
;
1741 call
->reply
[0] = vnode
;
1742 call
->reply
[1] = vs
;
1743 call
->reply
[2] = tmpbuf
;
1745 /* marshall the parameters */
1747 bp
= xdr_encode_u32(bp
, YFSGETVOLUMESTATUS
);
1748 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1749 bp
= xdr_encode_u64(bp
, vnode
->fid
.vid
);
1750 yfs_check_req(call
, bp
);
1752 afs_use_fs_server(call
, fc
->cbi
);
1753 trace_afs_make_fs_call(call
, &vnode
->fid
);
1754 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1758 * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock
1760 static int yfs_deliver_fs_xxxx_lock(struct afs_call
*call
)
1762 struct afs_vnode
*vnode
= call
->reply
[0];
1766 _enter("{%u}", call
->unmarshall
);
1768 ret
= afs_transfer_reply(call
);
1772 /* unmarshall the reply once we've received all of it */
1774 ret
= yfs_decode_status(call
, &bp
, &vnode
->status
, vnode
,
1775 &call
->expected_version
, NULL
);
1778 xdr_decode_YFSVolSync(&bp
, NULL
);
1780 _leave(" = 0 [done]");
1785 * YFS.SetLock operation type
1787 static const struct afs_call_type yfs_RXYFSSetLock
= {
1788 .name
= "YFS.SetLock",
1789 .op
= yfs_FS_SetLock
,
1790 .deliver
= yfs_deliver_fs_xxxx_lock
,
1791 .destructor
= afs_flat_call_destructor
,
1795 * YFS.ExtendLock operation type
1797 static const struct afs_call_type yfs_RXYFSExtendLock
= {
1798 .name
= "YFS.ExtendLock",
1799 .op
= yfs_FS_ExtendLock
,
1800 .deliver
= yfs_deliver_fs_xxxx_lock
,
1801 .destructor
= afs_flat_call_destructor
,
1805 * YFS.ReleaseLock operation type
1807 static const struct afs_call_type yfs_RXYFSReleaseLock
= {
1808 .name
= "YFS.ReleaseLock",
1809 .op
= yfs_FS_ReleaseLock
,
1810 .deliver
= yfs_deliver_fs_xxxx_lock
,
1811 .destructor
= afs_flat_call_destructor
,
1815 * Set a lock on a file
1817 int yfs_fs_set_lock(struct afs_fs_cursor
*fc
, afs_lock_type_t type
)
1819 struct afs_vnode
*vnode
= fc
->vnode
;
1820 struct afs_call
*call
;
1821 struct afs_net
*net
= afs_v2net(vnode
);
1826 call
= afs_alloc_flat_call(net
, &yfs_RXYFSSetLock
,
1827 sizeof(__be32
) * 2 +
1828 sizeof(struct yfs_xdr_YFSFid
) +
1830 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1831 sizeof(struct yfs_xdr_YFSVolSync
));
1835 call
->key
= fc
->key
;
1836 call
->reply
[0] = vnode
;
1838 /* marshall the parameters */
1840 bp
= xdr_encode_u32(bp
, YFSSETLOCK
);
1841 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1842 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
1843 bp
= xdr_encode_u32(bp
, type
);
1844 yfs_check_req(call
, bp
);
1846 afs_use_fs_server(call
, fc
->cbi
);
1847 trace_afs_make_fs_call(call
, &vnode
->fid
);
1848 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1852 * extend a lock on a file
1854 int yfs_fs_extend_lock(struct afs_fs_cursor
*fc
)
1856 struct afs_vnode
*vnode
= fc
->vnode
;
1857 struct afs_call
*call
;
1858 struct afs_net
*net
= afs_v2net(vnode
);
1863 call
= afs_alloc_flat_call(net
, &yfs_RXYFSExtendLock
,
1864 sizeof(__be32
) * 2 +
1865 sizeof(struct yfs_xdr_YFSFid
),
1866 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1867 sizeof(struct yfs_xdr_YFSVolSync
));
1871 call
->key
= fc
->key
;
1872 call
->reply
[0] = vnode
;
1874 /* marshall the parameters */
1876 bp
= xdr_encode_u32(bp
, YFSEXTENDLOCK
);
1877 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1878 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
1879 yfs_check_req(call
, bp
);
1881 afs_use_fs_server(call
, fc
->cbi
);
1882 trace_afs_make_fs_call(call
, &vnode
->fid
);
1883 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1887 * release a lock on a file
1889 int yfs_fs_release_lock(struct afs_fs_cursor
*fc
)
1891 struct afs_vnode
*vnode
= fc
->vnode
;
1892 struct afs_call
*call
;
1893 struct afs_net
*net
= afs_v2net(vnode
);
1898 call
= afs_alloc_flat_call(net
, &yfs_RXYFSReleaseLock
,
1899 sizeof(__be32
) * 2 +
1900 sizeof(struct yfs_xdr_YFSFid
),
1901 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1902 sizeof(struct yfs_xdr_YFSVolSync
));
1906 call
->key
= fc
->key
;
1907 call
->reply
[0] = vnode
;
1909 /* marshall the parameters */
1911 bp
= xdr_encode_u32(bp
, YFSRELEASELOCK
);
1912 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1913 bp
= xdr_encode_YFSFid(bp
, &vnode
->fid
);
1914 yfs_check_req(call
, bp
);
1916 afs_use_fs_server(call
, fc
->cbi
);
1917 trace_afs_make_fs_call(call
, &vnode
->fid
);
1918 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
1922 * Deliver reply data to an FS.FetchStatus with no vnode.
1924 static int yfs_deliver_fs_fetch_status(struct afs_call
*call
)
1926 struct afs_file_status
*status
= call
->reply
[1];
1927 struct afs_callback
*callback
= call
->reply
[2];
1928 struct afs_volsync
*volsync
= call
->reply
[3];
1929 struct afs_vnode
*vnode
= call
->reply
[0];
1933 ret
= afs_transfer_reply(call
);
1937 _enter("{%llx:%llu}", vnode
->fid
.vid
, vnode
->fid
.vnode
);
1939 /* unmarshall the reply once we've received all of it */
1941 ret
= yfs_decode_status(call
, &bp
, status
, vnode
,
1942 &call
->expected_version
, NULL
);
1945 xdr_decode_YFSCallBack_raw(&bp
, callback
);
1946 xdr_decode_YFSVolSync(&bp
, volsync
);
1948 _leave(" = 0 [done]");
1953 * YFS.FetchStatus operation type
1955 static const struct afs_call_type yfs_RXYFSFetchStatus
= {
1956 .name
= "YFS.FetchStatus",
1957 .op
= yfs_FS_FetchStatus
,
1958 .deliver
= yfs_deliver_fs_fetch_status
,
1959 .destructor
= afs_flat_call_destructor
,
1963 * Fetch the status information for a fid without needing a vnode handle.
1965 int yfs_fs_fetch_status(struct afs_fs_cursor
*fc
,
1966 struct afs_net
*net
,
1967 struct afs_fid
*fid
,
1968 struct afs_file_status
*status
,
1969 struct afs_callback
*callback
,
1970 struct afs_volsync
*volsync
)
1972 struct afs_call
*call
;
1975 _enter(",%x,{%llx:%llu},,",
1976 key_serial(fc
->key
), fid
->vid
, fid
->vnode
);
1978 call
= afs_alloc_flat_call(net
, &yfs_RXYFSFetchStatus
,
1979 sizeof(__be32
) * 2 +
1980 sizeof(struct yfs_xdr_YFSFid
),
1981 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1982 sizeof(struct yfs_xdr_YFSCallBack
) +
1983 sizeof(struct yfs_xdr_YFSVolSync
));
1985 fc
->ac
.error
= -ENOMEM
;
1989 call
->key
= fc
->key
;
1990 call
->reply
[0] = NULL
; /* vnode for fid[0] */
1991 call
->reply
[1] = status
;
1992 call
->reply
[2] = callback
;
1993 call
->reply
[3] = volsync
;
1994 call
->expected_version
= 1; /* vnode->status.data_version */
1996 /* marshall the parameters */
1998 bp
= xdr_encode_u32(bp
, YFSFETCHSTATUS
);
1999 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
2000 bp
= xdr_encode_YFSFid(bp
, fid
);
2001 yfs_check_req(call
, bp
);
2003 call
->cb_break
= fc
->cb_break
;
2004 afs_use_fs_server(call
, fc
->cbi
);
2005 trace_afs_make_fs_call(call
, fid
);
2006 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);
2010 * Deliver reply data to an YFS.InlineBulkStatus call
2012 static int yfs_deliver_fs_inline_bulk_status(struct afs_call
*call
)
2014 struct afs_file_status
*statuses
;
2015 struct afs_callback
*callbacks
;
2016 struct afs_vnode
*vnode
= call
->reply
[0];
2021 _enter("{%u}", call
->unmarshall
);
2023 switch (call
->unmarshall
) {
2025 afs_extract_to_tmp(call
);
2028 /* Extract the file status count and array in two steps */
2030 _debug("extract status count");
2031 ret
= afs_extract_data(call
, true);
2035 tmp
= ntohl(call
->tmp
);
2036 _debug("status count: %u/%u", tmp
, call
->count2
);
2037 if (tmp
!= call
->count2
)
2038 return afs_protocol_error(call
, -EBADMSG
,
2039 afs_eproto_ibulkst_count
);
2044 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSFetchStatus
));
2047 _debug("extract status array %u", call
->count
);
2048 ret
= afs_extract_data(call
, true);
2053 statuses
= call
->reply
[1];
2054 ret
= yfs_decode_status(call
, &bp
, &statuses
[call
->count
],
2055 call
->count
== 0 ? vnode
: NULL
,
2061 if (call
->count
< call
->count2
)
2066 afs_extract_to_tmp(call
);
2068 /* Extract the callback count and array in two steps */
2070 _debug("extract CB count");
2071 ret
= afs_extract_data(call
, true);
2075 tmp
= ntohl(call
->tmp
);
2076 _debug("CB count: %u", tmp
);
2077 if (tmp
!= call
->count2
)
2078 return afs_protocol_error(call
, -EBADMSG
,
2079 afs_eproto_ibulkst_cb_count
);
2083 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSCallBack
));
2086 _debug("extract CB array");
2087 ret
= afs_extract_data(call
, true);
2091 _debug("unmarshall CB array");
2093 callbacks
= call
->reply
[2];
2094 xdr_decode_YFSCallBack_raw(&bp
, &callbacks
[call
->count
]);
2095 statuses
= call
->reply
[1];
2096 if (call
->count
== 0 && vnode
&& statuses
[0].abort_code
== 0) {
2098 xdr_decode_YFSCallBack(call
, vnode
, &bp
);
2101 if (call
->count
< call
->count2
)
2104 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSVolSync
));
2108 ret
= afs_extract_data(call
, false);
2113 xdr_decode_YFSVolSync(&bp
, call
->reply
[3]);
2121 _leave(" = 0 [done]");
2126 * FS.InlineBulkStatus operation type
2128 static const struct afs_call_type yfs_RXYFSInlineBulkStatus
= {
2129 .name
= "YFS.InlineBulkStatus",
2130 .op
= yfs_FS_InlineBulkStatus
,
2131 .deliver
= yfs_deliver_fs_inline_bulk_status
,
2132 .destructor
= afs_flat_call_destructor
,
2136 * Fetch the status information for up to 1024 files
2138 int yfs_fs_inline_bulk_status(struct afs_fs_cursor
*fc
,
2139 struct afs_net
*net
,
2140 struct afs_fid
*fids
,
2141 struct afs_file_status
*statuses
,
2142 struct afs_callback
*callbacks
,
2143 unsigned int nr_fids
,
2144 struct afs_volsync
*volsync
)
2146 struct afs_call
*call
;
2150 _enter(",%x,{%llx:%llu},%u",
2151 key_serial(fc
->key
), fids
[0].vid
, fids
[1].vnode
, nr_fids
);
2153 call
= afs_alloc_flat_call(net
, &yfs_RXYFSInlineBulkStatus
,
2157 sizeof(struct yfs_xdr_YFSFid
) * nr_fids
,
2158 sizeof(struct yfs_xdr_YFSFetchStatus
));
2160 fc
->ac
.error
= -ENOMEM
;
2164 call
->key
= fc
->key
;
2165 call
->reply
[0] = NULL
; /* vnode for fid[0] */
2166 call
->reply
[1] = statuses
;
2167 call
->reply
[2] = callbacks
;
2168 call
->reply
[3] = volsync
;
2169 call
->count2
= nr_fids
;
2171 /* marshall the parameters */
2173 bp
= xdr_encode_u32(bp
, YFSINLINEBULKSTATUS
);
2174 bp
= xdr_encode_u32(bp
, 0); /* RPCFlags */
2175 bp
= xdr_encode_u32(bp
, nr_fids
);
2176 for (i
= 0; i
< nr_fids
; i
++)
2177 bp
= xdr_encode_YFSFid(bp
, &fids
[i
]);
2178 yfs_check_req(call
, bp
);
2180 call
->cb_break
= fc
->cb_break
;
2181 afs_use_fs_server(call
, fc
->cbi
);
2182 trace_afs_make_fs_call(call
, &fids
[0]);
2183 return afs_make_call(&fc
->ac
, call
, GFP_NOFS
, false);