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 static const struct afs_fid afs_zero_fid;
20 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
22 call->cbi = afs_get_cb_interest(cbi);
25 #define xdr_size(x) (sizeof(*x) / sizeof(__be32))
27 static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
29 const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
31 fid->vid = xdr_to_u64(x->volume);
32 fid->vnode = xdr_to_u64(x->vnode.lo);
33 fid->vnode_hi = ntohl(x->vnode.hi);
34 fid->unique = ntohl(x->vnode.unique);
38 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
44 static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
46 struct yfs_xdr_u64 *x = (void *)bp;
49 return bp + xdr_size(x);
52 static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
54 struct yfs_xdr_YFSFid *x = (void *)bp;
56 x->volume = u64_to_xdr(fid->vid);
57 x->vnode.lo = u64_to_xdr(fid->vnode);
58 x->vnode.hi = htonl(fid->vnode_hi);
59 x->vnode.unique = htonl(fid->unique);
60 return bp + xdr_size(x);
63 static size_t xdr_strlen(unsigned int len)
65 return sizeof(__be32) + round_up(len, sizeof(__be32));
68 static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
70 bp = xdr_encode_u32(bp, len);
71 bp = memcpy(bp, p, len);
73 unsigned int pad = 4 - (len & 3);
75 memset((u8 *)bp + len, 0, pad);
79 return bp + len / sizeof(__be32);
82 static s64 linux_to_yfs_time(const struct timespec64 *t)
84 /* Convert to 100ns intervals. */
85 return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
88 static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
90 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
92 x->mask = htonl(AFS_SET_MODE);
93 x->mode = htonl(mode & S_IALLUGO);
94 x->mtime_client = u64_to_xdr(0);
95 x->owner = u64_to_xdr(0);
96 x->group = u64_to_xdr(0);
97 return bp + xdr_size(x);
100 static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
102 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
103 s64 mtime = linux_to_yfs_time(t);
105 x->mask = htonl(AFS_SET_MTIME);
107 x->mtime_client = u64_to_xdr(mtime);
108 x->owner = u64_to_xdr(0);
109 x->group = u64_to_xdr(0);
110 return bp + xdr_size(x);
114 * Convert a signed 100ns-resolution 64-bit time into a timespec.
116 static struct timespec64 yfs_time_to_linux(s64 t)
118 struct timespec64 ts;
122 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
123 * the alternative, do_div, does not work with negative numbers so have
124 * to special case them
128 ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
129 ts.tv_nsec = -ts.tv_nsec;
133 ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
140 static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
142 s64 t = xdr_to_u64(xdr);
144 return yfs_time_to_linux(t);
147 static void yfs_check_req(struct afs_call *call, __be32 *bp)
149 size_t len = (void *)bp - call->request;
151 if (len > call->request_size)
152 pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
153 call->type->name, len, call->request_size);
154 else if (len < call->request_size)
155 pr_warning("kAFS: %s: Request buffer underflow (%zu<%u)\n",
156 call->type->name, len, call->request_size);
160 * Dump a bad file status record.
162 static void xdr_dump_bad(const __be32 *bp)
167 pr_notice("YFS XDR: Bad status record\n");
168 for (i = 0; i < 6 * 4 * 4; i += 16) {
171 pr_notice("%03x: %08x %08x %08x %08x\n",
172 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
176 pr_notice("0x60: %08x %08x\n", ntohl(x[0]), ntohl(x[1]));
180 * Decode a YFSFetchStatus block
182 static void xdr_decode_YFSFetchStatus(const __be32 **_bp,
183 struct afs_call *call,
184 struct afs_status_cb *scb)
186 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
187 struct afs_file_status *status = &scb->status;
190 status->abort_code = ntohl(xdr->abort_code);
191 if (status->abort_code != 0) {
192 if (status->abort_code == VNOVNODE)
194 scb->have_error = true;
198 type = ntohl(xdr->type);
202 case AFS_FTYPE_SYMLINK:
209 status->nlink = ntohl(xdr->nlink);
210 status->author = xdr_to_u64(xdr->author);
211 status->owner = xdr_to_u64(xdr->owner);
212 status->caller_access = ntohl(xdr->caller_access); /* Ticket dependent */
213 status->anon_access = ntohl(xdr->anon_access);
214 status->mode = ntohl(xdr->mode) & S_IALLUGO;
215 status->group = xdr_to_u64(xdr->group);
216 status->lock_count = ntohl(xdr->lock_count);
218 status->mtime_client = xdr_to_time(xdr->mtime_client);
219 status->mtime_server = xdr_to_time(xdr->mtime_server);
220 status->size = xdr_to_u64(xdr->size);
221 status->data_version = xdr_to_u64(xdr->data_version);
222 scb->have_status = true;
224 *_bp += xdr_size(xdr);
229 afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
234 * Decode a YFSCallBack block
236 static void xdr_decode_YFSCallBack(const __be32 **_bp,
237 struct afs_call *call,
238 struct afs_status_cb *scb)
240 struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
241 struct afs_callback *cb = &scb->callback;
244 cb_expiry = ktime_add(call->issue_time, xdr_to_u64(x->expiration_time) * 100);
245 cb->expires_at = ktime_divns(cb_expiry, NSEC_PER_SEC);
251 * Decode a YFSVolSync block
253 static void xdr_decode_YFSVolSync(const __be32 **_bp,
254 struct afs_volsync *volsync)
256 struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
260 creation = xdr_to_u64(x->vol_creation_date);
261 do_div(creation, 10 * 1000 * 1000);
262 volsync->creation = creation;
269 * Encode the requested attributes into a YFSStoreStatus block
271 static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
273 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
274 s64 mtime = 0, owner = 0, group = 0;
275 u32 mask = 0, mode = 0;
278 if (attr->ia_valid & ATTR_MTIME) {
279 mask |= AFS_SET_MTIME;
280 mtime = linux_to_yfs_time(&attr->ia_mtime);
283 if (attr->ia_valid & ATTR_UID) {
284 mask |= AFS_SET_OWNER;
285 owner = from_kuid(&init_user_ns, attr->ia_uid);
288 if (attr->ia_valid & ATTR_GID) {
289 mask |= AFS_SET_GROUP;
290 group = from_kgid(&init_user_ns, attr->ia_gid);
293 if (attr->ia_valid & ATTR_MODE) {
294 mask |= AFS_SET_MODE;
295 mode = attr->ia_mode & S_IALLUGO;
298 x->mask = htonl(mask);
299 x->mode = htonl(mode);
300 x->mtime_client = u64_to_xdr(mtime);
301 x->owner = u64_to_xdr(owner);
302 x->group = u64_to_xdr(group);
303 return bp + xdr_size(x);
307 * Decode a YFSFetchVolumeStatus block.
309 static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
310 struct afs_volume_status *vs)
312 const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
315 vs->vid = xdr_to_u64(x->vid);
316 vs->parent_id = xdr_to_u64(x->parent_id);
317 flags = ntohl(x->flags);
318 vs->online = flags & yfs_FVSOnline;
319 vs->in_service = flags & yfs_FVSInservice;
320 vs->blessed = flags & yfs_FVSBlessed;
321 vs->needs_salvage = flags & yfs_FVSNeedsSalvage;
322 vs->type = ntohl(x->type);
324 vs->max_quota = xdr_to_u64(x->max_quota);
325 vs->blocks_in_use = xdr_to_u64(x->blocks_in_use);
326 vs->part_blocks_avail = xdr_to_u64(x->part_blocks_avail);
327 vs->part_max_blocks = xdr_to_u64(x->part_max_blocks);
328 vs->vol_copy_date = xdr_to_u64(x->vol_copy_date);
329 vs->vol_backup_date = xdr_to_u64(x->vol_backup_date);
330 *_bp += sizeof(*x) / sizeof(__be32);
334 * Deliver a reply that's a status, callback and volsync.
336 static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call)
341 ret = afs_transfer_reply(call);
345 /* unmarshall the reply once we've received all of it */
347 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
348 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
349 xdr_decode_YFSVolSync(&bp, call->out_volsync);
351 _leave(" = 0 [done]");
356 * Deliver reply data to operations that just return a file status and a volume
359 static int yfs_deliver_status_and_volsync(struct afs_call *call)
364 ret = afs_transfer_reply(call);
369 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
370 xdr_decode_YFSVolSync(&bp, call->out_volsync);
372 _leave(" = 0 [done]");
377 * YFS.FetchStatus operation type
379 static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = {
380 .name = "YFS.FetchStatus(vnode)",
381 .op = yfs_FS_FetchStatus,
382 .deliver = yfs_deliver_fs_status_cb_and_volsync,
383 .destructor = afs_flat_call_destructor,
387 * Fetch the status information for a file.
389 int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
390 struct afs_volsync *volsync)
392 struct afs_vnode *vnode = fc->vnode;
393 struct afs_call *call;
394 struct afs_net *net = afs_v2net(vnode);
397 _enter(",%x,{%llx:%llu},,",
398 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
400 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode,
402 sizeof(struct yfs_xdr_YFSFid),
403 sizeof(struct yfs_xdr_YFSFetchStatus) +
404 sizeof(struct yfs_xdr_YFSCallBack) +
405 sizeof(struct yfs_xdr_YFSVolSync));
407 fc->ac.error = -ENOMEM;
413 call->out_volsync = volsync;
415 /* marshall the parameters */
417 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
418 bp = xdr_encode_u32(bp, 0); /* RPC flags */
419 bp = xdr_encode_YFSFid(bp, &vnode->fid);
420 yfs_check_req(call, bp);
422 afs_use_fs_server(call, fc->cbi);
423 trace_afs_make_fs_call(call, &vnode->fid);
424 afs_set_fc_call(call, fc);
425 afs_make_call(&fc->ac, call, GFP_NOFS);
426 return afs_wait_for_call_to_complete(call, &fc->ac);
430 * Deliver reply data to an YFS.FetchData64.
432 static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
434 struct afs_read *req = call->read_request;
439 _enter("{%u,%zu/%llu}",
440 call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
442 switch (call->unmarshall) {
446 req->offset = req->pos & (PAGE_SIZE - 1);
447 afs_extract_to_tmp64(call);
451 /* extract the returned data length */
453 _debug("extract data length");
454 ret = afs_extract_data(call, true);
458 req->actual_len = be64_to_cpu(call->tmp64);
459 _debug("DATA length: %llu", req->actual_len);
460 req->remain = min(req->len, req->actual_len);
461 if (req->remain == 0)
467 ASSERTCMP(req->index, <, req->nr_pages);
468 if (req->remain > PAGE_SIZE - req->offset)
469 size = PAGE_SIZE - req->offset;
472 call->bvec[0].bv_len = size;
473 call->bvec[0].bv_offset = req->offset;
474 call->bvec[0].bv_page = req->pages[req->index];
475 iov_iter_bvec(&call->iter, READ, call->bvec, 1, size);
476 ASSERTCMP(size, <=, PAGE_SIZE);
479 /* extract the returned data */
481 _debug("extract data %zu/%llu",
482 iov_iter_count(&call->iter), req->remain);
484 ret = afs_extract_data(call, true);
487 req->remain -= call->bvec[0].bv_len;
488 req->offset += call->bvec[0].bv_len;
489 ASSERTCMP(req->offset, <=, PAGE_SIZE);
490 if (req->offset == PAGE_SIZE) {
497 ASSERTCMP(req->remain, ==, 0);
498 if (req->actual_len <= req->len)
501 /* Discard any excess data the server gave us */
502 afs_extract_discard(call, req->actual_len - req->len);
503 call->unmarshall = 3;
507 _debug("extract discard %zu/%llu",
508 iov_iter_count(&call->iter), req->actual_len - req->len);
510 ret = afs_extract_data(call, true);
515 call->unmarshall = 4;
516 afs_extract_to_buf(call,
517 sizeof(struct yfs_xdr_YFSFetchStatus) +
518 sizeof(struct yfs_xdr_YFSCallBack) +
519 sizeof(struct yfs_xdr_YFSVolSync));
522 /* extract the metadata */
524 ret = afs_extract_data(call, false);
529 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
530 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
531 xdr_decode_YFSVolSync(&bp, call->out_volsync);
533 req->data_version = call->out_scb->status.data_version;
534 req->file_size = call->out_scb->status.size;
543 for (; req->index < req->nr_pages; req->index++) {
544 if (req->offset < PAGE_SIZE)
545 zero_user_segment(req->pages[req->index],
546 req->offset, PAGE_SIZE);
551 for (req->index = 0; req->index < req->nr_pages; req->index++)
554 _leave(" = 0 [done]");
558 static void yfs_fetch_data_destructor(struct afs_call *call)
560 afs_put_read(call->read_request);
561 afs_flat_call_destructor(call);
565 * YFS.FetchData64 operation type
567 static const struct afs_call_type yfs_RXYFSFetchData64 = {
568 .name = "YFS.FetchData64",
569 .op = yfs_FS_FetchData64,
570 .deliver = yfs_deliver_fs_fetch_data64,
571 .destructor = yfs_fetch_data_destructor,
575 * Fetch data from a file.
577 int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
578 struct afs_read *req)
580 struct afs_vnode *vnode = fc->vnode;
581 struct afs_call *call;
582 struct afs_net *net = afs_v2net(vnode);
585 _enter(",%x,{%llx:%llu},%llx,%llx",
586 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
589 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
591 sizeof(struct yfs_xdr_YFSFid) +
592 sizeof(struct yfs_xdr_u64) * 2,
593 sizeof(struct yfs_xdr_YFSFetchStatus) +
594 sizeof(struct yfs_xdr_YFSCallBack) +
595 sizeof(struct yfs_xdr_YFSVolSync));
601 call->out_volsync = NULL;
602 call->read_request = req;
604 /* marshall the parameters */
606 bp = xdr_encode_u32(bp, YFSFETCHDATA64);
607 bp = xdr_encode_u32(bp, 0); /* RPC flags */
608 bp = xdr_encode_YFSFid(bp, &vnode->fid);
609 bp = xdr_encode_u64(bp, req->pos);
610 bp = xdr_encode_u64(bp, req->len);
611 yfs_check_req(call, bp);
613 refcount_inc(&req->usage);
614 afs_use_fs_server(call, fc->cbi);
615 trace_afs_make_fs_call(call, &vnode->fid);
616 afs_set_fc_call(call, fc);
617 afs_make_call(&fc->ac, call, GFP_NOFS);
618 return afs_wait_for_call_to_complete(call, &fc->ac);
622 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
624 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
629 _enter("{%u}", call->unmarshall);
631 ret = afs_transfer_reply(call);
635 /* unmarshall the reply once we've received all of it */
637 xdr_decode_YFSFid(&bp, call->out_fid);
638 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
639 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
640 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
641 xdr_decode_YFSVolSync(&bp, call->out_volsync);
643 _leave(" = 0 [done]");
648 * FS.CreateFile and FS.MakeDir operation type
650 static const struct afs_call_type afs_RXFSCreateFile = {
651 .name = "YFS.CreateFile",
652 .op = yfs_FS_CreateFile,
653 .deliver = yfs_deliver_fs_create_vnode,
654 .destructor = afs_flat_call_destructor,
660 int yfs_fs_create_file(struct afs_fs_cursor *fc,
663 struct afs_status_cb *dvnode_scb,
664 struct afs_fid *newfid,
665 struct afs_status_cb *new_scb)
667 struct afs_vnode *dvnode = fc->vnode;
668 struct afs_call *call;
669 struct afs_net *net = afs_v2net(dvnode);
670 size_t namesz, reqsz, rplsz;
675 namesz = strlen(name);
676 reqsz = (sizeof(__be32) +
678 sizeof(struct yfs_xdr_YFSFid) +
680 sizeof(struct yfs_xdr_YFSStoreStatus) +
682 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
683 sizeof(struct yfs_xdr_YFSFetchStatus) +
684 sizeof(struct yfs_xdr_YFSFetchStatus) +
685 sizeof(struct yfs_xdr_YFSCallBack) +
686 sizeof(struct yfs_xdr_YFSVolSync));
688 call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
693 call->out_dir_scb = dvnode_scb;
694 call->out_fid = newfid;
695 call->out_scb = new_scb;
697 /* marshall the parameters */
699 bp = xdr_encode_u32(bp, YFSCREATEFILE);
700 bp = xdr_encode_u32(bp, 0); /* RPC flags */
701 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
702 bp = xdr_encode_string(bp, name, namesz);
703 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
704 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
705 yfs_check_req(call, bp);
707 afs_use_fs_server(call, fc->cbi);
708 trace_afs_make_fs_call1(call, &dvnode->fid, name);
709 afs_set_fc_call(call, fc);
710 afs_make_call(&fc->ac, call, GFP_NOFS);
711 return afs_wait_for_call_to_complete(call, &fc->ac);
714 static const struct afs_call_type yfs_RXFSMakeDir = {
715 .name = "YFS.MakeDir",
716 .op = yfs_FS_MakeDir,
717 .deliver = yfs_deliver_fs_create_vnode,
718 .destructor = afs_flat_call_destructor,
724 int yfs_fs_make_dir(struct afs_fs_cursor *fc,
727 struct afs_status_cb *dvnode_scb,
728 struct afs_fid *newfid,
729 struct afs_status_cb *new_scb)
731 struct afs_vnode *dvnode = fc->vnode;
732 struct afs_call *call;
733 struct afs_net *net = afs_v2net(dvnode);
734 size_t namesz, reqsz, rplsz;
739 namesz = strlen(name);
740 reqsz = (sizeof(__be32) +
741 sizeof(struct yfs_xdr_RPCFlags) +
742 sizeof(struct yfs_xdr_YFSFid) +
744 sizeof(struct yfs_xdr_YFSStoreStatus));
745 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
746 sizeof(struct yfs_xdr_YFSFetchStatus) +
747 sizeof(struct yfs_xdr_YFSFetchStatus) +
748 sizeof(struct yfs_xdr_YFSCallBack) +
749 sizeof(struct yfs_xdr_YFSVolSync));
751 call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
756 call->out_dir_scb = dvnode_scb;
757 call->out_fid = newfid;
758 call->out_scb = new_scb;
760 /* marshall the parameters */
762 bp = xdr_encode_u32(bp, YFSMAKEDIR);
763 bp = xdr_encode_u32(bp, 0); /* RPC flags */
764 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
765 bp = xdr_encode_string(bp, name, namesz);
766 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
767 yfs_check_req(call, bp);
769 afs_use_fs_server(call, fc->cbi);
770 trace_afs_make_fs_call1(call, &dvnode->fid, name);
771 afs_set_fc_call(call, fc);
772 afs_make_call(&fc->ac, call, GFP_NOFS);
773 return afs_wait_for_call_to_complete(call, &fc->ac);
777 * Deliver reply data to a YFS.RemoveFile2 operation.
779 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
785 _enter("{%u}", call->unmarshall);
787 ret = afs_transfer_reply(call);
792 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
793 xdr_decode_YFSFid(&bp, &fid);
794 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
795 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
797 xdr_decode_YFSVolSync(&bp, call->out_volsync);
802 * YFS.RemoveFile2 operation type.
804 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
805 .name = "YFS.RemoveFile2",
806 .op = yfs_FS_RemoveFile2,
807 .deliver = yfs_deliver_fs_remove_file2,
808 .destructor = afs_flat_call_destructor,
812 * Remove a file and retrieve new file status.
814 int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
815 const char *name, struct afs_status_cb *dvnode_scb,
816 struct afs_status_cb *vnode_scb)
818 struct afs_vnode *dvnode = fc->vnode;
819 struct afs_call *call;
820 struct afs_net *net = afs_v2net(dvnode);
826 namesz = strlen(name);
828 call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
830 sizeof(struct yfs_xdr_RPCFlags) +
831 sizeof(struct yfs_xdr_YFSFid) +
833 sizeof(struct yfs_xdr_YFSFetchStatus) +
834 sizeof(struct yfs_xdr_YFSFid) +
835 sizeof(struct yfs_xdr_YFSFetchStatus) +
836 sizeof(struct yfs_xdr_YFSVolSync));
841 call->out_dir_scb = dvnode_scb;
842 call->out_scb = vnode_scb;
844 /* marshall the parameters */
846 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
847 bp = xdr_encode_u32(bp, 0); /* RPC flags */
848 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
849 bp = xdr_encode_string(bp, name, namesz);
850 yfs_check_req(call, bp);
852 afs_use_fs_server(call, fc->cbi);
853 trace_afs_make_fs_call1(call, &dvnode->fid, name);
854 afs_set_fc_call(call, fc);
855 afs_make_call(&fc->ac, call, GFP_NOFS);
856 return afs_wait_for_call_to_complete(call, &fc->ac);
860 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
862 static int yfs_deliver_fs_remove(struct afs_call *call)
867 _enter("{%u}", call->unmarshall);
869 ret = afs_transfer_reply(call);
874 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
875 xdr_decode_YFSVolSync(&bp, call->out_volsync);
880 * FS.RemoveDir and FS.RemoveFile operation types.
882 static const struct afs_call_type yfs_RXYFSRemoveFile = {
883 .name = "YFS.RemoveFile",
884 .op = yfs_FS_RemoveFile,
885 .deliver = yfs_deliver_fs_remove,
886 .destructor = afs_flat_call_destructor,
889 static const struct afs_call_type yfs_RXYFSRemoveDir = {
890 .name = "YFS.RemoveDir",
891 .op = yfs_FS_RemoveDir,
892 .deliver = yfs_deliver_fs_remove,
893 .destructor = afs_flat_call_destructor,
897 * remove a file or directory
899 int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
900 const char *name, bool isdir,
901 struct afs_status_cb *dvnode_scb)
903 struct afs_vnode *dvnode = fc->vnode;
904 struct afs_call *call;
905 struct afs_net *net = afs_v2net(dvnode);
911 namesz = strlen(name);
912 call = afs_alloc_flat_call(
913 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
915 sizeof(struct yfs_xdr_RPCFlags) +
916 sizeof(struct yfs_xdr_YFSFid) +
918 sizeof(struct yfs_xdr_YFSFetchStatus) +
919 sizeof(struct yfs_xdr_YFSVolSync));
924 call->out_dir_scb = dvnode_scb;
926 /* marshall the parameters */
928 bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
929 bp = xdr_encode_u32(bp, 0); /* RPC flags */
930 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
931 bp = xdr_encode_string(bp, name, namesz);
932 yfs_check_req(call, bp);
934 afs_use_fs_server(call, fc->cbi);
935 trace_afs_make_fs_call1(call, &dvnode->fid, name);
936 afs_set_fc_call(call, fc);
937 afs_make_call(&fc->ac, call, GFP_NOFS);
938 return afs_wait_for_call_to_complete(call, &fc->ac);
942 * Deliver reply data to a YFS.Link operation.
944 static int yfs_deliver_fs_link(struct afs_call *call)
949 _enter("{%u}", call->unmarshall);
951 ret = afs_transfer_reply(call);
956 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
957 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
958 xdr_decode_YFSVolSync(&bp, call->out_volsync);
959 _leave(" = 0 [done]");
964 * YFS.Link operation type.
966 static const struct afs_call_type yfs_RXYFSLink = {
969 .deliver = yfs_deliver_fs_link,
970 .destructor = afs_flat_call_destructor,
976 int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
978 struct afs_status_cb *dvnode_scb,
979 struct afs_status_cb *vnode_scb)
981 struct afs_vnode *dvnode = fc->vnode;
982 struct afs_call *call;
983 struct afs_net *net = afs_v2net(vnode);
989 namesz = strlen(name);
990 call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
992 sizeof(struct yfs_xdr_RPCFlags) +
993 sizeof(struct yfs_xdr_YFSFid) +
995 sizeof(struct yfs_xdr_YFSFid),
996 sizeof(struct yfs_xdr_YFSFetchStatus) +
997 sizeof(struct yfs_xdr_YFSFetchStatus) +
998 sizeof(struct yfs_xdr_YFSVolSync));
1002 call->key = fc->key;
1003 call->out_dir_scb = dvnode_scb;
1004 call->out_scb = vnode_scb;
1006 /* marshall the parameters */
1008 bp = xdr_encode_u32(bp, YFSLINK);
1009 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1010 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1011 bp = xdr_encode_string(bp, name, namesz);
1012 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1013 yfs_check_req(call, bp);
1015 afs_use_fs_server(call, fc->cbi);
1016 trace_afs_make_fs_call1(call, &vnode->fid, name);
1017 afs_set_fc_call(call, fc);
1018 afs_make_call(&fc->ac, call, GFP_NOFS);
1019 return afs_wait_for_call_to_complete(call, &fc->ac);
1023 * Deliver reply data to a YFS.Symlink operation.
1025 static int yfs_deliver_fs_symlink(struct afs_call *call)
1030 _enter("{%u}", call->unmarshall);
1032 ret = afs_transfer_reply(call);
1036 /* unmarshall the reply once we've received all of it */
1038 xdr_decode_YFSFid(&bp, call->out_fid);
1039 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1040 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1041 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1043 _leave(" = 0 [done]");
1048 * YFS.Symlink operation type
1050 static const struct afs_call_type yfs_RXYFSSymlink = {
1051 .name = "YFS.Symlink",
1052 .op = yfs_FS_Symlink,
1053 .deliver = yfs_deliver_fs_symlink,
1054 .destructor = afs_flat_call_destructor,
1058 * Create a symbolic link.
1060 int yfs_fs_symlink(struct afs_fs_cursor *fc,
1062 const char *contents,
1063 struct afs_status_cb *dvnode_scb,
1064 struct afs_fid *newfid,
1065 struct afs_status_cb *vnode_scb)
1067 struct afs_vnode *dvnode = fc->vnode;
1068 struct afs_call *call;
1069 struct afs_net *net = afs_v2net(dvnode);
1070 size_t namesz, contents_sz;
1075 namesz = strlen(name);
1076 contents_sz = strlen(contents);
1077 call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1079 sizeof(struct yfs_xdr_RPCFlags) +
1080 sizeof(struct yfs_xdr_YFSFid) +
1081 xdr_strlen(namesz) +
1082 xdr_strlen(contents_sz) +
1083 sizeof(struct yfs_xdr_YFSStoreStatus),
1084 sizeof(struct yfs_xdr_YFSFid) +
1085 sizeof(struct yfs_xdr_YFSFetchStatus) +
1086 sizeof(struct yfs_xdr_YFSFetchStatus) +
1087 sizeof(struct yfs_xdr_YFSVolSync));
1091 call->key = fc->key;
1092 call->out_dir_scb = dvnode_scb;
1093 call->out_fid = newfid;
1094 call->out_scb = vnode_scb;
1096 /* marshall the parameters */
1098 bp = xdr_encode_u32(bp, YFSSYMLINK);
1099 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1100 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1101 bp = xdr_encode_string(bp, name, namesz);
1102 bp = xdr_encode_string(bp, contents, contents_sz);
1103 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1104 yfs_check_req(call, bp);
1106 afs_use_fs_server(call, fc->cbi);
1107 trace_afs_make_fs_call1(call, &dvnode->fid, name);
1108 afs_set_fc_call(call, fc);
1109 afs_make_call(&fc->ac, call, GFP_NOFS);
1110 return afs_wait_for_call_to_complete(call, &fc->ac);
1114 * Deliver reply data to a YFS.Rename operation.
1116 static int yfs_deliver_fs_rename(struct afs_call *call)
1121 _enter("{%u}", call->unmarshall);
1123 ret = afs_transfer_reply(call);
1128 /* If the two dirs are the same, we have two copies of the same status
1129 * report, so we just decode it twice.
1131 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1132 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1133 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1134 _leave(" = 0 [done]");
1139 * YFS.Rename operation type
1141 static const struct afs_call_type yfs_RXYFSRename = {
1142 .name = "FS.Rename",
1143 .op = yfs_FS_Rename,
1144 .deliver = yfs_deliver_fs_rename,
1145 .destructor = afs_flat_call_destructor,
1149 * Rename a file or directory.
1151 int yfs_fs_rename(struct afs_fs_cursor *fc,
1152 const char *orig_name,
1153 struct afs_vnode *new_dvnode,
1154 const char *new_name,
1155 struct afs_status_cb *orig_dvnode_scb,
1156 struct afs_status_cb *new_dvnode_scb)
1158 struct afs_vnode *orig_dvnode = fc->vnode;
1159 struct afs_call *call;
1160 struct afs_net *net = afs_v2net(orig_dvnode);
1161 size_t o_namesz, n_namesz;
1166 o_namesz = strlen(orig_name);
1167 n_namesz = strlen(new_name);
1168 call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1170 sizeof(struct yfs_xdr_RPCFlags) +
1171 sizeof(struct yfs_xdr_YFSFid) +
1172 xdr_strlen(o_namesz) +
1173 sizeof(struct yfs_xdr_YFSFid) +
1174 xdr_strlen(n_namesz),
1175 sizeof(struct yfs_xdr_YFSFetchStatus) +
1176 sizeof(struct yfs_xdr_YFSFetchStatus) +
1177 sizeof(struct yfs_xdr_YFSVolSync));
1181 call->key = fc->key;
1182 call->out_dir_scb = orig_dvnode_scb;
1183 call->out_scb = new_dvnode_scb;
1185 /* marshall the parameters */
1187 bp = xdr_encode_u32(bp, YFSRENAME);
1188 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1189 bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1190 bp = xdr_encode_string(bp, orig_name, o_namesz);
1191 bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1192 bp = xdr_encode_string(bp, new_name, n_namesz);
1193 yfs_check_req(call, bp);
1195 afs_use_fs_server(call, fc->cbi);
1196 trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
1197 afs_set_fc_call(call, fc);
1198 afs_make_call(&fc->ac, call, GFP_NOFS);
1199 return afs_wait_for_call_to_complete(call, &fc->ac);
1203 * YFS.StoreData64 operation type.
1205 static const struct afs_call_type yfs_RXYFSStoreData64 = {
1206 .name = "YFS.StoreData64",
1207 .op = yfs_FS_StoreData64,
1208 .deliver = yfs_deliver_status_and_volsync,
1209 .destructor = afs_flat_call_destructor,
1213 * Store a set of pages to a large file.
1215 int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1216 pgoff_t first, pgoff_t last,
1217 unsigned offset, unsigned to,
1218 struct afs_status_cb *scb)
1220 struct afs_vnode *vnode = fc->vnode;
1221 struct afs_call *call;
1222 struct afs_net *net = afs_v2net(vnode);
1223 loff_t size, pos, i_size;
1226 _enter(",%x,{%llx:%llu},,",
1227 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1229 size = (loff_t)to - (loff_t)offset;
1231 size += (loff_t)(last - first) << PAGE_SHIFT;
1232 pos = (loff_t)first << PAGE_SHIFT;
1235 i_size = i_size_read(&vnode->vfs_inode);
1236 if (pos + size > i_size)
1237 i_size = size + pos;
1239 _debug("size %llx, at %llx, i_size %llx",
1240 (unsigned long long)size, (unsigned long long)pos,
1241 (unsigned long long)i_size);
1243 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1246 sizeof(struct yfs_xdr_YFSFid) +
1247 sizeof(struct yfs_xdr_YFSStoreStatus) +
1248 sizeof(struct yfs_xdr_u64) * 3,
1249 sizeof(struct yfs_xdr_YFSFetchStatus) +
1250 sizeof(struct yfs_xdr_YFSVolSync));
1254 call->key = fc->key;
1255 call->mapping = mapping;
1256 call->first = first;
1258 call->first_offset = offset;
1260 call->send_pages = true;
1261 call->out_scb = scb;
1263 /* marshall the parameters */
1265 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1266 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1267 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1268 bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1269 bp = xdr_encode_u64(bp, pos);
1270 bp = xdr_encode_u64(bp, size);
1271 bp = xdr_encode_u64(bp, i_size);
1272 yfs_check_req(call, bp);
1274 afs_use_fs_server(call, fc->cbi);
1275 trace_afs_make_fs_call(call, &vnode->fid);
1276 afs_set_fc_call(call, fc);
1277 afs_make_call(&fc->ac, call, GFP_NOFS);
1278 return afs_wait_for_call_to_complete(call, &fc->ac);
1282 * YFS.StoreStatus operation type
1284 static const struct afs_call_type yfs_RXYFSStoreStatus = {
1285 .name = "YFS.StoreStatus",
1286 .op = yfs_FS_StoreStatus,
1287 .deliver = yfs_deliver_status_and_volsync,
1288 .destructor = afs_flat_call_destructor,
1291 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1292 .name = "YFS.StoreData64",
1293 .op = yfs_FS_StoreData64,
1294 .deliver = yfs_deliver_status_and_volsync,
1295 .destructor = afs_flat_call_destructor,
1299 * Set the attributes on a file, using YFS.StoreData64 rather than
1300 * YFS.StoreStatus so as to alter the file size also.
1302 static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr,
1303 struct afs_status_cb *scb)
1305 struct afs_vnode *vnode = fc->vnode;
1306 struct afs_call *call;
1307 struct afs_net *net = afs_v2net(vnode);
1310 _enter(",%x,{%llx:%llu},,",
1311 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1313 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1314 sizeof(__be32) * 2 +
1315 sizeof(struct yfs_xdr_YFSFid) +
1316 sizeof(struct yfs_xdr_YFSStoreStatus) +
1317 sizeof(struct yfs_xdr_u64) * 3,
1318 sizeof(struct yfs_xdr_YFSFetchStatus) +
1319 sizeof(struct yfs_xdr_YFSVolSync));
1323 call->key = fc->key;
1324 call->out_scb = scb;
1326 /* marshall the parameters */
1328 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1329 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1330 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1331 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1332 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1333 bp = xdr_encode_u64(bp, 0); /* size of write */
1334 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1335 yfs_check_req(call, bp);
1337 afs_use_fs_server(call, fc->cbi);
1338 trace_afs_make_fs_call(call, &vnode->fid);
1339 afs_set_fc_call(call, fc);
1340 afs_make_call(&fc->ac, call, GFP_NOFS);
1341 return afs_wait_for_call_to_complete(call, &fc->ac);
1345 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1346 * file size, and YFS.StoreStatus otherwise.
1348 int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr,
1349 struct afs_status_cb *scb)
1351 struct afs_vnode *vnode = fc->vnode;
1352 struct afs_call *call;
1353 struct afs_net *net = afs_v2net(vnode);
1356 if (attr->ia_valid & ATTR_SIZE)
1357 return yfs_fs_setattr_size(fc, attr, scb);
1359 _enter(",%x,{%llx:%llu},,",
1360 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1362 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1363 sizeof(__be32) * 2 +
1364 sizeof(struct yfs_xdr_YFSFid) +
1365 sizeof(struct yfs_xdr_YFSStoreStatus),
1366 sizeof(struct yfs_xdr_YFSFetchStatus) +
1367 sizeof(struct yfs_xdr_YFSVolSync));
1371 call->key = fc->key;
1372 call->out_scb = scb;
1374 /* marshall the parameters */
1376 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1377 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1378 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1379 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1380 yfs_check_req(call, bp);
1382 afs_use_fs_server(call, fc->cbi);
1383 trace_afs_make_fs_call(call, &vnode->fid);
1384 afs_set_fc_call(call, fc);
1385 afs_make_call(&fc->ac, call, GFP_NOFS);
1386 return afs_wait_for_call_to_complete(call, &fc->ac);
1390 * Deliver reply data to a YFS.GetVolumeStatus operation.
1392 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1399 _enter("{%u}", call->unmarshall);
1401 switch (call->unmarshall) {
1404 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1407 /* extract the returned status record */
1409 _debug("extract status");
1410 ret = afs_extract_data(call, true);
1415 xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus);
1417 afs_extract_to_tmp(call);
1420 /* extract the volume name length */
1422 ret = afs_extract_data(call, true);
1426 call->count = ntohl(call->tmp);
1427 _debug("volname length: %u", call->count);
1428 if (call->count >= AFSNAMEMAX)
1429 return afs_protocol_error(call, -EBADMSG,
1430 afs_eproto_volname_len);
1431 size = (call->count + 3) & ~3; /* It's padded */
1432 afs_extract_to_buf(call, size);
1436 /* extract the volume name */
1438 _debug("extract volname");
1439 ret = afs_extract_data(call, true);
1445 _debug("volname '%s'", p);
1446 afs_extract_to_tmp(call);
1450 /* extract the offline message length */
1452 ret = afs_extract_data(call, true);
1456 call->count = ntohl(call->tmp);
1457 _debug("offline msg length: %u", call->count);
1458 if (call->count >= AFSNAMEMAX)
1459 return afs_protocol_error(call, -EBADMSG,
1460 afs_eproto_offline_msg_len);
1461 size = (call->count + 3) & ~3; /* It's padded */
1462 afs_extract_to_buf(call, size);
1466 /* extract the offline message */
1468 _debug("extract offline");
1469 ret = afs_extract_data(call, true);
1475 _debug("offline '%s'", p);
1477 afs_extract_to_tmp(call);
1481 /* extract the message of the day length */
1483 ret = afs_extract_data(call, true);
1487 call->count = ntohl(call->tmp);
1488 _debug("motd length: %u", call->count);
1489 if (call->count >= AFSNAMEMAX)
1490 return afs_protocol_error(call, -EBADMSG,
1491 afs_eproto_motd_len);
1492 size = (call->count + 3) & ~3; /* It's padded */
1493 afs_extract_to_buf(call, size);
1497 /* extract the message of the day */
1499 _debug("extract motd");
1500 ret = afs_extract_data(call, false);
1506 _debug("motd '%s'", p);
1515 _leave(" = 0 [done]");
1520 * YFS.GetVolumeStatus operation type
1522 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1523 .name = "YFS.GetVolumeStatus",
1524 .op = yfs_FS_GetVolumeStatus,
1525 .deliver = yfs_deliver_fs_get_volume_status,
1526 .destructor = afs_flat_call_destructor,
1530 * fetch the status of a volume
1532 int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1533 struct afs_volume_status *vs)
1535 struct afs_vnode *vnode = fc->vnode;
1536 struct afs_call *call;
1537 struct afs_net *net = afs_v2net(vnode);
1542 call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1543 sizeof(__be32) * 2 +
1544 sizeof(struct yfs_xdr_u64),
1546 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1552 call->key = fc->key;
1553 call->out_volstatus = vs;
1555 /* marshall the parameters */
1557 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1558 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1559 bp = xdr_encode_u64(bp, vnode->fid.vid);
1560 yfs_check_req(call, bp);
1562 afs_use_fs_server(call, fc->cbi);
1563 trace_afs_make_fs_call(call, &vnode->fid);
1564 afs_set_fc_call(call, fc);
1565 afs_make_call(&fc->ac, call, GFP_NOFS);
1566 return afs_wait_for_call_to_complete(call, &fc->ac);
1570 * YFS.SetLock operation type
1572 static const struct afs_call_type yfs_RXYFSSetLock = {
1573 .name = "YFS.SetLock",
1574 .op = yfs_FS_SetLock,
1575 .deliver = yfs_deliver_status_and_volsync,
1576 .done = afs_lock_op_done,
1577 .destructor = afs_flat_call_destructor,
1581 * YFS.ExtendLock operation type
1583 static const struct afs_call_type yfs_RXYFSExtendLock = {
1584 .name = "YFS.ExtendLock",
1585 .op = yfs_FS_ExtendLock,
1586 .deliver = yfs_deliver_status_and_volsync,
1587 .done = afs_lock_op_done,
1588 .destructor = afs_flat_call_destructor,
1592 * YFS.ReleaseLock operation type
1594 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1595 .name = "YFS.ReleaseLock",
1596 .op = yfs_FS_ReleaseLock,
1597 .deliver = yfs_deliver_status_and_volsync,
1598 .destructor = afs_flat_call_destructor,
1602 * Set a lock on a file
1604 int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,
1605 struct afs_status_cb *scb)
1607 struct afs_vnode *vnode = fc->vnode;
1608 struct afs_call *call;
1609 struct afs_net *net = afs_v2net(vnode);
1614 call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1615 sizeof(__be32) * 2 +
1616 sizeof(struct yfs_xdr_YFSFid) +
1618 sizeof(struct yfs_xdr_YFSFetchStatus) +
1619 sizeof(struct yfs_xdr_YFSVolSync));
1623 call->key = fc->key;
1624 call->lvnode = vnode;
1625 call->out_scb = scb;
1627 /* marshall the parameters */
1629 bp = xdr_encode_u32(bp, YFSSETLOCK);
1630 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1631 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1632 bp = xdr_encode_u32(bp, type);
1633 yfs_check_req(call, bp);
1635 afs_use_fs_server(call, fc->cbi);
1636 trace_afs_make_fs_calli(call, &vnode->fid, type);
1637 afs_set_fc_call(call, fc);
1638 afs_make_call(&fc->ac, call, GFP_NOFS);
1639 return afs_wait_for_call_to_complete(call, &fc->ac);
1643 * extend a lock on a file
1645 int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1647 struct afs_vnode *vnode = fc->vnode;
1648 struct afs_call *call;
1649 struct afs_net *net = afs_v2net(vnode);
1654 call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1655 sizeof(__be32) * 2 +
1656 sizeof(struct yfs_xdr_YFSFid),
1657 sizeof(struct yfs_xdr_YFSFetchStatus) +
1658 sizeof(struct yfs_xdr_YFSVolSync));
1662 call->key = fc->key;
1663 call->lvnode = vnode;
1664 call->out_scb = scb;
1666 /* marshall the parameters */
1668 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1669 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1670 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1671 yfs_check_req(call, bp);
1673 afs_use_fs_server(call, fc->cbi);
1674 trace_afs_make_fs_call(call, &vnode->fid);
1675 afs_set_fc_call(call, fc);
1676 afs_make_call(&fc->ac, call, GFP_NOFS);
1677 return afs_wait_for_call_to_complete(call, &fc->ac);
1681 * release a lock on a file
1683 int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1685 struct afs_vnode *vnode = fc->vnode;
1686 struct afs_call *call;
1687 struct afs_net *net = afs_v2net(vnode);
1692 call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1693 sizeof(__be32) * 2 +
1694 sizeof(struct yfs_xdr_YFSFid),
1695 sizeof(struct yfs_xdr_YFSFetchStatus) +
1696 sizeof(struct yfs_xdr_YFSVolSync));
1700 call->key = fc->key;
1701 call->lvnode = vnode;
1702 call->out_scb = scb;
1704 /* marshall the parameters */
1706 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1707 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1708 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1709 yfs_check_req(call, bp);
1711 afs_use_fs_server(call, fc->cbi);
1712 trace_afs_make_fs_call(call, &vnode->fid);
1713 afs_set_fc_call(call, fc);
1714 afs_make_call(&fc->ac, call, GFP_NOFS);
1715 return afs_wait_for_call_to_complete(call, &fc->ac);
1719 * YFS.FetchStatus operation type
1721 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1722 .name = "YFS.FetchStatus",
1723 .op = yfs_FS_FetchStatus,
1724 .deliver = yfs_deliver_fs_status_cb_and_volsync,
1725 .destructor = afs_flat_call_destructor,
1729 * Fetch the status information for a fid without needing a vnode handle.
1731 int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1732 struct afs_net *net,
1733 struct afs_fid *fid,
1734 struct afs_status_cb *scb,
1735 struct afs_volsync *volsync)
1737 struct afs_call *call;
1740 _enter(",%x,{%llx:%llu},,",
1741 key_serial(fc->key), fid->vid, fid->vnode);
1743 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1744 sizeof(__be32) * 2 +
1745 sizeof(struct yfs_xdr_YFSFid),
1746 sizeof(struct yfs_xdr_YFSFetchStatus) +
1747 sizeof(struct yfs_xdr_YFSCallBack) +
1748 sizeof(struct yfs_xdr_YFSVolSync));
1750 fc->ac.error = -ENOMEM;
1754 call->key = fc->key;
1755 call->out_scb = scb;
1756 call->out_volsync = volsync;
1758 /* marshall the parameters */
1760 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1761 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1762 bp = xdr_encode_YFSFid(bp, fid);
1763 yfs_check_req(call, bp);
1765 afs_use_fs_server(call, fc->cbi);
1766 trace_afs_make_fs_call(call, fid);
1767 afs_set_fc_call(call, fc);
1768 afs_make_call(&fc->ac, call, GFP_NOFS);
1769 return afs_wait_for_call_to_complete(call, &fc->ac);
1773 * Deliver reply data to an YFS.InlineBulkStatus call
1775 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1777 struct afs_status_cb *scb;
1782 _enter("{%u}", call->unmarshall);
1784 switch (call->unmarshall) {
1786 afs_extract_to_tmp(call);
1790 /* Extract the file status count and array in two steps */
1792 _debug("extract status count");
1793 ret = afs_extract_data(call, true);
1797 tmp = ntohl(call->tmp);
1798 _debug("status count: %u/%u", tmp, call->count2);
1799 if (tmp != call->count2)
1800 return afs_protocol_error(call, -EBADMSG,
1801 afs_eproto_ibulkst_count);
1806 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1810 _debug("extract status array %u", call->count);
1811 ret = afs_extract_data(call, true);
1816 scb = &call->out_scb[call->count];
1817 xdr_decode_YFSFetchStatus(&bp, call, scb);
1820 if (call->count < call->count2)
1825 afs_extract_to_tmp(call);
1828 /* Extract the callback count and array in two steps */
1830 _debug("extract CB count");
1831 ret = afs_extract_data(call, true);
1835 tmp = ntohl(call->tmp);
1836 _debug("CB count: %u", tmp);
1837 if (tmp != call->count2)
1838 return afs_protocol_error(call, -EBADMSG,
1839 afs_eproto_ibulkst_cb_count);
1843 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1847 _debug("extract CB array");
1848 ret = afs_extract_data(call, true);
1852 _debug("unmarshall CB array");
1854 scb = &call->out_scb[call->count];
1855 xdr_decode_YFSCallBack(&bp, call, scb);
1857 if (call->count < call->count2)
1860 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1865 ret = afs_extract_data(call, false);
1870 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1879 _leave(" = 0 [done]");
1884 * FS.InlineBulkStatus operation type
1886 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1887 .name = "YFS.InlineBulkStatus",
1888 .op = yfs_FS_InlineBulkStatus,
1889 .deliver = yfs_deliver_fs_inline_bulk_status,
1890 .destructor = afs_flat_call_destructor,
1894 * Fetch the status information for up to 1024 files
1896 int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
1897 struct afs_net *net,
1898 struct afs_fid *fids,
1899 struct afs_status_cb *statuses,
1900 unsigned int nr_fids,
1901 struct afs_volsync *volsync)
1903 struct afs_call *call;
1907 _enter(",%x,{%llx:%llu},%u",
1908 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
1910 call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
1914 sizeof(struct yfs_xdr_YFSFid) * nr_fids,
1915 sizeof(struct yfs_xdr_YFSFetchStatus));
1917 fc->ac.error = -ENOMEM;
1921 call->key = fc->key;
1922 call->out_scb = statuses;
1923 call->out_volsync = volsync;
1924 call->count2 = nr_fids;
1926 /* marshall the parameters */
1928 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1929 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1930 bp = xdr_encode_u32(bp, nr_fids);
1931 for (i = 0; i < nr_fids; i++)
1932 bp = xdr_encode_YFSFid(bp, &fids[i]);
1933 yfs_check_req(call, bp);
1935 afs_use_fs_server(call, fc->cbi);
1936 trace_afs_make_fs_call(call, &fids[0]);
1937 afs_set_fc_call(call, fc);
1938 afs_make_call(&fc->ac, call, GFP_NOFS);
1939 return afs_wait_for_call_to_complete(call, &fc->ac);
1943 * Deliver reply data to an YFS.FetchOpaqueACL.
1945 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1947 struct yfs_acl *yacl = call->out_yacl;
1948 struct afs_acl *acl;
1953 _enter("{%u}", call->unmarshall);
1955 switch (call->unmarshall) {
1957 afs_extract_to_tmp(call);
1961 /* Extract the file ACL length */
1963 ret = afs_extract_data(call, true);
1967 size = call->count2 = ntohl(call->tmp);
1968 size = round_up(size, 4);
1970 if (yacl->flags & YFS_ACL_WANT_ACL) {
1971 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1975 acl->size = call->count2;
1976 afs_extract_begin(call, acl->data, size);
1978 afs_extract_discard(call, size);
1983 /* Extract the file ACL */
1985 ret = afs_extract_data(call, true);
1989 afs_extract_to_tmp(call);
1993 /* Extract the volume ACL length */
1995 ret = afs_extract_data(call, true);
1999 size = call->count2 = ntohl(call->tmp);
2000 size = round_up(size, 4);
2002 if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2003 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2006 yacl->vol_acl = acl;
2007 acl->size = call->count2;
2008 afs_extract_begin(call, acl->data, size);
2010 afs_extract_discard(call, size);
2015 /* Extract the volume ACL */
2017 ret = afs_extract_data(call, true);
2021 afs_extract_to_buf(call,
2022 sizeof(__be32) * 2 +
2023 sizeof(struct yfs_xdr_YFSFetchStatus) +
2024 sizeof(struct yfs_xdr_YFSVolSync));
2028 /* extract the metadata */
2030 ret = afs_extract_data(call, false);
2035 yacl->inherit_flag = ntohl(*bp++);
2036 yacl->num_cleaned = ntohl(*bp++);
2037 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
2038 xdr_decode_YFSVolSync(&bp, call->out_volsync);
2047 _leave(" = 0 [done]");
2051 void yfs_free_opaque_acl(struct yfs_acl *yacl)
2055 kfree(yacl->vol_acl);
2061 * YFS.FetchOpaqueACL operation type
2063 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2064 .name = "YFS.FetchOpaqueACL",
2065 .op = yfs_FS_FetchOpaqueACL,
2066 .deliver = yfs_deliver_fs_fetch_opaque_acl,
2067 .destructor = afs_flat_call_destructor,
2071 * Fetch the YFS advanced ACLs for a file.
2073 struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
2074 struct yfs_acl *yacl,
2075 struct afs_status_cb *scb)
2077 struct afs_vnode *vnode = fc->vnode;
2078 struct afs_call *call;
2079 struct afs_net *net = afs_v2net(vnode);
2082 _enter(",%x,{%llx:%llu},,",
2083 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2085 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,
2086 sizeof(__be32) * 2 +
2087 sizeof(struct yfs_xdr_YFSFid),
2088 sizeof(__be32) * 2 +
2089 sizeof(struct yfs_xdr_YFSFetchStatus) +
2090 sizeof(struct yfs_xdr_YFSVolSync));
2092 fc->ac.error = -ENOMEM;
2093 return ERR_PTR(-ENOMEM);
2096 call->key = fc->key;
2097 call->out_yacl = yacl;
2098 call->out_scb = scb;
2099 call->out_volsync = NULL;
2101 /* marshall the parameters */
2103 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2104 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2105 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2106 yfs_check_req(call, bp);
2108 afs_use_fs_server(call, fc->cbi);
2109 trace_afs_make_fs_call(call, &vnode->fid);
2110 afs_make_call(&fc->ac, call, GFP_KERNEL);
2111 return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2115 * YFS.StoreOpaqueACL2 operation type
2117 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2118 .name = "YFS.StoreOpaqueACL2",
2119 .op = yfs_FS_StoreOpaqueACL2,
2120 .deliver = yfs_deliver_status_and_volsync,
2121 .destructor = afs_flat_call_destructor,
2125 * Fetch the YFS ACL for a file.
2127 int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl,
2128 struct afs_status_cb *scb)
2130 struct afs_vnode *vnode = fc->vnode;
2131 struct afs_call *call;
2132 struct afs_net *net = afs_v2net(vnode);
2136 _enter(",%x,{%llx:%llu},,",
2137 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2139 size = round_up(acl->size, 4);
2140 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreOpaqueACL2,
2141 sizeof(__be32) * 2 +
2142 sizeof(struct yfs_xdr_YFSFid) +
2143 sizeof(__be32) + size,
2144 sizeof(struct yfs_xdr_YFSFetchStatus) +
2145 sizeof(struct yfs_xdr_YFSVolSync));
2147 fc->ac.error = -ENOMEM;
2151 call->key = fc->key;
2152 call->out_scb = scb;
2153 call->out_volsync = NULL;
2155 /* marshall the parameters */
2157 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2158 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2159 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2160 bp = xdr_encode_u32(bp, acl->size);
2161 memcpy(bp, acl->data, acl->size);
2162 if (acl->size != size)
2163 memset((void *)bp + acl->size, 0, size - acl->size);
2164 bp += size / sizeof(__be32);
2165 yfs_check_req(call, bp);
2167 trace_afs_make_fs_call(call, &vnode->fid);
2168 afs_make_call(&fc->ac, call, GFP_KERNEL);
2169 return afs_wait_for_call_to_complete(call, &fc->ac);