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(__be32
*bp
, mode_t
*mode
,
87 const struct timespec64
*t
)
89 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
90 mode_t masked_mode
= mode
? *mode
& S_IALLUGO
: 0;
91 s64 mtime
= linux_to_yfs_time(t
);
92 u32 mask
= AFS_SET_MTIME
;
94 mask
|= mode
? AFS_SET_MODE
: 0;
96 x
->mask
= htonl(mask
);
97 x
->mode
= htonl(masked_mode
);
98 x
->mtime_client
= u64_to_xdr(mtime
);
99 x
->owner
= u64_to_xdr(0);
100 x
->group
= u64_to_xdr(0);
101 return bp
+ xdr_size(x
);
105 * Convert a signed 100ns-resolution 64-bit time into a timespec.
107 static struct timespec64
yfs_time_to_linux(s64 t
)
109 struct timespec64 ts
;
113 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
114 * the alternative, do_div, does not work with negative numbers so have
115 * to special case them
119 ts
.tv_nsec
= (time64_t
)(do_div(abs_t
, 10000000) * 100);
120 ts
.tv_nsec
= -ts
.tv_nsec
;
124 ts
.tv_nsec
= (time64_t
)do_div(abs_t
, 10000000) * 100;
131 static struct timespec64
xdr_to_time(const struct yfs_xdr_u64 xdr
)
133 s64 t
= xdr_to_u64(xdr
);
135 return yfs_time_to_linux(t
);
138 static void yfs_check_req(struct afs_call
*call
, __be32
*bp
)
140 size_t len
= (void *)bp
- call
->request
;
142 if (len
> call
->request_size
)
143 pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
144 call
->type
->name
, len
, call
->request_size
);
145 else if (len
< call
->request_size
)
146 pr_warn("kAFS: %s: Request buffer underflow (%zu<%u)\n",
147 call
->type
->name
, len
, call
->request_size
);
151 * Dump a bad file status record.
153 static void xdr_dump_bad(const __be32
*bp
)
158 pr_notice("YFS XDR: Bad status record\n");
159 for (i
= 0; i
< 6 * 4 * 4; i
+= 16) {
162 pr_notice("%03x: %08x %08x %08x %08x\n",
163 i
, ntohl(x
[0]), ntohl(x
[1]), ntohl(x
[2]), ntohl(x
[3]));
167 pr_notice("0x60: %08x %08x\n", ntohl(x
[0]), ntohl(x
[1]));
171 * Decode a YFSFetchStatus block
173 static void xdr_decode_YFSFetchStatus(const __be32
**_bp
,
174 struct afs_call
*call
,
175 struct afs_status_cb
*scb
)
177 const struct yfs_xdr_YFSFetchStatus
*xdr
= (const void *)*_bp
;
178 struct afs_file_status
*status
= &scb
->status
;
181 status
->abort_code
= ntohl(xdr
->abort_code
);
182 if (status
->abort_code
!= 0) {
183 if (status
->abort_code
== VNOVNODE
)
185 scb
->have_error
= true;
189 type
= ntohl(xdr
->type
);
193 case AFS_FTYPE_SYMLINK
:
200 status
->nlink
= ntohl(xdr
->nlink
);
201 status
->author
= xdr_to_u64(xdr
->author
);
202 status
->owner
= xdr_to_u64(xdr
->owner
);
203 status
->caller_access
= ntohl(xdr
->caller_access
); /* Ticket dependent */
204 status
->anon_access
= ntohl(xdr
->anon_access
);
205 status
->mode
= ntohl(xdr
->mode
) & S_IALLUGO
;
206 status
->group
= xdr_to_u64(xdr
->group
);
207 status
->lock_count
= ntohl(xdr
->lock_count
);
209 status
->mtime_client
= xdr_to_time(xdr
->mtime_client
);
210 status
->mtime_server
= xdr_to_time(xdr
->mtime_server
);
211 status
->size
= xdr_to_u64(xdr
->size
);
212 status
->data_version
= xdr_to_u64(xdr
->data_version
);
213 scb
->have_status
= true;
215 *_bp
+= xdr_size(xdr
);
220 afs_protocol_error(call
, afs_eproto_bad_status
);
225 * Decode a YFSCallBack block
227 static void xdr_decode_YFSCallBack(const __be32
**_bp
,
228 struct afs_call
*call
,
229 struct afs_status_cb
*scb
)
231 struct yfs_xdr_YFSCallBack
*x
= (void *)*_bp
;
232 struct afs_callback
*cb
= &scb
->callback
;
235 cb_expiry
= ktime_add(call
->issue_time
, xdr_to_u64(x
->expiration_time
) * 100);
236 cb
->expires_at
= ktime_divns(cb_expiry
, NSEC_PER_SEC
);
242 * Decode a YFSVolSync block
244 static void xdr_decode_YFSVolSync(const __be32
**_bp
,
245 struct afs_volsync
*volsync
)
247 struct yfs_xdr_YFSVolSync
*x
= (void *)*_bp
;
248 u64 creation
, update
;
251 creation
= xdr_to_u64(x
->vol_creation_date
);
252 do_div(creation
, 10 * 1000 * 1000);
253 volsync
->creation
= creation
;
254 update
= xdr_to_u64(x
->vol_update_date
);
255 do_div(update
, 10 * 1000 * 1000);
256 volsync
->update
= update
;
263 * Encode the requested attributes into a YFSStoreStatus block
265 static __be32
*xdr_encode_YFS_StoreStatus(__be32
*bp
, struct iattr
*attr
)
267 struct yfs_xdr_YFSStoreStatus
*x
= (void *)bp
;
268 s64 mtime
= 0, owner
= 0, group
= 0;
269 u32 mask
= 0, mode
= 0;
272 if (attr
->ia_valid
& ATTR_MTIME
) {
273 mask
|= AFS_SET_MTIME
;
274 mtime
= linux_to_yfs_time(&attr
->ia_mtime
);
277 if (attr
->ia_valid
& ATTR_UID
) {
278 mask
|= AFS_SET_OWNER
;
279 owner
= from_kuid(&init_user_ns
, attr
->ia_uid
);
282 if (attr
->ia_valid
& ATTR_GID
) {
283 mask
|= AFS_SET_GROUP
;
284 group
= from_kgid(&init_user_ns
, attr
->ia_gid
);
287 if (attr
->ia_valid
& ATTR_MODE
) {
288 mask
|= AFS_SET_MODE
;
289 mode
= attr
->ia_mode
& S_IALLUGO
;
292 x
->mask
= htonl(mask
);
293 x
->mode
= htonl(mode
);
294 x
->mtime_client
= u64_to_xdr(mtime
);
295 x
->owner
= u64_to_xdr(owner
);
296 x
->group
= u64_to_xdr(group
);
297 return bp
+ xdr_size(x
);
301 * Decode a YFSFetchVolumeStatus block.
303 static void xdr_decode_YFSFetchVolumeStatus(const __be32
**_bp
,
304 struct afs_volume_status
*vs
)
306 const struct yfs_xdr_YFSFetchVolumeStatus
*x
= (const void *)*_bp
;
309 vs
->vid
= xdr_to_u64(x
->vid
);
310 vs
->parent_id
= xdr_to_u64(x
->parent_id
);
311 flags
= ntohl(x
->flags
);
312 vs
->online
= flags
& yfs_FVSOnline
;
313 vs
->in_service
= flags
& yfs_FVSInservice
;
314 vs
->blessed
= flags
& yfs_FVSBlessed
;
315 vs
->needs_salvage
= flags
& yfs_FVSNeedsSalvage
;
316 vs
->type
= ntohl(x
->type
);
318 vs
->max_quota
= xdr_to_u64(x
->max_quota
);
319 vs
->blocks_in_use
= xdr_to_u64(x
->blocks_in_use
);
320 vs
->part_blocks_avail
= xdr_to_u64(x
->part_blocks_avail
);
321 vs
->part_max_blocks
= xdr_to_u64(x
->part_max_blocks
);
322 vs
->vol_copy_date
= xdr_to_u64(x
->vol_copy_date
);
323 vs
->vol_backup_date
= xdr_to_u64(x
->vol_backup_date
);
324 *_bp
+= sizeof(*x
) / sizeof(__be32
);
328 * Deliver reply data to operations that just return a file status and a volume
331 static int yfs_deliver_status_and_volsync(struct afs_call
*call
)
333 struct afs_operation
*op
= call
->op
;
337 ret
= afs_transfer_reply(call
);
342 xdr_decode_YFSFetchStatus(&bp
, call
, &op
->file
[0].scb
);
343 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
345 _leave(" = 0 [done]");
350 * Deliver reply data to an YFS.FetchData64.
352 static int yfs_deliver_fs_fetch_data64(struct afs_call
*call
)
354 struct afs_operation
*op
= call
->op
;
355 struct afs_vnode_param
*vp
= &op
->file
[0];
356 struct afs_read
*req
= op
->fetch
.req
;
361 _enter("{%u,%zu, %zu/%llu}",
362 call
->unmarshall
, call
->iov_len
, iov_iter_count(call
->iter
),
365 switch (call
->unmarshall
) {
368 afs_extract_to_tmp64(call
);
372 /* Extract the returned data length into ->actual_len. This
373 * may indicate more or less data than was requested will be
377 _debug("extract data length");
378 ret
= afs_extract_data(call
, true);
382 req
->actual_len
= be64_to_cpu(call
->tmp64
);
383 _debug("DATA length: %llu", req
->actual_len
);
385 if (req
->actual_len
== 0)
388 call
->iter
= req
->iter
;
389 call
->iov_len
= min(req
->actual_len
, req
->len
);
393 /* extract the returned data */
395 count_before
= call
->iov_len
;
396 _debug("extract data %zu/%llu", count_before
, req
->actual_len
);
398 ret
= afs_extract_data(call
, true);
400 req
->subreq
->transferred
+= count_before
- call
->iov_len
;
401 netfs_read_subreq_progress(req
->subreq
, false);
406 call
->iter
= &call
->def_iter
;
407 if (req
->actual_len
<= req
->len
)
410 /* Discard any excess data the server gave us */
411 afs_extract_discard(call
, req
->actual_len
- req
->len
);
412 call
->unmarshall
= 3;
416 _debug("extract discard %zu/%llu",
417 iov_iter_count(call
->iter
), req
->actual_len
- req
->len
);
419 ret
= afs_extract_data(call
, true);
424 call
->unmarshall
= 4;
425 afs_extract_to_buf(call
,
426 sizeof(struct yfs_xdr_YFSFetchStatus
) +
427 sizeof(struct yfs_xdr_YFSCallBack
) +
428 sizeof(struct yfs_xdr_YFSVolSync
));
431 /* extract the metadata */
433 ret
= afs_extract_data(call
, false);
438 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
439 xdr_decode_YFSCallBack(&bp
, call
, &vp
->scb
);
440 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
442 req
->data_version
= vp
->scb
.status
.data_version
;
443 req
->file_size
= vp
->scb
.status
.size
;
452 _leave(" = 0 [done]");
457 * YFS.FetchData64 operation type
459 static const struct afs_call_type yfs_RXYFSFetchData64
= {
460 .name
= "YFS.FetchData64",
461 .op
= yfs_FS_FetchData64
,
462 .deliver
= yfs_deliver_fs_fetch_data64
,
463 .destructor
= afs_flat_call_destructor
,
467 * Fetch data from a file.
469 void yfs_fs_fetch_data(struct afs_operation
*op
)
471 struct afs_vnode_param
*vp
= &op
->file
[0];
472 struct afs_read
*req
= op
->fetch
.req
;
473 struct afs_call
*call
;
476 _enter(",%x,{%llx:%llu},%llx,%llx",
477 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
,
480 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSFetchData64
,
482 sizeof(struct yfs_xdr_YFSFid
) +
483 sizeof(struct yfs_xdr_u64
) * 2,
484 sizeof(struct yfs_xdr_YFSFetchStatus
) +
485 sizeof(struct yfs_xdr_YFSCallBack
) +
486 sizeof(struct yfs_xdr_YFSVolSync
));
488 return afs_op_nomem(op
);
490 req
->call_debug_id
= call
->debug_id
;
492 /* marshall the parameters */
494 bp
= xdr_encode_u32(bp
, YFSFETCHDATA64
);
495 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
496 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
497 bp
= xdr_encode_u64(bp
, req
->pos
);
498 bp
= xdr_encode_u64(bp
, req
->len
);
499 yfs_check_req(call
, bp
);
502 trace_afs_make_fs_call(call
, &vp
->fid
);
503 afs_make_op_call(op
, call
, GFP_NOFS
);
507 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
509 static int yfs_deliver_fs_create_vnode(struct afs_call
*call
)
511 struct afs_operation
*op
= call
->op
;
512 struct afs_vnode_param
*dvp
= &op
->file
[0];
513 struct afs_vnode_param
*vp
= &op
->file
[1];
517 _enter("{%u}", call
->unmarshall
);
519 ret
= afs_transfer_reply(call
);
523 /* unmarshall the reply once we've received all of it */
525 xdr_decode_YFSFid(&bp
, &op
->file
[1].fid
);
526 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
527 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
528 xdr_decode_YFSCallBack(&bp
, call
, &vp
->scb
);
529 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
531 _leave(" = 0 [done]");
536 * FS.CreateFile and FS.MakeDir operation type
538 static const struct afs_call_type afs_RXFSCreateFile
= {
539 .name
= "YFS.CreateFile",
540 .op
= yfs_FS_CreateFile
,
541 .deliver
= yfs_deliver_fs_create_vnode
,
542 .destructor
= afs_flat_call_destructor
,
548 void yfs_fs_create_file(struct afs_operation
*op
)
550 const struct qstr
*name
= &op
->dentry
->d_name
;
551 struct afs_vnode_param
*dvp
= &op
->file
[0];
552 struct afs_call
*call
;
558 reqsz
= (sizeof(__be32
) +
560 sizeof(struct yfs_xdr_YFSFid
) +
561 xdr_strlen(name
->len
) +
562 sizeof(struct yfs_xdr_YFSStoreStatus
) +
564 rplsz
= (sizeof(struct yfs_xdr_YFSFid
) +
565 sizeof(struct yfs_xdr_YFSFetchStatus
) +
566 sizeof(struct yfs_xdr_YFSFetchStatus
) +
567 sizeof(struct yfs_xdr_YFSCallBack
) +
568 sizeof(struct yfs_xdr_YFSVolSync
));
570 call
= afs_alloc_flat_call(op
->net
, &afs_RXFSCreateFile
, reqsz
, rplsz
);
572 return afs_op_nomem(op
);
574 /* marshall the parameters */
576 bp
= xdr_encode_u32(bp
, YFSCREATEFILE
);
577 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
578 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
579 bp
= xdr_encode_name(bp
, name
);
580 bp
= xdr_encode_YFSStoreStatus(bp
, &op
->create
.mode
, &op
->mtime
);
581 bp
= xdr_encode_u32(bp
, yfs_LockNone
); /* ViceLockType */
582 yfs_check_req(call
, bp
);
584 call
->fid
= dvp
->fid
;
585 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
586 afs_make_op_call(op
, call
, GFP_NOFS
);
589 static const struct afs_call_type yfs_RXFSMakeDir
= {
590 .name
= "YFS.MakeDir",
591 .op
= yfs_FS_MakeDir
,
592 .deliver
= yfs_deliver_fs_create_vnode
,
593 .destructor
= afs_flat_call_destructor
,
599 void yfs_fs_make_dir(struct afs_operation
*op
)
601 const struct qstr
*name
= &op
->dentry
->d_name
;
602 struct afs_vnode_param
*dvp
= &op
->file
[0];
603 struct afs_call
*call
;
609 reqsz
= (sizeof(__be32
) +
610 sizeof(struct yfs_xdr_RPCFlags
) +
611 sizeof(struct yfs_xdr_YFSFid
) +
612 xdr_strlen(name
->len
) +
613 sizeof(struct yfs_xdr_YFSStoreStatus
));
614 rplsz
= (sizeof(struct yfs_xdr_YFSFid
) +
615 sizeof(struct yfs_xdr_YFSFetchStatus
) +
616 sizeof(struct yfs_xdr_YFSFetchStatus
) +
617 sizeof(struct yfs_xdr_YFSCallBack
) +
618 sizeof(struct yfs_xdr_YFSVolSync
));
620 call
= afs_alloc_flat_call(op
->net
, &yfs_RXFSMakeDir
, reqsz
, rplsz
);
622 return afs_op_nomem(op
);
624 /* marshall the parameters */
626 bp
= xdr_encode_u32(bp
, YFSMAKEDIR
);
627 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
628 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
629 bp
= xdr_encode_name(bp
, name
);
630 bp
= xdr_encode_YFSStoreStatus(bp
, &op
->create
.mode
, &op
->mtime
);
631 yfs_check_req(call
, bp
);
633 call
->fid
= dvp
->fid
;
634 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
635 afs_make_op_call(op
, call
, GFP_NOFS
);
639 * Deliver reply data to a YFS.RemoveFile2 operation.
641 static int yfs_deliver_fs_remove_file2(struct afs_call
*call
)
643 struct afs_operation
*op
= call
->op
;
644 struct afs_vnode_param
*dvp
= &op
->file
[0];
645 struct afs_vnode_param
*vp
= &op
->file
[1];
650 _enter("{%u}", call
->unmarshall
);
652 ret
= afs_transfer_reply(call
);
657 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
658 xdr_decode_YFSFid(&bp
, &fid
);
659 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
660 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
662 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
666 static void yfs_done_fs_remove_file2(struct afs_call
*call
)
668 if (call
->error
== -ECONNABORTED
&&
669 call
->abort_code
== RX_INVALID_OPERATION
) {
670 set_bit(AFS_SERVER_FL_NO_RM2
, &call
->server
->flags
);
671 call
->op
->flags
|= AFS_OPERATION_DOWNGRADE
;
676 * YFS.RemoveFile2 operation type.
678 static const struct afs_call_type yfs_RXYFSRemoveFile2
= {
679 .name
= "YFS.RemoveFile2",
680 .op
= yfs_FS_RemoveFile2
,
681 .deliver
= yfs_deliver_fs_remove_file2
,
682 .done
= yfs_done_fs_remove_file2
,
683 .destructor
= afs_flat_call_destructor
,
687 * Remove a file and retrieve new file status.
689 void yfs_fs_remove_file2(struct afs_operation
*op
)
691 struct afs_vnode_param
*dvp
= &op
->file
[0];
692 const struct qstr
*name
= &op
->dentry
->d_name
;
693 struct afs_call
*call
;
698 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRemoveFile2
,
700 sizeof(struct yfs_xdr_RPCFlags
) +
701 sizeof(struct yfs_xdr_YFSFid
) +
702 xdr_strlen(name
->len
),
703 sizeof(struct yfs_xdr_YFSFetchStatus
) +
704 sizeof(struct yfs_xdr_YFSFid
) +
705 sizeof(struct yfs_xdr_YFSFetchStatus
) +
706 sizeof(struct yfs_xdr_YFSVolSync
));
708 return afs_op_nomem(op
);
710 /* marshall the parameters */
712 bp
= xdr_encode_u32(bp
, YFSREMOVEFILE2
);
713 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
714 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
715 bp
= xdr_encode_name(bp
, name
);
716 yfs_check_req(call
, bp
);
718 call
->fid
= dvp
->fid
;
719 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
720 afs_make_op_call(op
, call
, GFP_NOFS
);
724 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
726 static int yfs_deliver_fs_remove(struct afs_call
*call
)
728 struct afs_operation
*op
= call
->op
;
729 struct afs_vnode_param
*dvp
= &op
->file
[0];
733 _enter("{%u}", call
->unmarshall
);
735 ret
= afs_transfer_reply(call
);
740 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
741 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
746 * FS.RemoveDir and FS.RemoveFile operation types.
748 static const struct afs_call_type yfs_RXYFSRemoveFile
= {
749 .name
= "YFS.RemoveFile",
750 .op
= yfs_FS_RemoveFile
,
751 .deliver
= yfs_deliver_fs_remove
,
752 .destructor
= afs_flat_call_destructor
,
758 void yfs_fs_remove_file(struct afs_operation
*op
)
760 const struct qstr
*name
= &op
->dentry
->d_name
;
761 struct afs_vnode_param
*dvp
= &op
->file
[0];
762 struct afs_call
*call
;
767 if (!test_bit(AFS_SERVER_FL_NO_RM2
, &op
->server
->flags
))
768 return yfs_fs_remove_file2(op
);
770 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRemoveFile
,
772 sizeof(struct yfs_xdr_RPCFlags
) +
773 sizeof(struct yfs_xdr_YFSFid
) +
774 xdr_strlen(name
->len
),
775 sizeof(struct yfs_xdr_YFSFetchStatus
) +
776 sizeof(struct yfs_xdr_YFSVolSync
));
778 return afs_op_nomem(op
);
780 /* marshall the parameters */
782 bp
= xdr_encode_u32(bp
, YFSREMOVEFILE
);
783 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
784 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
785 bp
= xdr_encode_name(bp
, name
);
786 yfs_check_req(call
, bp
);
788 call
->fid
= dvp
->fid
;
789 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
790 afs_make_op_call(op
, call
, GFP_NOFS
);
793 static const struct afs_call_type yfs_RXYFSRemoveDir
= {
794 .name
= "YFS.RemoveDir",
795 .op
= yfs_FS_RemoveDir
,
796 .deliver
= yfs_deliver_fs_remove
,
797 .destructor
= afs_flat_call_destructor
,
801 * Remove a directory.
803 void yfs_fs_remove_dir(struct afs_operation
*op
)
805 const struct qstr
*name
= &op
->dentry
->d_name
;
806 struct afs_vnode_param
*dvp
= &op
->file
[0];
807 struct afs_call
*call
;
812 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRemoveDir
,
814 sizeof(struct yfs_xdr_RPCFlags
) +
815 sizeof(struct yfs_xdr_YFSFid
) +
816 xdr_strlen(name
->len
),
817 sizeof(struct yfs_xdr_YFSFetchStatus
) +
818 sizeof(struct yfs_xdr_YFSVolSync
));
820 return afs_op_nomem(op
);
822 /* marshall the parameters */
824 bp
= xdr_encode_u32(bp
, YFSREMOVEDIR
);
825 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
826 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
827 bp
= xdr_encode_name(bp
, name
);
828 yfs_check_req(call
, bp
);
830 call
->fid
= dvp
->fid
;
831 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
832 afs_make_op_call(op
, call
, GFP_NOFS
);
836 * Deliver reply data to a YFS.Link operation.
838 static int yfs_deliver_fs_link(struct afs_call
*call
)
840 struct afs_operation
*op
= call
->op
;
841 struct afs_vnode_param
*dvp
= &op
->file
[0];
842 struct afs_vnode_param
*vp
= &op
->file
[1];
846 _enter("{%u}", call
->unmarshall
);
848 ret
= afs_transfer_reply(call
);
853 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
854 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
855 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
856 _leave(" = 0 [done]");
861 * YFS.Link operation type.
863 static const struct afs_call_type yfs_RXYFSLink
= {
866 .deliver
= yfs_deliver_fs_link
,
867 .destructor
= afs_flat_call_destructor
,
873 void yfs_fs_link(struct afs_operation
*op
)
875 const struct qstr
*name
= &op
->dentry
->d_name
;
876 struct afs_vnode_param
*dvp
= &op
->file
[0];
877 struct afs_vnode_param
*vp
= &op
->file
[1];
878 struct afs_call
*call
;
883 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSLink
,
885 sizeof(struct yfs_xdr_RPCFlags
) +
886 sizeof(struct yfs_xdr_YFSFid
) +
887 xdr_strlen(name
->len
) +
888 sizeof(struct yfs_xdr_YFSFid
),
889 sizeof(struct yfs_xdr_YFSFetchStatus
) +
890 sizeof(struct yfs_xdr_YFSFetchStatus
) +
891 sizeof(struct yfs_xdr_YFSVolSync
));
893 return afs_op_nomem(op
);
895 /* marshall the parameters */
897 bp
= xdr_encode_u32(bp
, YFSLINK
);
898 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
899 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
900 bp
= xdr_encode_name(bp
, name
);
901 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
902 yfs_check_req(call
, bp
);
905 trace_afs_make_fs_call1(call
, &vp
->fid
, name
);
906 afs_make_op_call(op
, call
, GFP_NOFS
);
910 * Deliver reply data to a YFS.Symlink operation.
912 static int yfs_deliver_fs_symlink(struct afs_call
*call
)
914 struct afs_operation
*op
= call
->op
;
915 struct afs_vnode_param
*dvp
= &op
->file
[0];
916 struct afs_vnode_param
*vp
= &op
->file
[1];
920 _enter("{%u}", call
->unmarshall
);
922 ret
= afs_transfer_reply(call
);
926 /* unmarshall the reply once we've received all of it */
928 xdr_decode_YFSFid(&bp
, &vp
->fid
);
929 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
930 xdr_decode_YFSFetchStatus(&bp
, call
, &dvp
->scb
);
931 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
933 _leave(" = 0 [done]");
938 * YFS.Symlink operation type
940 static const struct afs_call_type yfs_RXYFSSymlink
= {
941 .name
= "YFS.Symlink",
942 .op
= yfs_FS_Symlink
,
943 .deliver
= yfs_deliver_fs_symlink
,
944 .destructor
= afs_flat_call_destructor
,
948 * Create a symbolic link.
950 void yfs_fs_symlink(struct afs_operation
*op
)
952 const struct qstr
*name
= &op
->dentry
->d_name
;
953 struct afs_vnode_param
*dvp
= &op
->file
[0];
954 struct afs_call
*call
;
961 contents_sz
= strlen(op
->create
.symlink
);
962 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSSymlink
,
964 sizeof(struct yfs_xdr_RPCFlags
) +
965 sizeof(struct yfs_xdr_YFSFid
) +
966 xdr_strlen(name
->len
) +
967 xdr_strlen(contents_sz
) +
968 sizeof(struct yfs_xdr_YFSStoreStatus
),
969 sizeof(struct yfs_xdr_YFSFid
) +
970 sizeof(struct yfs_xdr_YFSFetchStatus
) +
971 sizeof(struct yfs_xdr_YFSFetchStatus
) +
972 sizeof(struct yfs_xdr_YFSVolSync
));
974 return afs_op_nomem(op
);
976 /* marshall the parameters */
978 bp
= xdr_encode_u32(bp
, YFSSYMLINK
);
979 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
980 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
981 bp
= xdr_encode_name(bp
, name
);
982 bp
= xdr_encode_string(bp
, op
->create
.symlink
, contents_sz
);
983 bp
= xdr_encode_YFSStoreStatus(bp
, &mode
, &op
->mtime
);
984 yfs_check_req(call
, bp
);
986 call
->fid
= dvp
->fid
;
987 trace_afs_make_fs_call1(call
, &dvp
->fid
, name
);
988 afs_make_op_call(op
, call
, GFP_NOFS
);
992 * Deliver reply data to a YFS.Rename operation.
994 static int yfs_deliver_fs_rename(struct afs_call
*call
)
996 struct afs_operation
*op
= call
->op
;
997 struct afs_vnode_param
*orig_dvp
= &op
->file
[0];
998 struct afs_vnode_param
*new_dvp
= &op
->file
[1];
1002 _enter("{%u}", call
->unmarshall
);
1004 ret
= afs_transfer_reply(call
);
1009 /* If the two dirs are the same, we have two copies of the same status
1010 * report, so we just decode it twice.
1012 xdr_decode_YFSFetchStatus(&bp
, call
, &orig_dvp
->scb
);
1013 xdr_decode_YFSFetchStatus(&bp
, call
, &new_dvp
->scb
);
1014 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1015 _leave(" = 0 [done]");
1020 * YFS.Rename operation type
1022 static const struct afs_call_type yfs_RXYFSRename
= {
1023 .name
= "FS.Rename",
1024 .op
= yfs_FS_Rename
,
1025 .deliver
= yfs_deliver_fs_rename
,
1026 .destructor
= afs_flat_call_destructor
,
1030 * Rename a file or directory.
1032 void yfs_fs_rename(struct afs_operation
*op
)
1034 struct afs_vnode_param
*orig_dvp
= &op
->file
[0];
1035 struct afs_vnode_param
*new_dvp
= &op
->file
[1];
1036 const struct qstr
*orig_name
= &op
->dentry
->d_name
;
1037 const struct qstr
*new_name
= &op
->dentry_2
->d_name
;
1038 struct afs_call
*call
;
1043 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSRename
,
1045 sizeof(struct yfs_xdr_RPCFlags
) +
1046 sizeof(struct yfs_xdr_YFSFid
) +
1047 xdr_strlen(orig_name
->len
) +
1048 sizeof(struct yfs_xdr_YFSFid
) +
1049 xdr_strlen(new_name
->len
),
1050 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1051 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1052 sizeof(struct yfs_xdr_YFSVolSync
));
1054 return afs_op_nomem(op
);
1056 /* marshall the parameters */
1058 bp
= xdr_encode_u32(bp
, YFSRENAME
);
1059 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1060 bp
= xdr_encode_YFSFid(bp
, &orig_dvp
->fid
);
1061 bp
= xdr_encode_name(bp
, orig_name
);
1062 bp
= xdr_encode_YFSFid(bp
, &new_dvp
->fid
);
1063 bp
= xdr_encode_name(bp
, new_name
);
1064 yfs_check_req(call
, bp
);
1066 call
->fid
= orig_dvp
->fid
;
1067 trace_afs_make_fs_call2(call
, &orig_dvp
->fid
, orig_name
, new_name
);
1068 afs_make_op_call(op
, call
, GFP_NOFS
);
1072 * YFS.StoreData64 operation type.
1074 static const struct afs_call_type yfs_RXYFSStoreData64
= {
1075 .name
= "YFS.StoreData64",
1076 .op
= yfs_FS_StoreData64
,
1077 .deliver
= yfs_deliver_status_and_volsync
,
1078 .destructor
= afs_flat_call_destructor
,
1082 * Store a set of pages to a large file.
1084 void yfs_fs_store_data(struct afs_operation
*op
)
1086 struct afs_vnode_param
*vp
= &op
->file
[0];
1087 struct afs_call
*call
;
1090 _enter(",%x,{%llx:%llu},,",
1091 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1093 _debug("size %llx, at %llx, i_size %llx",
1094 (unsigned long long)op
->store
.size
,
1095 (unsigned long long)op
->store
.pos
,
1096 (unsigned long long)op
->store
.i_size
);
1098 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreData64
,
1101 sizeof(struct yfs_xdr_YFSFid
) +
1102 sizeof(struct yfs_xdr_YFSStoreStatus
) +
1103 sizeof(struct yfs_xdr_u64
) * 3,
1104 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1105 sizeof(struct yfs_xdr_YFSVolSync
));
1107 return afs_op_nomem(op
);
1109 call
->write_iter
= op
->store
.write_iter
;
1111 /* marshall the parameters */
1113 bp
= xdr_encode_u32(bp
, YFSSTOREDATA64
);
1114 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1115 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1116 bp
= xdr_encode_YFSStoreStatus(bp
, NULL
, &op
->mtime
);
1117 bp
= xdr_encode_u64(bp
, op
->store
.pos
);
1118 bp
= xdr_encode_u64(bp
, op
->store
.size
);
1119 bp
= xdr_encode_u64(bp
, op
->store
.i_size
);
1120 yfs_check_req(call
, bp
);
1122 call
->fid
= vp
->fid
;
1123 trace_afs_make_fs_call(call
, &vp
->fid
);
1124 afs_make_op_call(op
, call
, GFP_NOFS
);
1128 * YFS.StoreStatus operation type
1130 static const struct afs_call_type yfs_RXYFSStoreStatus
= {
1131 .name
= "YFS.StoreStatus",
1132 .op
= yfs_FS_StoreStatus
,
1133 .deliver
= yfs_deliver_status_and_volsync
,
1134 .destructor
= afs_flat_call_destructor
,
1137 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status
= {
1138 .name
= "YFS.StoreData64",
1139 .op
= yfs_FS_StoreData64
,
1140 .deliver
= yfs_deliver_status_and_volsync
,
1141 .destructor
= afs_flat_call_destructor
,
1145 * Set the attributes on a file, using YFS.StoreData64 rather than
1146 * YFS.StoreStatus so as to alter the file size also.
1148 static void yfs_fs_setattr_size(struct afs_operation
*op
)
1150 struct afs_vnode_param
*vp
= &op
->file
[0];
1151 struct afs_call
*call
;
1152 struct iattr
*attr
= op
->setattr
.attr
;
1155 _enter(",%x,{%llx:%llu},,",
1156 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1158 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreData64_as_Status
,
1159 sizeof(__be32
) * 2 +
1160 sizeof(struct yfs_xdr_YFSFid
) +
1161 sizeof(struct yfs_xdr_YFSStoreStatus
) +
1162 sizeof(struct yfs_xdr_u64
) * 3,
1163 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1164 sizeof(struct yfs_xdr_YFSVolSync
));
1166 return afs_op_nomem(op
);
1168 /* marshall the parameters */
1170 bp
= xdr_encode_u32(bp
, YFSSTOREDATA64
);
1171 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1172 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1173 bp
= xdr_encode_YFS_StoreStatus(bp
, attr
);
1174 bp
= xdr_encode_u64(bp
, attr
->ia_size
); /* position of start of write */
1175 bp
= xdr_encode_u64(bp
, 0); /* size of write */
1176 bp
= xdr_encode_u64(bp
, attr
->ia_size
); /* new file length */
1177 yfs_check_req(call
, bp
);
1179 call
->fid
= vp
->fid
;
1180 trace_afs_make_fs_call(call
, &vp
->fid
);
1181 afs_make_op_call(op
, call
, GFP_NOFS
);
1185 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1186 * file size, and YFS.StoreStatus otherwise.
1188 void yfs_fs_setattr(struct afs_operation
*op
)
1190 struct afs_vnode_param
*vp
= &op
->file
[0];
1191 struct afs_call
*call
;
1192 struct iattr
*attr
= op
->setattr
.attr
;
1195 if (attr
->ia_valid
& ATTR_SIZE
)
1196 return yfs_fs_setattr_size(op
);
1198 _enter(",%x,{%llx:%llu},,",
1199 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1201 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreStatus
,
1202 sizeof(__be32
) * 2 +
1203 sizeof(struct yfs_xdr_YFSFid
) +
1204 sizeof(struct yfs_xdr_YFSStoreStatus
),
1205 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1206 sizeof(struct yfs_xdr_YFSVolSync
));
1208 return afs_op_nomem(op
);
1210 /* marshall the parameters */
1212 bp
= xdr_encode_u32(bp
, YFSSTORESTATUS
);
1213 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1214 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1215 bp
= xdr_encode_YFS_StoreStatus(bp
, attr
);
1216 yfs_check_req(call
, bp
);
1218 call
->fid
= vp
->fid
;
1219 trace_afs_make_fs_call(call
, &vp
->fid
);
1220 afs_make_op_call(op
, call
, GFP_NOFS
);
1224 * Deliver reply data to a YFS.GetVolumeStatus operation.
1226 static int yfs_deliver_fs_get_volume_status(struct afs_call
*call
)
1228 struct afs_operation
*op
= call
->op
;
1234 _enter("{%u}", call
->unmarshall
);
1236 switch (call
->unmarshall
) {
1239 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSFetchVolumeStatus
));
1242 /* extract the returned status record */
1244 _debug("extract status");
1245 ret
= afs_extract_data(call
, true);
1250 xdr_decode_YFSFetchVolumeStatus(&bp
, &op
->volstatus
.vs
);
1252 afs_extract_to_tmp(call
);
1255 /* extract the volume name length */
1257 ret
= afs_extract_data(call
, true);
1261 call
->count
= ntohl(call
->tmp
);
1262 _debug("volname length: %u", call
->count
);
1263 if (call
->count
>= AFSNAMEMAX
)
1264 return afs_protocol_error(call
, afs_eproto_volname_len
);
1265 size
= (call
->count
+ 3) & ~3; /* It's padded */
1266 afs_extract_to_buf(call
, size
);
1270 /* extract the volume name */
1272 _debug("extract volname");
1273 ret
= afs_extract_data(call
, true);
1279 _debug("volname '%s'", p
);
1280 afs_extract_to_tmp(call
);
1284 /* extract the offline message length */
1286 ret
= afs_extract_data(call
, true);
1290 call
->count
= ntohl(call
->tmp
);
1291 _debug("offline msg length: %u", call
->count
);
1292 if (call
->count
>= AFSNAMEMAX
)
1293 return afs_protocol_error(call
, afs_eproto_offline_msg_len
);
1294 size
= (call
->count
+ 3) & ~3; /* It's padded */
1295 afs_extract_to_buf(call
, size
);
1299 /* extract the offline message */
1301 _debug("extract offline");
1302 ret
= afs_extract_data(call
, true);
1308 _debug("offline '%s'", p
);
1310 afs_extract_to_tmp(call
);
1314 /* extract the message of the day length */
1316 ret
= afs_extract_data(call
, true);
1320 call
->count
= ntohl(call
->tmp
);
1321 _debug("motd length: %u", call
->count
);
1322 if (call
->count
>= AFSNAMEMAX
)
1323 return afs_protocol_error(call
, afs_eproto_motd_len
);
1324 size
= (call
->count
+ 3) & ~3; /* It's padded */
1325 afs_extract_to_buf(call
, size
);
1329 /* extract the message of the day */
1331 _debug("extract motd");
1332 ret
= afs_extract_data(call
, false);
1338 _debug("motd '%s'", p
);
1347 _leave(" = 0 [done]");
1352 * YFS.GetVolumeStatus operation type
1354 static const struct afs_call_type yfs_RXYFSGetVolumeStatus
= {
1355 .name
= "YFS.GetVolumeStatus",
1356 .op
= yfs_FS_GetVolumeStatus
,
1357 .deliver
= yfs_deliver_fs_get_volume_status
,
1358 .destructor
= afs_flat_call_destructor
,
1362 * fetch the status of a volume
1364 void yfs_fs_get_volume_status(struct afs_operation
*op
)
1366 struct afs_vnode_param
*vp
= &op
->file
[0];
1367 struct afs_call
*call
;
1372 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSGetVolumeStatus
,
1373 sizeof(__be32
) * 2 +
1374 sizeof(struct yfs_xdr_u64
),
1376 sizeof(struct yfs_xdr_YFSFetchVolumeStatus
) +
1380 return afs_op_nomem(op
);
1382 /* marshall the parameters */
1384 bp
= xdr_encode_u32(bp
, YFSGETVOLUMESTATUS
);
1385 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1386 bp
= xdr_encode_u64(bp
, vp
->fid
.vid
);
1387 yfs_check_req(call
, bp
);
1389 call
->fid
= vp
->fid
;
1390 trace_afs_make_fs_call(call
, &vp
->fid
);
1391 afs_make_op_call(op
, call
, GFP_NOFS
);
1395 * YFS.SetLock operation type
1397 static const struct afs_call_type yfs_RXYFSSetLock
= {
1398 .name
= "YFS.SetLock",
1399 .op
= yfs_FS_SetLock
,
1400 .deliver
= yfs_deliver_status_and_volsync
,
1401 .done
= afs_lock_op_done
,
1402 .destructor
= afs_flat_call_destructor
,
1406 * YFS.ExtendLock operation type
1408 static const struct afs_call_type yfs_RXYFSExtendLock
= {
1409 .name
= "YFS.ExtendLock",
1410 .op
= yfs_FS_ExtendLock
,
1411 .deliver
= yfs_deliver_status_and_volsync
,
1412 .done
= afs_lock_op_done
,
1413 .destructor
= afs_flat_call_destructor
,
1417 * YFS.ReleaseLock operation type
1419 static const struct afs_call_type yfs_RXYFSReleaseLock
= {
1420 .name
= "YFS.ReleaseLock",
1421 .op
= yfs_FS_ReleaseLock
,
1422 .deliver
= yfs_deliver_status_and_volsync
,
1423 .destructor
= afs_flat_call_destructor
,
1427 * Set a lock on a file
1429 void yfs_fs_set_lock(struct afs_operation
*op
)
1431 struct afs_vnode_param
*vp
= &op
->file
[0];
1432 struct afs_call
*call
;
1437 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSSetLock
,
1438 sizeof(__be32
) * 2 +
1439 sizeof(struct yfs_xdr_YFSFid
) +
1441 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1442 sizeof(struct yfs_xdr_YFSVolSync
));
1444 return afs_op_nomem(op
);
1446 /* marshall the parameters */
1448 bp
= xdr_encode_u32(bp
, YFSSETLOCK
);
1449 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1450 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1451 bp
= xdr_encode_u32(bp
, op
->lock
.type
);
1452 yfs_check_req(call
, bp
);
1454 call
->fid
= vp
->fid
;
1455 trace_afs_make_fs_calli(call
, &vp
->fid
, op
->lock
.type
);
1456 afs_make_op_call(op
, call
, GFP_NOFS
);
1460 * extend a lock on a file
1462 void yfs_fs_extend_lock(struct afs_operation
*op
)
1464 struct afs_vnode_param
*vp
= &op
->file
[0];
1465 struct afs_call
*call
;
1470 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSExtendLock
,
1471 sizeof(__be32
) * 2 +
1472 sizeof(struct yfs_xdr_YFSFid
),
1473 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1474 sizeof(struct yfs_xdr_YFSVolSync
));
1476 return afs_op_nomem(op
);
1478 /* marshall the parameters */
1480 bp
= xdr_encode_u32(bp
, YFSEXTENDLOCK
);
1481 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1482 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1483 yfs_check_req(call
, bp
);
1485 call
->fid
= vp
->fid
;
1486 trace_afs_make_fs_call(call
, &vp
->fid
);
1487 afs_make_op_call(op
, call
, GFP_NOFS
);
1491 * release a lock on a file
1493 void yfs_fs_release_lock(struct afs_operation
*op
)
1495 struct afs_vnode_param
*vp
= &op
->file
[0];
1496 struct afs_call
*call
;
1501 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSReleaseLock
,
1502 sizeof(__be32
) * 2 +
1503 sizeof(struct yfs_xdr_YFSFid
),
1504 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1505 sizeof(struct yfs_xdr_YFSVolSync
));
1507 return afs_op_nomem(op
);
1509 /* marshall the parameters */
1511 bp
= xdr_encode_u32(bp
, YFSRELEASELOCK
);
1512 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1513 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1514 yfs_check_req(call
, bp
);
1516 call
->fid
= vp
->fid
;
1517 trace_afs_make_fs_call(call
, &vp
->fid
);
1518 afs_make_op_call(op
, call
, GFP_NOFS
);
1522 * Deliver a reply to YFS.FetchStatus
1524 static int yfs_deliver_fs_fetch_status(struct afs_call
*call
)
1526 struct afs_operation
*op
= call
->op
;
1527 struct afs_vnode_param
*vp
= &op
->file
[op
->fetch_status
.which
];
1531 ret
= afs_transfer_reply(call
);
1535 /* unmarshall the reply once we've received all of it */
1537 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
1538 xdr_decode_YFSCallBack(&bp
, call
, &vp
->scb
);
1539 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1541 _leave(" = 0 [done]");
1546 * YFS.FetchStatus operation type
1548 static const struct afs_call_type yfs_RXYFSFetchStatus
= {
1549 .name
= "YFS.FetchStatus",
1550 .op
= yfs_FS_FetchStatus
,
1551 .deliver
= yfs_deliver_fs_fetch_status
,
1552 .destructor
= afs_flat_call_destructor
,
1556 * Fetch the status information for a fid without needing a vnode handle.
1558 void yfs_fs_fetch_status(struct afs_operation
*op
)
1560 struct afs_vnode_param
*vp
= &op
->file
[op
->fetch_status
.which
];
1561 struct afs_call
*call
;
1564 _enter(",%x,{%llx:%llu},,",
1565 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1567 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSFetchStatus
,
1568 sizeof(__be32
) * 2 +
1569 sizeof(struct yfs_xdr_YFSFid
),
1570 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1571 sizeof(struct yfs_xdr_YFSCallBack
) +
1572 sizeof(struct yfs_xdr_YFSVolSync
));
1574 return afs_op_nomem(op
);
1576 /* marshall the parameters */
1578 bp
= xdr_encode_u32(bp
, YFSFETCHSTATUS
);
1579 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1580 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1581 yfs_check_req(call
, bp
);
1583 call
->fid
= vp
->fid
;
1584 trace_afs_make_fs_call(call
, &vp
->fid
);
1585 afs_make_op_call(op
, call
, GFP_NOFS
);
1589 * Deliver reply data to an YFS.InlineBulkStatus call
1591 static int yfs_deliver_fs_inline_bulk_status(struct afs_call
*call
)
1593 struct afs_operation
*op
= call
->op
;
1594 struct afs_status_cb
*scb
;
1599 _enter("{%u}", call
->unmarshall
);
1601 switch (call
->unmarshall
) {
1603 afs_extract_to_tmp(call
);
1607 /* Extract the file status count and array in two steps */
1609 _debug("extract status count");
1610 ret
= afs_extract_data(call
, true);
1614 tmp
= ntohl(call
->tmp
);
1615 _debug("status count: %u/%u", tmp
, op
->nr_files
);
1616 if (tmp
!= op
->nr_files
)
1617 return afs_protocol_error(call
, afs_eproto_ibulkst_count
);
1622 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSFetchStatus
));
1626 _debug("extract status array %u", call
->count
);
1627 ret
= afs_extract_data(call
, true);
1631 switch (call
->count
) {
1633 scb
= &op
->file
[0].scb
;
1636 scb
= &op
->file
[1].scb
;
1639 scb
= &op
->more_files
[call
->count
- 2].scb
;
1644 xdr_decode_YFSFetchStatus(&bp
, call
, scb
);
1647 if (call
->count
< op
->nr_files
)
1652 afs_extract_to_tmp(call
);
1655 /* Extract the callback count and array in two steps */
1657 _debug("extract CB count");
1658 ret
= afs_extract_data(call
, true);
1662 tmp
= ntohl(call
->tmp
);
1663 _debug("CB count: %u", tmp
);
1664 if (tmp
!= op
->nr_files
)
1665 return afs_protocol_error(call
, afs_eproto_ibulkst_cb_count
);
1669 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSCallBack
));
1673 _debug("extract CB array");
1674 ret
= afs_extract_data(call
, true);
1678 _debug("unmarshall CB array");
1679 switch (call
->count
) {
1681 scb
= &op
->file
[0].scb
;
1684 scb
= &op
->file
[1].scb
;
1687 scb
= &op
->more_files
[call
->count
- 2].scb
;
1692 xdr_decode_YFSCallBack(&bp
, call
, scb
);
1694 if (call
->count
< op
->nr_files
)
1697 afs_extract_to_buf(call
, sizeof(struct yfs_xdr_YFSVolSync
));
1702 ret
= afs_extract_data(call
, false);
1707 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1716 _leave(" = 0 [done]");
1721 * FS.InlineBulkStatus operation type
1723 static const struct afs_call_type yfs_RXYFSInlineBulkStatus
= {
1724 .name
= "YFS.InlineBulkStatus",
1725 .op
= yfs_FS_InlineBulkStatus
,
1726 .deliver
= yfs_deliver_fs_inline_bulk_status
,
1727 .destructor
= afs_flat_call_destructor
,
1731 * Fetch the status information for up to 1024 files
1733 void yfs_fs_inline_bulk_status(struct afs_operation
*op
)
1735 struct afs_vnode_param
*dvp
= &op
->file
[0];
1736 struct afs_vnode_param
*vp
= &op
->file
[1];
1737 struct afs_call
*call
;
1741 _enter(",%x,{%llx:%llu},%u",
1742 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
, op
->nr_files
);
1744 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSInlineBulkStatus
,
1748 sizeof(struct yfs_xdr_YFSFid
) * op
->nr_files
,
1749 sizeof(struct yfs_xdr_YFSFetchStatus
));
1751 return afs_op_nomem(op
);
1753 /* marshall the parameters */
1755 bp
= xdr_encode_u32(bp
, YFSINLINEBULKSTATUS
);
1756 bp
= xdr_encode_u32(bp
, 0); /* RPCFlags */
1757 bp
= xdr_encode_u32(bp
, op
->nr_files
);
1758 bp
= xdr_encode_YFSFid(bp
, &dvp
->fid
);
1759 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1760 for (i
= 0; i
< op
->nr_files
- 2; i
++)
1761 bp
= xdr_encode_YFSFid(bp
, &op
->more_files
[i
].fid
);
1762 yfs_check_req(call
, bp
);
1764 call
->fid
= vp
->fid
;
1765 trace_afs_make_fs_call(call
, &vp
->fid
);
1766 afs_make_op_call(op
, call
, GFP_NOFS
);
1770 * Deliver reply data to an YFS.FetchOpaqueACL.
1772 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call
*call
)
1774 struct afs_operation
*op
= call
->op
;
1775 struct afs_vnode_param
*vp
= &op
->file
[0];
1776 struct yfs_acl
*yacl
= op
->yacl
;
1777 struct afs_acl
*acl
;
1782 _enter("{%u}", call
->unmarshall
);
1784 switch (call
->unmarshall
) {
1786 afs_extract_to_tmp(call
);
1790 /* Extract the file ACL length */
1792 ret
= afs_extract_data(call
, true);
1796 size
= call
->count2
= ntohl(call
->tmp
);
1797 size
= round_up(size
, 4);
1799 if (yacl
->flags
& YFS_ACL_WANT_ACL
) {
1800 acl
= kmalloc(struct_size(acl
, data
, size
), GFP_KERNEL
);
1804 acl
->size
= call
->count2
;
1805 afs_extract_begin(call
, acl
->data
, size
);
1807 afs_extract_discard(call
, size
);
1812 /* Extract the file ACL */
1814 ret
= afs_extract_data(call
, true);
1818 afs_extract_to_tmp(call
);
1822 /* Extract the volume ACL length */
1824 ret
= afs_extract_data(call
, true);
1828 size
= call
->count2
= ntohl(call
->tmp
);
1829 size
= round_up(size
, 4);
1831 if (yacl
->flags
& YFS_ACL_WANT_VOL_ACL
) {
1832 acl
= kmalloc(struct_size(acl
, data
, size
), GFP_KERNEL
);
1835 yacl
->vol_acl
= acl
;
1836 acl
->size
= call
->count2
;
1837 afs_extract_begin(call
, acl
->data
, size
);
1839 afs_extract_discard(call
, size
);
1844 /* Extract the volume ACL */
1846 ret
= afs_extract_data(call
, true);
1850 afs_extract_to_buf(call
,
1851 sizeof(__be32
) * 2 +
1852 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1853 sizeof(struct yfs_xdr_YFSVolSync
));
1857 /* extract the metadata */
1859 ret
= afs_extract_data(call
, false);
1864 yacl
->inherit_flag
= ntohl(*bp
++);
1865 yacl
->num_cleaned
= ntohl(*bp
++);
1866 xdr_decode_YFSFetchStatus(&bp
, call
, &vp
->scb
);
1867 xdr_decode_YFSVolSync(&bp
, &op
->volsync
);
1876 _leave(" = 0 [done]");
1880 void yfs_free_opaque_acl(struct yfs_acl
*yacl
)
1884 kfree(yacl
->vol_acl
);
1890 * YFS.FetchOpaqueACL operation type
1892 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL
= {
1893 .name
= "YFS.FetchOpaqueACL",
1894 .op
= yfs_FS_FetchOpaqueACL
,
1895 .deliver
= yfs_deliver_fs_fetch_opaque_acl
,
1896 .destructor
= afs_flat_call_destructor
,
1900 * Fetch the YFS advanced ACLs for a file.
1902 void yfs_fs_fetch_opaque_acl(struct afs_operation
*op
)
1904 struct afs_vnode_param
*vp
= &op
->file
[0];
1905 struct afs_call
*call
;
1908 _enter(",%x,{%llx:%llu},,",
1909 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1911 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSFetchOpaqueACL
,
1912 sizeof(__be32
) * 2 +
1913 sizeof(struct yfs_xdr_YFSFid
),
1914 sizeof(__be32
) * 2 +
1915 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1916 sizeof(struct yfs_xdr_YFSVolSync
));
1918 return afs_op_nomem(op
);
1920 /* marshall the parameters */
1922 bp
= xdr_encode_u32(bp
, YFSFETCHOPAQUEACL
);
1923 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1924 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1925 yfs_check_req(call
, bp
);
1927 call
->fid
= vp
->fid
;
1928 trace_afs_make_fs_call(call
, &vp
->fid
);
1929 afs_make_op_call(op
, call
, GFP_KERNEL
);
1933 * YFS.StoreOpaqueACL2 operation type
1935 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2
= {
1936 .name
= "YFS.StoreOpaqueACL2",
1937 .op
= yfs_FS_StoreOpaqueACL2
,
1938 .deliver
= yfs_deliver_status_and_volsync
,
1939 .destructor
= afs_flat_call_destructor
,
1943 * Fetch the YFS ACL for a file.
1945 void yfs_fs_store_opaque_acl2(struct afs_operation
*op
)
1947 struct afs_vnode_param
*vp
= &op
->file
[0];
1948 struct afs_call
*call
;
1949 struct afs_acl
*acl
= op
->acl
;
1953 _enter(",%x,{%llx:%llu},,",
1954 key_serial(op
->key
), vp
->fid
.vid
, vp
->fid
.vnode
);
1956 size
= round_up(acl
->size
, 4);
1957 call
= afs_alloc_flat_call(op
->net
, &yfs_RXYFSStoreOpaqueACL2
,
1958 sizeof(__be32
) * 2 +
1959 sizeof(struct yfs_xdr_YFSFid
) +
1960 sizeof(__be32
) + size
,
1961 sizeof(struct yfs_xdr_YFSFetchStatus
) +
1962 sizeof(struct yfs_xdr_YFSVolSync
));
1964 return afs_op_nomem(op
);
1966 /* marshall the parameters */
1968 bp
= xdr_encode_u32(bp
, YFSSTOREOPAQUEACL2
);
1969 bp
= xdr_encode_u32(bp
, 0); /* RPC flags */
1970 bp
= xdr_encode_YFSFid(bp
, &vp
->fid
);
1971 bp
= xdr_encode_u32(bp
, acl
->size
);
1972 memcpy(bp
, acl
->data
, acl
->size
);
1973 if (acl
->size
!= size
)
1974 memset((void *)bp
+ acl
->size
, 0, size
- acl
->size
);
1975 bp
+= size
/ sizeof(__be32
);
1976 yfs_check_req(call
, bp
);
1978 call
->fid
= vp
->fid
;
1979 trace_afs_make_fs_call(call
, &vp
->fid
);
1980 afs_make_op_call(op
, call
, GFP_KERNEL
);