1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* YFS File Server client stubs
4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #include <linux/init.h>
9 #include <linux/slab.h>
10 #include <linux/sched.h>
11 #include <linux/circ_buf.h>
12 #include <linux/iversion.h>
16 #include "protocol_yfs.h"
18 #define xdr_size(x) (sizeof(*x) / sizeof(__be32))
20 static void xdr_decode_YFSFid(const __be32
**_bp
, struct afs_fid
*fid
)
22 const struct yfs_xdr_YFSFid
*x
= (const void *)*_bp
;
24 fid
->vid
= xdr_to_u64(x
->volume
);
25 fid
->vnode
= xdr_to_u64(x
->vnode
.lo
);
26 fid
->vnode_hi
= ntohl(x
->vnode
.hi
);
27 fid
->unique
= ntohl(x
->vnode
.unique
);
31 static __be32
*xdr_encode_u32(__be32
*bp
, u32 n
)
37 static __be32
*xdr_encode_u64(__be32
*bp
, u64 n
)
39 struct yfs_xdr_u64
*x
= (void *)bp
;
42 return bp
+ xdr_size(x
);
45 static __be32
*xdr_encode_YFSFid(__be32
*bp
, struct afs_fid
*fid
)
47 struct yfs_xdr_YFSFid
*x
= (void *)bp
;
49 x
->volume
= u64_to_xdr(fid
->vid
);
50 x
->vnode
.lo
= u64_to_xdr(fid
->vnode
);
51 x
->vnode
.hi
= htonl(fid
->vnode_hi
);
52 x
->vnode
.unique
= htonl(fid
->unique
);
53 return bp
+ xdr_size(x
);
56 static size_t xdr_strlen(unsigned int len
)
58 return sizeof(__be32
) + round_up(len
, sizeof(__be32
));
61 static __be32
*xdr_encode_string(__be32
*bp
, const char *p
, unsigned int len
)
63 bp
= xdr_encode_u32(bp
, len
);
64 bp
= memcpy(bp
, p
, len
);
66 unsigned int pad
= 4 - (len
& 3);
68 memset((u8
*)bp
+ len
, 0, pad
);
72 return bp
+ len
/ sizeof(__be32
);
75 static __be32
*xdr_encode_name(__be32
*bp
, const struct qstr
*p
)
77 return xdr_encode_string(bp
, p
->name
, p
->len
);
80 static s64
linux_to_yfs_time(const struct timespec64
*t
)
82 /* Convert to 100ns intervals. */
83 return (u64
)t
->tv_sec
* 10000000 + t
->tv_nsec
/100;
86 static __be32
*xdr_encode_YFSStoreStatus_mode(__be32
*bp
, mode_t mode
)
88 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
90 x
->mask
= htonl(AFS_SET_MODE
);
91 x
->mode
= htonl(mode
& S_IALLUGO
);
92 x
->mtime_client
= u64_to_xdr(0);
93 x
->owner
= u64_to_xdr(0);
94 x
->group
= u64_to_xdr(0);
95 return bp
+ xdr_size(x
);
98 static __be32
*xdr_encode_YFSStoreStatus_mtime(__be32
*bp
, const struct timespec64
*t
)
100 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
101 s64 mtime
= linux_to_yfs_time(t
);
103 x
->mask
= htonl(AFS_SET_MTIME
);
105 x
->mtime_client
= u64_to_xdr(mtime
);
106 x
->owner
= u64_to_xdr(0);
107 x
->group
= u64_to_xdr(0);
108 return bp
+ xdr_size(x
);
112 * Convert a signed 100ns-resolution 64-bit time into a timespec.
114 static struct timespec64
yfs_time_to_linux(s64 t
)
116 struct timespec64 ts
;
120 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
121 * the alternative, do_div, does not work with negative numbers so have
122 * to special case them
126 ts
.tv_nsec
= (time64_t
)(do_div(abs_t
, 10000000) * 100);
127 ts
.tv_nsec
= -ts
.tv_nsec
;
131 ts
.tv_nsec
= (time64_t
)do_div(abs_t
, 10000000) * 100;
138 static struct timespec64
xdr_to_time(const struct yfs_xdr_u64 xdr
)
140 s64 t
= xdr_to_u64(xdr
);
142 return yfs_time_to_linux(t
);
145 static void yfs_check_req(struct afs_call
*call
, __be32
*bp
)
147 size_t len
= (void *)bp
- call
->request
;
149 if (len
> call
->request_size
)
150 pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
151 call
->type
->name
, len
, call
->request_size
);
152 else if (len
< call
->request_size
)
153 pr_warn("kAFS: %s: Request buffer underflow (%zu<%u)\n",
154 call
->type
->name
, len
, call
->request_size
);
158 * Dump a bad file status record.
160 static void xdr_dump_bad(const __be32
*bp
)
165 pr_notice("YFS XDR: Bad status record\n");
166 for (i
= 0; i
< 6 * 4 * 4; i
+= 16) {
169 pr_notice("%03x: %08x %08x %08x %08x\n",
170 i
, ntohl(x
[0]), ntohl(x
[1]), ntohl(x
[2]), ntohl(x
[3]));
174 pr_notice("0x60: %08x %08x\n", ntohl(x
[0]), ntohl(x
[1]));
178 * Decode a YFSFetchStatus block
180 static void xdr_decode_YFSFetchStatus(const __be32
**_bp
,
181 struct afs_call
*call
,
182 struct afs_status_cb
*scb
)
184 const struct yfs_xdr_YFSFetchStatus
*xdr
= (const void *)*_bp
;
185 struct afs_file_status
*status
= &scb
->status
;
188 status
->abort_code
= ntohl(xdr
->abort_code
);
189 if (status
->abort_code
!= 0) {
190 if (status
->abort_code
== VNOVNODE
)
192 scb
->have_error
= true;
196 type
= ntohl(xdr
->type
);
200 case AFS_FTYPE_SYMLINK
:
207 status
->nlink
= ntohl(xdr
->nlink
);
208 status
->author
= xdr_to_u64(xdr
->author
);
209 status
->owner
= xdr_to_u64(xdr
->owner
);
210 status
->caller_access
= ntohl(xdr
->caller_access
); /* Ticket dependent */
211 status
->anon_access
= ntohl(xdr
->anon_access
);
212 status
->mode
= ntohl(xdr
->mode
) & S_IALLUGO
;
213 status
->group
= xdr_to_u64(xdr
->group
);
214 status
->lock_count
= ntohl(xdr
->lock_count
);
216 status
->mtime_client
= xdr_to_time(xdr
->mtime_client
);
217 status
->mtime_server
= xdr_to_time(xdr
->mtime_server
);
218 status
->size
= xdr_to_u64(xdr
->size
);
219 status
->data_version
= xdr_to_u64(xdr
->data_version
);
220 scb
->have_status
= true;
222 *_bp
+= xdr_size(xdr
);
227 afs_protocol_error(call
, afs_eproto_bad_status
);
232 * Decode a YFSCallBack block
234 static void xdr_decode_YFSCallBack(const __be32
**_bp
,
235 struct afs_call
*call
,
236 struct afs_status_cb
*scb
)
238 struct yfs_xdr_YFSCallBack
*x
= (void *)*_bp
;
239 struct afs_callback
*cb
= &scb
->callback
;
242 cb_expiry
= call
->reply_time
;
243 cb_expiry
= ktime_add(cb_expiry
, xdr_to_u64(x
->expiration_time
) * 100);
244 cb
->expires_at
= ktime_divns(cb_expiry
, NSEC_PER_SEC
);
250 * Decode a YFSVolSync block
252 static void xdr_decode_YFSVolSync(const __be32
**_bp
,
253 struct afs_volsync
*volsync
)
255 struct yfs_xdr_YFSVolSync
*x
= (void *)*_bp
;
259 creation
= xdr_to_u64(x
->vol_creation_date
);
260 do_div(creation
, 10 * 1000 * 1000);
261 volsync
->creation
= creation
;
268 * Encode the requested attributes into a YFSStoreStatus block
270 static __be32
*xdr_encode_YFS_StoreStatus(__be32
*bp
, struct iattr
*attr
)
272 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
273 s64 mtime
= 0, owner
= 0, group
= 0;
274 u32 mask
= 0, mode
= 0;
277 if (attr
->ia_valid
& ATTR_MTIME
) {
278 mask
|= AFS_SET_MTIME
;
279 mtime
= linux_to_yfs_time(&attr
->ia_mtime
);
282 if (attr
->ia_valid
& ATTR_UID
) {
283 mask
|= AFS_SET_OWNER
;
284 owner
= from_kuid(&init_user_ns
, attr
->ia_uid
);
287 if (attr
->ia_valid
& ATTR_GID
) {
288 mask
|= AFS_SET_GROUP
;
289 group
= from_kgid(&init_user_ns
, attr
->ia_gid
);
292 if (attr
->ia_valid
& ATTR_MODE
) {
293 mask
|= AFS_SET_MODE
;
294 mode
= attr
->ia_mode
& S_IALLUGO
;
297 x
->mask
= htonl(mask
);
298 x
->mode
= htonl(mode
);
299 x
->mtime_client
= u64_to_xdr(mtime
);
300 x
->owner
= u64_to_xdr(owner
);
301 x
->group
= u64_to_xdr(group
);
302 return bp
+ xdr_size(x
);
306 * Decode a YFSFetchVolumeStatus block.
308 static void xdr_decode_YFSFetchVolumeStatus(const __be32
**_bp
,
309 struct afs_volume_status
*vs
)
311 const struct yfs_xdr_YFSFetchVolumeStatus
*x
= (const void *)*_bp
;
314 vs
->vid
= xdr_to_u64(x
->vid
);
315 vs
->parent_id
= xdr_to_u64(x
->parent_id
);
316 flags
= ntohl(x
->flags
);
317 vs
->online
= flags
& yfs_FVSOnline
;
318 vs
->in_service
= flags
& yfs_FVSInservice
;
319 vs
->blessed
= flags
& yfs_FVSBlessed
;
320 vs
->needs_salvage
= flags
& yfs_FVSNeedsSalvage
;
321 vs
->type
= ntohl(x
->type
);
323 vs
->max_quota
= xdr_to_u64(x
->max_quota
);
324 vs
->blocks_in_use
= xdr_to_u64(x
->blocks_in_use
);
325 vs
->part_blocks_avail
= xdr_to_u64(x
->part_blocks_avail
);
326 vs
->part_max_blocks
= xdr_to_u64(x
->part_max_blocks
);
327 vs
->vol_copy_date
= xdr_to_u64(x
->vol_copy_date
);
328 vs
->vol_backup_date
= xdr_to_u64(x
->vol_backup_date
);
329 *_bp
+= sizeof(*x
) / sizeof(__be32
);
333 * Deliver reply data to operations that just return a file status and a volume
336 static int yfs_deliver_status_and_volsync(struct afs_call
*call
)
338 struct afs_operation
*op
= call
->op
;
342 ret
= afs_transfer_reply(call
);
347 xdr_decode_YFSFetchStatus(&bp
, call
, &op
->file
[0].scb
);
348 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
350 _leave(" = 0 [done]");
355 * Deliver reply data to an YFS.FetchData64.
357 static int yfs_deliver_fs_fetch_data64(struct afs_call
*call
)
359 struct afs_operation
*op
= call
->op
;
360 struct afs_vnode_param
*vp
= &op
->file
[0];
361 struct afs_read
*req
= op
->fetch
.req
;
366 _enter("{%u,%zu/%llu}",
367 call
->unmarshall
, iov_iter_count(call
->iter
), req
->actual_len
);
369 switch (call
->unmarshall
) {
373 req
->offset
= req
->pos
& (PAGE_SIZE
- 1);
374 afs_extract_to_tmp64(call
);
378 /* extract the returned data length */
380 _debug("extract data length");
381 ret
= afs_extract_data(call
, true);
385 req
->actual_len
= be64_to_cpu(call
->tmp64
);
386 _debug("DATA length: %llu", req
->actual_len
);
387 req
->remain
= min(req
->len
, req
->actual_len
);
388 if (req
->remain
== 0)
394 ASSERTCMP(req
->index
, <, req
->nr_pages
);
395 if (req
->remain
> PAGE_SIZE
- req
->offset
)
396 size
= PAGE_SIZE
- req
->offset
;
399 call
->bvec
[0].bv_len
= size
;
400 call
->bvec
[0].bv_offset
= req
->offset
;
401 call
->bvec
[0].bv_page
= req
->pages
[req
->index
];
402 iov_iter_bvec(&call
->def_iter
, READ
, call
->bvec
, 1, size
);
403 ASSERTCMP(size
, <=, PAGE_SIZE
);
406 /* extract the returned data */
408 _debug("extract data %zu/%llu",
409 iov_iter_count(call
->iter
), req
->remain
);
411 ret
= afs_extract_data(call
, true);
414 req
->remain
-= call
->bvec
[0].bv_len
;
415 req
->offset
+= call
->bvec
[0].bv_len
;
416 ASSERTCMP(req
->offset
, <=, PAGE_SIZE
);
417 if (req
->offset
== PAGE_SIZE
) {
424 ASSERTCMP(req
->remain
, ==, 0);
425 if (req
->actual_len
<= req
->len
)
428 /* Discard any excess data the server gave us */
429 afs_extract_discard(call
, req
->actual_len
- req
->len
);
430 call
->unmarshall
= 3;
434 _debug("extract discard %zu/%llu",
435 iov_iter_count(call
->iter
), req
->actual_len
- req
->len
);
437 ret
= afs_extract_data(call
, true);
442 call
->unmarshall
= 4;
443 afs_extract_to_buf(call
,
444 sizeof(struct yfs_xdr_YFSFetchStatus
) +
445 sizeof(struct yfs_xdr_YFSCallBack
) +
446 sizeof(struct yfs_xdr_YFSVolSync
));
449 /* extract the metadata */
451 ret
= afs_extract_data(call
, false);
456 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
457 xdr_decode_YFSCallBack(&bp
, call
, &vp
->scb
);
458 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
460 req
->data_version
= vp
->scb
.status
.data_version
;
461 req
->file_size
= vp
->scb
.status
.size
;
470 for (; req
->index
< req
->nr_pages
; req
->index
++) {
471 if (req
->offset
< PAGE_SIZE
)
472 zero_user_segment(req
->pages
[req
->index
],
473 req
->offset
, PAGE_SIZE
);
478 for (req
->index
= 0; req
->index
< req
->nr_pages
; req
->index
++)
481 _leave(" = 0 [done]");
486 * YFS.FetchData64 operation type
488 static const struct afs_call_type yfs_RXYFSFetchData64
= {
489 .name
= "YFS.FetchData64",
490 .op
= yfs_FS_FetchData64
,
491 .deliver
= yfs_deliver_fs_fetch_data64
,
492 .destructor
= afs_flat_call_destructor
,
496 * Fetch data from a file.
498 void yfs_fs_fetch_data(struct afs_operation
*op
)
500 struct afs_vnode_param
*vp
= &op
->file
[0];
501 struct afs_read
*req
= op
->fetch
.req
;
502 struct afs_call
*call
;
505 _enter(",%x,{%llx:%llu},%llx,%llx",
506 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
,
509 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSFetchData64
,
511 sizeof(struct yfs_xdr_YFSFid
) +
512 sizeof(struct yfs_xdr_u64
) * 2,
513 sizeof(struct yfs_xdr_YFSFetchStatus
) +
514 sizeof(struct yfs_xdr_YFSCallBack
) +
515 sizeof(struct yfs_xdr_YFSVolSync
));
517 return afs_op_nomem(op
);
519 /* marshall the parameters */
521 bp
= xdr_encode_u32(bp
, YFSFETCHDATA64
);
522 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
523 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
524 bp
= xdr_encode_u64(bp
, req
->pos
);
525 bp
= xdr_encode_u64(bp
, req
->len
);
526 yfs_check_req(call
, bp
);
528 trace_afs_make_fs_call(call
, &vp
->fid
);
529 afs_make_op_call(op
, call
, GFP_NOFS
);
533 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
535 static int yfs_deliver_fs_create_vnode(struct afs_call
*call
)
537 struct afs_operation
*op
= call
->op
;
538 struct afs_vnode_param
*dvp
= &op
->file
[0];
539 struct afs_vnode_param
*vp
= &op
->file
[1];
543 _enter("{%u}", call
->unmarshall
);
545 ret
= afs_transfer_reply(call
);
549 /* unmarshall the reply once we've received all of it */
551 xdr_decode_YFSFid(&bp
, &op
->file
[1].fid
);
552 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
553 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
554 xdr_decode_YFSCallBack(&bp
, call
, &vp
->scb
);
555 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
557 _leave(" = 0 [done]");
562 * FS.CreateFile and FS.MakeDir operation type
564 static const struct afs_call_type afs_RXFSCreateFile
= {
565 .name
= "YFS.CreateFile",
566 .op
= yfs_FS_CreateFile
,
567 .deliver
= yfs_deliver_fs_create_vnode
,
568 .destructor
= afs_flat_call_destructor
,
574 void yfs_fs_create_file(struct afs_operation
*op
)
576 const struct qstr
*name
= &op
->dentry
->d_name
;
577 struct afs_vnode_param
*dvp
= &op
->file
[0];
578 struct afs_call
*call
;
584 reqsz
= (sizeof(__be32
) +
586 sizeof(struct yfs_xdr_YFSFid
) +
587 xdr_strlen(name
->len
) +
588 sizeof(struct yfs_xdr_YFSStoreStatus
) +
590 rplsz
= (sizeof(struct yfs_xdr_YFSFid
) +
591 sizeof(struct yfs_xdr_YFSFetchStatus
) +
592 sizeof(struct yfs_xdr_YFSFetchStatus
) +
593 sizeof(struct yfs_xdr_YFSCallBack
) +
594 sizeof(struct yfs_xdr_YFSVolSync
));
596 call
= afs_alloc_flat_call(op
->net
, &afs_RXFSCreateFile
, reqsz
, rplsz
);
598 return afs_op_nomem(op
);
600 /* marshall the parameters */
602 bp
= xdr_encode_u32(bp
, YFSCREATEFILE
);
603 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
604 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
605 bp
= xdr_encode_name(bp
, name
);
606 bp
= xdr_encode_YFSStoreStatus_mode(bp
, op
->create
.mode
);
607 bp
= xdr_encode_u32(bp
, yfs_LockNone
); /* ViceLockType */
608 yfs_check_req(call
, bp
);
610 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
611 afs_make_op_call(op
, call
, GFP_NOFS
);
614 static const struct afs_call_type yfs_RXFSMakeDir
= {
615 .name
= "YFS.MakeDir",
616 .op
= yfs_FS_MakeDir
,
617 .deliver
= yfs_deliver_fs_create_vnode
,
618 .destructor
= afs_flat_call_destructor
,
624 void yfs_fs_make_dir(struct afs_operation
*op
)
626 const struct qstr
*name
= &op
->dentry
->d_name
;
627 struct afs_vnode_param
*dvp
= &op
->file
[0];
628 struct afs_call
*call
;
634 reqsz
= (sizeof(__be32
) +
635 sizeof(struct yfs_xdr_RPCFlags
) +
636 sizeof(struct yfs_xdr_YFSFid
) +
637 xdr_strlen(name
->len
) +
638 sizeof(struct yfs_xdr_YFSStoreStatus
));
639 rplsz
= (sizeof(struct yfs_xdr_YFSFid
) +
640 sizeof(struct yfs_xdr_YFSFetchStatus
) +
641 sizeof(struct yfs_xdr_YFSFetchStatus
) +
642 sizeof(struct yfs_xdr_YFSCallBack
) +
643 sizeof(struct yfs_xdr_YFSVolSync
));
645 call
= afs_alloc_flat_call(op
->net
, &yfs_RXFSMakeDir
, reqsz
, rplsz
);
647 return afs_op_nomem(op
);
649 /* marshall the parameters */
651 bp
= xdr_encode_u32(bp
, YFSMAKEDIR
);
652 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
653 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
654 bp
= xdr_encode_name(bp
, name
);
655 bp
= xdr_encode_YFSStoreStatus_mode(bp
, op
->create
.mode
);
656 yfs_check_req(call
, bp
);
658 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
659 afs_make_op_call(op
, call
, GFP_NOFS
);
663 * Deliver reply data to a YFS.RemoveFile2 operation.
665 static int yfs_deliver_fs_remove_file2(struct afs_call
*call
)
667 struct afs_operation
*op
= call
->op
;
668 struct afs_vnode_param
*dvp
= &op
->file
[0];
669 struct afs_vnode_param
*vp
= &op
->file
[1];
674 _enter("{%u}", call
->unmarshall
);
676 ret
= afs_transfer_reply(call
);
681 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
682 xdr_decode_YFSFid(&bp
, &fid
);
683 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
684 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
686 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
690 static void yfs_done_fs_remove_file2(struct afs_call
*call
)
692 if (call
->error
== -ECONNABORTED
&&
693 call
->abort_code
== RX_INVALID_OPERATION
) {
694 set_bit(AFS_SERVER_FL_NO_RM2
, &call
->server
->flags
);
695 call
->op
->flags
|= AFS_OPERATION_DOWNGRADE
;
700 * YFS.RemoveFile2 operation type.
702 static const struct afs_call_type yfs_RXYFSRemoveFile2
= {
703 .name
= "YFS.RemoveFile2",
704 .op
= yfs_FS_RemoveFile2
,
705 .deliver
= yfs_deliver_fs_remove_file2
,
706 .done
= yfs_done_fs_remove_file2
,
707 .destructor
= afs_flat_call_destructor
,
711 * Remove a file and retrieve new file status.
713 void yfs_fs_remove_file2(struct afs_operation
*op
)
715 struct afs_vnode_param
*dvp
= &op
->file
[0];
716 const struct qstr
*name
= &op
->dentry
->d_name
;
717 struct afs_call
*call
;
722 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRemoveFile2
,
724 sizeof(struct yfs_xdr_RPCFlags
) +
725 sizeof(struct yfs_xdr_YFSFid
) +
726 xdr_strlen(name
->len
),
727 sizeof(struct yfs_xdr_YFSFetchStatus
) +
728 sizeof(struct yfs_xdr_YFSFid
) +
729 sizeof(struct yfs_xdr_YFSFetchStatus
) +
730 sizeof(struct yfs_xdr_YFSVolSync
));
732 return afs_op_nomem(op
);
734 /* marshall the parameters */
736 bp
= xdr_encode_u32(bp
, YFSREMOVEFILE2
);
737 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
738 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
739 bp
= xdr_encode_name(bp
, name
);
740 yfs_check_req(call
, bp
);
742 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
743 afs_make_op_call(op
, call
, GFP_NOFS
);
747 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
749 static int yfs_deliver_fs_remove(struct afs_call
*call
)
751 struct afs_operation
*op
= call
->op
;
752 struct afs_vnode_param
*dvp
= &op
->file
[0];
756 _enter("{%u}", call
->unmarshall
);
758 ret
= afs_transfer_reply(call
);
763 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
764 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
769 * FS.RemoveDir and FS.RemoveFile operation types.
771 static const struct afs_call_type yfs_RXYFSRemoveFile
= {
772 .name
= "YFS.RemoveFile",
773 .op
= yfs_FS_RemoveFile
,
774 .deliver
= yfs_deliver_fs_remove
,
775 .destructor
= afs_flat_call_destructor
,
781 void yfs_fs_remove_file(struct afs_operation
*op
)
783 const struct qstr
*name
= &op
->dentry
->d_name
;
784 struct afs_vnode_param
*dvp
= &op
->file
[0];
785 struct afs_call
*call
;
790 if (!test_bit(AFS_SERVER_FL_NO_RM2
, &op
->server
->flags
))
791 return yfs_fs_remove_file2(op
);
793 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRemoveFile
,
795 sizeof(struct yfs_xdr_RPCFlags
) +
796 sizeof(struct yfs_xdr_YFSFid
) +
797 xdr_strlen(name
->len
),
798 sizeof(struct yfs_xdr_YFSFetchStatus
) +
799 sizeof(struct yfs_xdr_YFSVolSync
));
801 return afs_op_nomem(op
);
803 /* marshall the parameters */
805 bp
= xdr_encode_u32(bp
, YFSREMOVEFILE
);
806 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
807 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
808 bp
= xdr_encode_name(bp
, name
);
809 yfs_check_req(call
, bp
);
811 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
812 afs_make_op_call(op
, call
, GFP_NOFS
);
815 static const struct afs_call_type yfs_RXYFSRemoveDir
= {
816 .name
= "YFS.RemoveDir",
817 .op
= yfs_FS_RemoveDir
,
818 .deliver
= yfs_deliver_fs_remove
,
819 .destructor
= afs_flat_call_destructor
,
823 * Remove a directory.
825 void yfs_fs_remove_dir(struct afs_operation
*op
)
827 const struct qstr
*name
= &op
->dentry
->d_name
;
828 struct afs_vnode_param
*dvp
= &op
->file
[0];
829 struct afs_call
*call
;
834 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRemoveDir
,
836 sizeof(struct yfs_xdr_RPCFlags
) +
837 sizeof(struct yfs_xdr_YFSFid
) +
838 xdr_strlen(name
->len
),
839 sizeof(struct yfs_xdr_YFSFetchStatus
) +
840 sizeof(struct yfs_xdr_YFSVolSync
));
842 return afs_op_nomem(op
);
844 /* marshall the parameters */
846 bp
= xdr_encode_u32(bp
, YFSREMOVEDIR
);
847 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
848 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
849 bp
= xdr_encode_name(bp
, name
);
850 yfs_check_req(call
, bp
);
852 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
853 afs_make_op_call(op
, call
, GFP_NOFS
);
857 * Deliver reply data to a YFS.Link operation.
859 static int yfs_deliver_fs_link(struct afs_call
*call
)
861 struct afs_operation
*op
= call
->op
;
862 struct afs_vnode_param
*dvp
= &op
->file
[0];
863 struct afs_vnode_param
*vp
= &op
->file
[1];
867 _enter("{%u}", call
->unmarshall
);
869 ret
= afs_transfer_reply(call
);
874 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
875 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
876 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
877 _leave(" = 0 [done]");
882 * YFS.Link operation type.
884 static const struct afs_call_type yfs_RXYFSLink
= {
887 .deliver
= yfs_deliver_fs_link
,
888 .destructor
= afs_flat_call_destructor
,
894 void yfs_fs_link(struct afs_operation
*op
)
896 const struct qstr
*name
= &op
->dentry
->d_name
;
897 struct afs_vnode_param
*dvp
= &op
->file
[0];
898 struct afs_vnode_param
*vp
= &op
->file
[1];
899 struct afs_call
*call
;
904 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSLink
,
906 sizeof(struct yfs_xdr_RPCFlags
) +
907 sizeof(struct yfs_xdr_YFSFid
) +
908 xdr_strlen(name
->len
) +
909 sizeof(struct yfs_xdr_YFSFid
),
910 sizeof(struct yfs_xdr_YFSFetchStatus
) +
911 sizeof(struct yfs_xdr_YFSFetchStatus
) +
912 sizeof(struct yfs_xdr_YFSVolSync
));
914 return afs_op_nomem(op
);
916 /* marshall the parameters */
918 bp
= xdr_encode_u32(bp
, YFSLINK
);
919 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
920 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
921 bp
= xdr_encode_name(bp
, name
);
922 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
923 yfs_check_req(call
, bp
);
925 trace_afs_make_fs_call1(call
, &vp
->fid
, name
);
926 afs_make_op_call(op
, call
, GFP_NOFS
);
930 * Deliver reply data to a YFS.Symlink operation.
932 static int yfs_deliver_fs_symlink(struct afs_call
*call
)
934 struct afs_operation
*op
= call
->op
;
935 struct afs_vnode_param
*dvp
= &op
->file
[0];
936 struct afs_vnode_param
*vp
= &op
->file
[1];
940 _enter("{%u}", call
->unmarshall
);
942 ret
= afs_transfer_reply(call
);
946 /* unmarshall the reply once we've received all of it */
948 xdr_decode_YFSFid(&bp
, &vp
->fid
);
949 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
950 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
951 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
953 _leave(" = 0 [done]");
958 * YFS.Symlink operation type
960 static const struct afs_call_type yfs_RXYFSSymlink
= {
961 .name
= "YFS.Symlink",
962 .op
= yfs_FS_Symlink
,
963 .deliver
= yfs_deliver_fs_symlink
,
964 .destructor
= afs_flat_call_destructor
,
968 * Create a symbolic link.
970 void yfs_fs_symlink(struct afs_operation
*op
)
972 const struct qstr
*name
= &op
->dentry
->d_name
;
973 struct afs_vnode_param
*dvp
= &op
->file
[0];
974 struct afs_call
*call
;
980 contents_sz
= strlen(op
->create
.symlink
);
981 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSSymlink
,
983 sizeof(struct yfs_xdr_RPCFlags
) +
984 sizeof(struct yfs_xdr_YFSFid
) +
985 xdr_strlen(name
->len
) +
986 xdr_strlen(contents_sz
) +
987 sizeof(struct yfs_xdr_YFSStoreStatus
),
988 sizeof(struct yfs_xdr_YFSFid
) +
989 sizeof(struct yfs_xdr_YFSFetchStatus
) +
990 sizeof(struct yfs_xdr_YFSFetchStatus
) +
991 sizeof(struct yfs_xdr_YFSVolSync
));
993 return afs_op_nomem(op
);
995 /* marshall the parameters */
997 bp
= xdr_encode_u32(bp
, YFSSYMLINK
);
998 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
999 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
1000 bp
= xdr_encode_name(bp
, name
);
1001 bp
= xdr_encode_string(bp
, op
->create
.symlink
, contents_sz
);
1002 bp
= xdr_encode_YFSStoreStatus_mode(bp
, S_IRWXUGO
);
1003 yfs_check_req(call
, bp
);
1005 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
1006 afs_make_op_call(op
, call
, GFP_NOFS
);
1010 * Deliver reply data to a YFS.Rename operation.
1012 static int yfs_deliver_fs_rename(struct afs_call
*call
)
1014 struct afs_operation
*op
= call
->op
;
1015 struct afs_vnode_param
*orig_dvp
= &op
->file
[0];
1016 struct afs_vnode_param
*new_dvp
= &op
->file
[1];
1020 _enter("{%u}", call
->unmarshall
);
1022 ret
= afs_transfer_reply(call
);
1027 /* If the two dirs are the same, we have two copies of the same status
1028 * report, so we just decode it twice.
1030 xdr_decode_YFSFetchStatus(&bp
, call
, &orig_dvp
->scb
);
1031 xdr_decode_YFSFetchStatus(&bp
, call
, &new_dvp
->scb
);
1032 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1033 _leave(" = 0 [done]");
1038 * YFS.Rename operation type
1040 static const struct afs_call_type yfs_RXYFSRename
= {
1041 .name
= "FS.Rename",
1042 .op
= yfs_FS_Rename
,
1043 .deliver
= yfs_deliver_fs_rename
,
1044 .destructor
= afs_flat_call_destructor
,
1048 * Rename a file or directory.
1050 void yfs_fs_rename(struct afs_operation
*op
)
1052 struct afs_vnode_param
*orig_dvp
= &op
->file
[0];
1053 struct afs_vnode_param
*new_dvp
= &op
->file
[1];
1054 const struct qstr
*orig_name
= &op
->dentry
->d_name
;
1055 const struct qstr
*new_name
= &op
->dentry_2
->d_name
;
1056 struct afs_call
*call
;
1061 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRename
,
1063 sizeof(struct yfs_xdr_RPCFlags
) +
1064 sizeof(struct yfs_xdr_YFSFid
) +
1065 xdr_strlen(orig_name
->len
) +
1066 sizeof(struct yfs_xdr_YFSFid
) +
1067 xdr_strlen(new_name
->len
),
1068 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1069 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1070 sizeof(struct yfs_xdr_YFSVolSync
));
1072 return afs_op_nomem(op
);
1074 /* marshall the parameters */
1076 bp
= xdr_encode_u32(bp
, YFSRENAME
);
1077 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1078 bp
= xdr_encode_YFSFid(bp
, &orig_dvp
->fid
);
1079 bp
= xdr_encode_name(bp
, orig_name
);
1080 bp
= xdr_encode_YFSFid(bp
, &new_dvp
->fid
);
1081 bp
= xdr_encode_name(bp
, new_name
);
1082 yfs_check_req(call
, bp
);
1084 trace_afs_make_fs_call2(call
, &orig_dvp
->fid
, orig_name
, new_name
);
1085 afs_make_op_call(op
, call
, GFP_NOFS
);
1089 * YFS.StoreData64 operation type.
1091 static const struct afs_call_type yfs_RXYFSStoreData64
= {
1092 .name
= "YFS.StoreData64",
1093 .op
= yfs_FS_StoreData64
,
1094 .deliver
= yfs_deliver_status_and_volsync
,
1095 .destructor
= afs_flat_call_destructor
,
1099 * Store a set of pages to a large file.
1101 void yfs_fs_store_data(struct afs_operation
*op
)
1103 struct afs_vnode_param
*vp
= &op
->file
[0];
1104 struct afs_call
*call
;
1105 loff_t size
, pos
, i_size
;
1108 _enter(",%x,{%llx:%llu},,",
1109 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1111 size
= (loff_t
)op
->store
.last_to
- (loff_t
)op
->store
.first_offset
;
1112 if (op
->store
.first
!= op
->store
.last
)
1113 size
+= (loff_t
)(op
->store
.last
- op
->store
.first
) << PAGE_SHIFT
;
1114 pos
= (loff_t
)op
->store
.first
<< PAGE_SHIFT
;
1115 pos
+= op
->store
.first_offset
;
1117 i_size
= i_size_read(&vp
->vnode
->vfs_inode
);
1118 if (pos
+ size
> i_size
)
1119 i_size
= size
+ pos
;
1121 _debug("size %llx, at %llx, i_size %llx",
1122 (unsigned long long)size
, (unsigned long long)pos
,
1123 (unsigned long long)i_size
);
1125 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreData64
,
1128 sizeof(struct yfs_xdr_YFSFid
) +
1129 sizeof(struct yfs_xdr_YFSStoreStatus
) +
1130 sizeof(struct yfs_xdr_u64
) * 3,
1131 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1132 sizeof(struct yfs_xdr_YFSVolSync
));
1134 return afs_op_nomem(op
);
1136 call
->key
= op
->key
;
1137 call
->send_pages
= true;
1139 /* marshall the parameters */
1141 bp
= xdr_encode_u32(bp
, YFSSTOREDATA64
);
1142 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1143 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1144 bp
= xdr_encode_YFSStoreStatus_mtime(bp
, &op
->mtime
);
1145 bp
= xdr_encode_u64(bp
, pos
);
1146 bp
= xdr_encode_u64(bp
, size
);
1147 bp
= xdr_encode_u64(bp
, i_size
);
1148 yfs_check_req(call
, bp
);
1150 trace_afs_make_fs_call(call
, &vp
->fid
);
1151 afs_make_op_call(op
, call
, GFP_NOFS
);
1155 * YFS.StoreStatus operation type
1157 static const struct afs_call_type yfs_RXYFSStoreStatus
= {
1158 .name
= "YFS.StoreStatus",
1159 .op
= yfs_FS_StoreStatus
,
1160 .deliver
= yfs_deliver_status_and_volsync
,
1161 .destructor
= afs_flat_call_destructor
,
1164 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status
= {
1165 .name
= "YFS.StoreData64",
1166 .op
= yfs_FS_StoreData64
,
1167 .deliver
= yfs_deliver_status_and_volsync
,
1168 .destructor
= afs_flat_call_destructor
,
1172 * Set the attributes on a file, using YFS.StoreData64 rather than
1173 * YFS.StoreStatus so as to alter the file size also.
1175 static void yfs_fs_setattr_size(struct afs_operation
*op
)
1177 struct afs_vnode_param
*vp
= &op
->file
[0];
1178 struct afs_call
*call
;
1179 struct iattr
*attr
= op
->setattr
.attr
;
1182 _enter(",%x,{%llx:%llu},,",
1183 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1185 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreData64_as_Status
,
1186 sizeof(__be32
) * 2 +
1187 sizeof(struct yfs_xdr_YFSFid
) +
1188 sizeof(struct yfs_xdr_YFSStoreStatus
) +
1189 sizeof(struct yfs_xdr_u64
) * 3,
1190 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1191 sizeof(struct yfs_xdr_YFSVolSync
));
1193 return afs_op_nomem(op
);
1195 /* marshall the parameters */
1197 bp
= xdr_encode_u32(bp
, YFSSTOREDATA64
);
1198 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1199 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1200 bp
= xdr_encode_YFS_StoreStatus(bp
, attr
);
1201 bp
= xdr_encode_u64(bp
, attr
->ia_size
); /* position of start of write */
1202 bp
= xdr_encode_u64(bp
, 0); /* size of write */
1203 bp
= xdr_encode_u64(bp
, attr
->ia_size
); /* new file length */
1204 yfs_check_req(call
, bp
);
1206 trace_afs_make_fs_call(call
, &vp
->fid
);
1207 afs_make_op_call(op
, call
, GFP_NOFS
);
1211 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1212 * file size, and YFS.StoreStatus otherwise.
1214 void yfs_fs_setattr(struct afs_operation
*op
)
1216 struct afs_vnode_param
*vp
= &op
->file
[0];
1217 struct afs_call
*call
;
1218 struct iattr
*attr
= op
->setattr
.attr
;
1221 if (attr
->ia_valid
& ATTR_SIZE
)
1222 return yfs_fs_setattr_size(op
);
1224 _enter(",%x,{%llx:%llu},,",
1225 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1227 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreStatus
,
1228 sizeof(__be32
) * 2 +
1229 sizeof(struct yfs_xdr_YFSFid
) +
1230 sizeof(struct yfs_xdr_YFSStoreStatus
),
1231 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1232 sizeof(struct yfs_xdr_YFSVolSync
));
1234 return afs_op_nomem(op
);
1236 /* marshall the parameters */
1238 bp
= xdr_encode_u32(bp
, YFSSTORESTATUS
);
1239 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1240 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1241 bp
= xdr_encode_YFS_StoreStatus(bp
, attr
);
1242 yfs_check_req(call
, bp
);
1244 trace_afs_make_fs_call(call
, &vp
->fid
);
1245 afs_make_op_call(op
, call
, GFP_NOFS
);
1249 * Deliver reply data to a YFS.GetVolumeStatus operation.
1251 static int yfs_deliver_fs_get_volume_status(struct afs_call
*call
)
1253 struct afs_operation
*op
= call
->op
;
1259 _enter("{%u}", call
->unmarshall
);
1261 switch (call
->unmarshall
) {
1264 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSFetchVolumeStatus
));
1267 /* extract the returned status record */
1269 _debug("extract status");
1270 ret
= afs_extract_data(call
, true);
1275 xdr_decode_YFSFetchVolumeStatus(&bp
, &op
->volstatus
.vs
);
1277 afs_extract_to_tmp(call
);
1280 /* extract the volume name length */
1282 ret
= afs_extract_data(call
, true);
1286 call
->count
= ntohl(call
->tmp
);
1287 _debug("volname length: %u", call
->count
);
1288 if (call
->count
>= AFSNAMEMAX
)
1289 return afs_protocol_error(call
, afs_eproto_volname_len
);
1290 size
= (call
->count
+ 3) & ~3; /* It's padded */
1291 afs_extract_to_buf(call
, size
);
1295 /* extract the volume name */
1297 _debug("extract volname");
1298 ret
= afs_extract_data(call
, true);
1304 _debug("volname '%s'", p
);
1305 afs_extract_to_tmp(call
);
1309 /* extract the offline message length */
1311 ret
= afs_extract_data(call
, true);
1315 call
->count
= ntohl(call
->tmp
);
1316 _debug("offline msg length: %u", call
->count
);
1317 if (call
->count
>= AFSNAMEMAX
)
1318 return afs_protocol_error(call
, afs_eproto_offline_msg_len
);
1319 size
= (call
->count
+ 3) & ~3; /* It's padded */
1320 afs_extract_to_buf(call
, size
);
1324 /* extract the offline message */
1326 _debug("extract offline");
1327 ret
= afs_extract_data(call
, true);
1333 _debug("offline '%s'", p
);
1335 afs_extract_to_tmp(call
);
1339 /* extract the message of the day length */
1341 ret
= afs_extract_data(call
, true);
1345 call
->count
= ntohl(call
->tmp
);
1346 _debug("motd length: %u", call
->count
);
1347 if (call
->count
>= AFSNAMEMAX
)
1348 return afs_protocol_error(call
, afs_eproto_motd_len
);
1349 size
= (call
->count
+ 3) & ~3; /* It's padded */
1350 afs_extract_to_buf(call
, size
);
1354 /* extract the message of the day */
1356 _debug("extract motd");
1357 ret
= afs_extract_data(call
, false);
1363 _debug("motd '%s'", p
);
1372 _leave(" = 0 [done]");
1377 * YFS.GetVolumeStatus operation type
1379 static const struct afs_call_type yfs_RXYFSGetVolumeStatus
= {
1380 .name
= "YFS.GetVolumeStatus",
1381 .op
= yfs_FS_GetVolumeStatus
,
1382 .deliver
= yfs_deliver_fs_get_volume_status
,
1383 .destructor
= afs_flat_call_destructor
,
1387 * fetch the status of a volume
1389 void yfs_fs_get_volume_status(struct afs_operation
*op
)
1391 struct afs_vnode_param
*vp
= &op
->file
[0];
1392 struct afs_call
*call
;
1397 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSGetVolumeStatus
,
1398 sizeof(__be32
) * 2 +
1399 sizeof(struct yfs_xdr_u64
),
1401 sizeof(struct yfs_xdr_YFSFetchVolumeStatus
) +
1405 return afs_op_nomem(op
);
1407 /* marshall the parameters */
1409 bp
= xdr_encode_u32(bp
, YFSGETVOLUMESTATUS
);
1410 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1411 bp
= xdr_encode_u64(bp
, vp
->fid
.vid
);
1412 yfs_check_req(call
, bp
);
1414 trace_afs_make_fs_call(call
, &vp
->fid
);
1415 afs_make_op_call(op
, call
, GFP_NOFS
);
1419 * YFS.SetLock operation type
1421 static const struct afs_call_type yfs_RXYFSSetLock
= {
1422 .name
= "YFS.SetLock",
1423 .op
= yfs_FS_SetLock
,
1424 .deliver
= yfs_deliver_status_and_volsync
,
1425 .done
= afs_lock_op_done
,
1426 .destructor
= afs_flat_call_destructor
,
1430 * YFS.ExtendLock operation type
1432 static const struct afs_call_type yfs_RXYFSExtendLock
= {
1433 .name
= "YFS.ExtendLock",
1434 .op
= yfs_FS_ExtendLock
,
1435 .deliver
= yfs_deliver_status_and_volsync
,
1436 .done
= afs_lock_op_done
,
1437 .destructor
= afs_flat_call_destructor
,
1441 * YFS.ReleaseLock operation type
1443 static const struct afs_call_type yfs_RXYFSReleaseLock
= {
1444 .name
= "YFS.ReleaseLock",
1445 .op
= yfs_FS_ReleaseLock
,
1446 .deliver
= yfs_deliver_status_and_volsync
,
1447 .destructor
= afs_flat_call_destructor
,
1451 * Set a lock on a file
1453 void yfs_fs_set_lock(struct afs_operation
*op
)
1455 struct afs_vnode_param
*vp
= &op
->file
[0];
1456 struct afs_call
*call
;
1461 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSSetLock
,
1462 sizeof(__be32
) * 2 +
1463 sizeof(struct yfs_xdr_YFSFid
) +
1465 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1466 sizeof(struct yfs_xdr_YFSVolSync
));
1468 return afs_op_nomem(op
);
1470 /* marshall the parameters */
1472 bp
= xdr_encode_u32(bp
, YFSSETLOCK
);
1473 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1474 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1475 bp
= xdr_encode_u32(bp
, op
->lock
.type
);
1476 yfs_check_req(call
, bp
);
1478 trace_afs_make_fs_calli(call
, &vp
->fid
, op
->lock
.type
);
1479 afs_make_op_call(op
, call
, GFP_NOFS
);
1483 * extend a lock on a file
1485 void yfs_fs_extend_lock(struct afs_operation
*op
)
1487 struct afs_vnode_param
*vp
= &op
->file
[0];
1488 struct afs_call
*call
;
1493 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSExtendLock
,
1494 sizeof(__be32
) * 2 +
1495 sizeof(struct yfs_xdr_YFSFid
),
1496 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1497 sizeof(struct yfs_xdr_YFSVolSync
));
1499 return afs_op_nomem(op
);
1501 /* marshall the parameters */
1503 bp
= xdr_encode_u32(bp
, YFSEXTENDLOCK
);
1504 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1505 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1506 yfs_check_req(call
, bp
);
1508 trace_afs_make_fs_call(call
, &vp
->fid
);
1509 afs_make_op_call(op
, call
, GFP_NOFS
);
1513 * release a lock on a file
1515 void yfs_fs_release_lock(struct afs_operation
*op
)
1517 struct afs_vnode_param
*vp
= &op
->file
[0];
1518 struct afs_call
*call
;
1523 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSReleaseLock
,
1524 sizeof(__be32
) * 2 +
1525 sizeof(struct yfs_xdr_YFSFid
),
1526 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1527 sizeof(struct yfs_xdr_YFSVolSync
));
1529 return afs_op_nomem(op
);
1531 /* marshall the parameters */
1533 bp
= xdr_encode_u32(bp
, YFSRELEASELOCK
);
1534 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1535 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1536 yfs_check_req(call
, bp
);
1538 trace_afs_make_fs_call(call
, &vp
->fid
);
1539 afs_make_op_call(op
, call
, GFP_NOFS
);
1543 * Deliver a reply to YFS.FetchStatus
1545 static int yfs_deliver_fs_fetch_status(struct afs_call
*call
)
1547 struct afs_operation
*op
= call
->op
;
1548 struct afs_vnode_param
*vp
= &op
->file
[op
->fetch_status
.which
];
1552 ret
= afs_transfer_reply(call
);
1556 /* unmarshall the reply once we've received all of it */
1558 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
1559 xdr_decode_YFSCallBack(&bp
, call
, &vp
->scb
);
1560 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1562 _leave(" = 0 [done]");
1567 * YFS.FetchStatus operation type
1569 static const struct afs_call_type yfs_RXYFSFetchStatus
= {
1570 .name
= "YFS.FetchStatus",
1571 .op
= yfs_FS_FetchStatus
,
1572 .deliver
= yfs_deliver_fs_fetch_status
,
1573 .destructor
= afs_flat_call_destructor
,
1577 * Fetch the status information for a fid without needing a vnode handle.
1579 void yfs_fs_fetch_status(struct afs_operation
*op
)
1581 struct afs_vnode_param
*vp
= &op
->file
[op
->fetch_status
.which
];
1582 struct afs_call
*call
;
1585 _enter(",%x,{%llx:%llu},,",
1586 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1588 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSFetchStatus
,
1589 sizeof(__be32
) * 2 +
1590 sizeof(struct yfs_xdr_YFSFid
),
1591 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1592 sizeof(struct yfs_xdr_YFSCallBack
) +
1593 sizeof(struct yfs_xdr_YFSVolSync
));
1595 return afs_op_nomem(op
);
1597 /* marshall the parameters */
1599 bp
= xdr_encode_u32(bp
, YFSFETCHSTATUS
);
1600 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1601 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1602 yfs_check_req(call
, bp
);
1604 trace_afs_make_fs_call(call
, &vp
->fid
);
1605 afs_make_op_call(op
, call
, GFP_NOFS
);
1609 * Deliver reply data to an YFS.InlineBulkStatus call
1611 static int yfs_deliver_fs_inline_bulk_status(struct afs_call
*call
)
1613 struct afs_operation
*op
= call
->op
;
1614 struct afs_status_cb
*scb
;
1619 _enter("{%u}", call
->unmarshall
);
1621 switch (call
->unmarshall
) {
1623 afs_extract_to_tmp(call
);
1627 /* Extract the file status count and array in two steps */
1629 _debug("extract status count");
1630 ret
= afs_extract_data(call
, true);
1634 tmp
= ntohl(call
->tmp
);
1635 _debug("status count: %u/%u", tmp
, op
->nr_files
);
1636 if (tmp
!= op
->nr_files
)
1637 return afs_protocol_error(call
, afs_eproto_ibulkst_count
);
1642 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSFetchStatus
));
1646 _debug("extract status array %u", call
->count
);
1647 ret
= afs_extract_data(call
, true);
1651 switch (call
->count
) {
1653 scb
= &op
->file
[0].scb
;
1656 scb
= &op
->file
[1].scb
;
1659 scb
= &op
->more_files
[call
->count
- 2].scb
;
1664 xdr_decode_YFSFetchStatus(&bp
, call
, scb
);
1667 if (call
->count
< op
->nr_files
)
1672 afs_extract_to_tmp(call
);
1675 /* Extract the callback count and array in two steps */
1677 _debug("extract CB count");
1678 ret
= afs_extract_data(call
, true);
1682 tmp
= ntohl(call
->tmp
);
1683 _debug("CB count: %u", tmp
);
1684 if (tmp
!= op
->nr_files
)
1685 return afs_protocol_error(call
, afs_eproto_ibulkst_cb_count
);
1689 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSCallBack
));
1693 _debug("extract CB array");
1694 ret
= afs_extract_data(call
, true);
1698 _debug("unmarshall CB array");
1699 switch (call
->count
) {
1701 scb
= &op
->file
[0].scb
;
1704 scb
= &op
->file
[1].scb
;
1707 scb
= &op
->more_files
[call
->count
- 2].scb
;
1712 xdr_decode_YFSCallBack(&bp
, call
, scb
);
1714 if (call
->count
< op
->nr_files
)
1717 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSVolSync
));
1722 ret
= afs_extract_data(call
, false);
1727 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1736 _leave(" = 0 [done]");
1741 * FS.InlineBulkStatus operation type
1743 static const struct afs_call_type yfs_RXYFSInlineBulkStatus
= {
1744 .name
= "YFS.InlineBulkStatus",
1745 .op
= yfs_FS_InlineBulkStatus
,
1746 .deliver
= yfs_deliver_fs_inline_bulk_status
,
1747 .destructor
= afs_flat_call_destructor
,
1751 * Fetch the status information for up to 1024 files
1753 void yfs_fs_inline_bulk_status(struct afs_operation
*op
)
1755 struct afs_vnode_param
*dvp
= &op
->file
[0];
1756 struct afs_vnode_param
*vp
= &op
->file
[1];
1757 struct afs_call
*call
;
1761 _enter(",%x,{%llx:%llu},%u",
1762 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
, op
->nr_files
);
1764 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSInlineBulkStatus
,
1768 sizeof(struct yfs_xdr_YFSFid
) * op
->nr_files
,
1769 sizeof(struct yfs_xdr_YFSFetchStatus
));
1771 return afs_op_nomem(op
);
1773 /* marshall the parameters */
1775 bp
= xdr_encode_u32(bp
, YFSINLINEBULKSTATUS
);
1776 bp
= xdr_encode_u32(bp
, 0); /* RPCFlags */
1777 bp
= xdr_encode_u32(bp
, op
->nr_files
);
1778 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
1779 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1780 for (i
= 0; i
< op
->nr_files
- 2; i
++)
1781 bp
= xdr_encode_YFSFid(bp
, &op
->more_files
[i
].fid
);
1782 yfs_check_req(call
, bp
);
1784 trace_afs_make_fs_call(call
, &vp
->fid
);
1785 afs_make_op_call(op
, call
, GFP_NOFS
);
1789 * Deliver reply data to an YFS.FetchOpaqueACL.
1791 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call
*call
)
1793 struct afs_operation
*op
= call
->op
;
1794 struct afs_vnode_param
*vp
= &op
->file
[0];
1795 struct yfs_acl
*yacl
= op
->yacl
;
1796 struct afs_acl
*acl
;
1801 _enter("{%u}", call
->unmarshall
);
1803 switch (call
->unmarshall
) {
1805 afs_extract_to_tmp(call
);
1809 /* Extract the file ACL length */
1811 ret
= afs_extract_data(call
, true);
1815 size
= call
->count2
= ntohl(call
->tmp
);
1816 size
= round_up(size
, 4);
1818 if (yacl
->flags
& YFS_ACL_WANT_ACL
) {
1819 acl
= kmalloc(struct_size(acl
, data
, size
), GFP_KERNEL
);
1823 acl
->size
= call
->count2
;
1824 afs_extract_begin(call
, acl
->data
, size
);
1826 afs_extract_discard(call
, size
);
1831 /* Extract the file ACL */
1833 ret
= afs_extract_data(call
, true);
1837 afs_extract_to_tmp(call
);
1841 /* Extract the volume ACL length */
1843 ret
= afs_extract_data(call
, true);
1847 size
= call
->count2
= ntohl(call
->tmp
);
1848 size
= round_up(size
, 4);
1850 if (yacl
->flags
& YFS_ACL_WANT_VOL_ACL
) {
1851 acl
= kmalloc(struct_size(acl
, data
, size
), GFP_KERNEL
);
1854 yacl
->vol_acl
= acl
;
1855 acl
->size
= call
->count2
;
1856 afs_extract_begin(call
, acl
->data
, size
);
1858 afs_extract_discard(call
, size
);
1863 /* Extract the volume ACL */
1865 ret
= afs_extract_data(call
, true);
1869 afs_extract_to_buf(call
,
1870 sizeof(__be32
) * 2 +
1871 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1872 sizeof(struct yfs_xdr_YFSVolSync
));
1876 /* extract the metadata */
1878 ret
= afs_extract_data(call
, false);
1883 yacl
->inherit_flag
= ntohl(*bp
++);
1884 yacl
->num_cleaned
= ntohl(*bp
++);
1885 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
1886 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1895 _leave(" = 0 [done]");
1899 void yfs_free_opaque_acl(struct yfs_acl
*yacl
)
1903 kfree(yacl
->vol_acl
);
1909 * YFS.FetchOpaqueACL operation type
1911 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL
= {
1912 .name
= "YFS.FetchOpaqueACL",
1913 .op
= yfs_FS_FetchOpaqueACL
,
1914 .deliver
= yfs_deliver_fs_fetch_opaque_acl
,
1915 .destructor
= afs_flat_call_destructor
,
1919 * Fetch the YFS advanced ACLs for a file.
1921 void yfs_fs_fetch_opaque_acl(struct afs_operation
*op
)
1923 struct afs_vnode_param
*vp
= &op
->file
[0];
1924 struct afs_call
*call
;
1927 _enter(",%x,{%llx:%llu},,",
1928 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1930 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSFetchOpaqueACL
,
1931 sizeof(__be32
) * 2 +
1932 sizeof(struct yfs_xdr_YFSFid
),
1933 sizeof(__be32
) * 2 +
1934 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1935 sizeof(struct yfs_xdr_YFSVolSync
));
1937 return afs_op_nomem(op
);
1939 /* marshall the parameters */
1941 bp
= xdr_encode_u32(bp
, YFSFETCHOPAQUEACL
);
1942 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1943 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1944 yfs_check_req(call
, bp
);
1946 trace_afs_make_fs_call(call
, &vp
->fid
);
1947 afs_make_op_call(op
, call
, GFP_KERNEL
);
1951 * YFS.StoreOpaqueACL2 operation type
1953 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2
= {
1954 .name
= "YFS.StoreOpaqueACL2",
1955 .op
= yfs_FS_StoreOpaqueACL2
,
1956 .deliver
= yfs_deliver_status_and_volsync
,
1957 .destructor
= afs_flat_call_destructor
,
1961 * Fetch the YFS ACL for a file.
1963 void yfs_fs_store_opaque_acl2(struct afs_operation
*op
)
1965 struct afs_vnode_param
*vp
= &op
->file
[0];
1966 struct afs_call
*call
;
1967 struct afs_acl
*acl
= op
->acl
;
1971 _enter(",%x,{%llx:%llu},,",
1972 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1974 size
= round_up(acl
->size
, 4);
1975 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreOpaqueACL2
,
1976 sizeof(__be32
) * 2 +
1977 sizeof(struct yfs_xdr_YFSFid
) +
1978 sizeof(__be32
) + size
,
1979 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1980 sizeof(struct yfs_xdr_YFSVolSync
));
1982 return afs_op_nomem(op
);
1984 /* marshall the parameters */
1986 bp
= xdr_encode_u32(bp
, YFSSTOREOPAQUEACL2
);
1987 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1988 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1989 bp
= xdr_encode_u32(bp
, acl
->size
);
1990 memcpy(bp
, acl
->data
, acl
->size
);
1991 if (acl
->size
!= size
)
1992 memset((void *)bp
+ acl
->size
, 0, size
- acl
->size
);
1993 bp
+= size
/ sizeof(__be32
);
1994 yfs_check_req(call
, bp
);
1996 trace_afs_make_fs_call(call
, &vp
->fid
);
1997 afs_make_op_call(op
, call
, GFP_KERNEL
);