Linux 6.14-rc1
[linux-stable.git] / fs / afs / yfsclient.c
blob257af259c04a6b2afcd96187752fd1d7f0f6fd55
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)
6 */
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>
13 #include "internal.h"
14 #include "afs_fs.h"
15 #include "xdr_fs.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);
28 *_bp += xdr_size(x);
31 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
33 *bp++ = htonl(n);
34 return bp;
37 static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
39 struct yfs_xdr_u64 *x = (void *)bp;
41 *x = u64_to_xdr(n);
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);
65 if (len & 3) {
66 unsigned int pad = 4 - (len & 3);
68 memset((u8 *)bp + len, 0, pad);
69 len += 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;
110 u64 abs_t;
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
117 if (t < 0) {
118 abs_t = -t;
119 ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
120 ts.tv_nsec = -ts.tv_nsec;
121 ts.tv_sec = -abs_t;
122 } else {
123 abs_t = t;
124 ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
125 ts.tv_sec = abs_t;
128 return ts;
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)
155 __be32 x[4];
156 int i;
158 pr_notice("YFS XDR: Bad status record\n");
159 for (i = 0; i < 6 * 4 * 4; i += 16) {
160 memcpy(x, bp, 16);
161 bp += 4;
162 pr_notice("%03x: %08x %08x %08x %08x\n",
163 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
166 memcpy(x, bp, 8);
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;
179 u32 type;
181 status->abort_code = ntohl(xdr->abort_code);
182 if (status->abort_code != 0) {
183 if (status->abort_code == VNOVNODE)
184 status->nlink = 0;
185 scb->have_error = true;
186 goto advance;
189 type = ntohl(xdr->type);
190 switch (type) {
191 case AFS_FTYPE_FILE:
192 case AFS_FTYPE_DIR:
193 case AFS_FTYPE_SYMLINK:
194 status->type = type;
195 break;
196 default:
197 goto bad;
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;
214 advance:
215 *_bp += xdr_size(xdr);
216 return;
218 bad:
219 xdr_dump_bad(*_bp);
220 afs_protocol_error(call, afs_eproto_bad_status);
221 goto advance;
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;
233 ktime_t cb_expiry;
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);
237 scb->have_cb = true;
238 *_bp += xdr_size(x);
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;
250 if (volsync) {
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;
259 *_bp += xdr_size(x);
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;
271 mask = 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;
307 u32 flags;
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);
317 vs->min_quota = 0;
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
329 * sync record.
331 static int yfs_deliver_status_and_volsync(struct afs_call *call)
333 struct afs_operation *op = call->op;
334 const __be32 *bp;
335 int ret;
337 ret = afs_transfer_reply(call);
338 if (ret < 0)
339 return ret;
341 bp = call->buffer;
342 xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb);
343 xdr_decode_YFSVolSync(&bp, &op->volsync);
345 _leave(" = 0 [done]");
346 return 0;
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 netfs_io_subrequest *subreq = op->fetch.subreq;
356 struct afs_vnode_param *vp = &op->file[0];
357 const __be32 *bp;
358 size_t count_before;
359 int ret;
361 _enter("{%u,%zu, %zu/%llu}",
362 call->unmarshall, call->iov_len, iov_iter_count(call->iter),
363 call->remaining);
365 switch (call->unmarshall) {
366 case 0:
367 call->remaining = 0;
368 afs_extract_to_tmp64(call);
369 call->unmarshall++;
370 fallthrough;
372 /* Extract the returned data length into ->actual_len. This
373 * may indicate more or less data than was requested will be
374 * returned.
376 case 1:
377 _debug("extract data length");
378 ret = afs_extract_data(call, true);
379 if (ret < 0)
380 return ret;
382 call->remaining = be64_to_cpu(call->tmp64);
383 _debug("DATA length: %llu", call->remaining);
385 if (call->remaining == 0)
386 goto no_more_data;
388 call->iter = &subreq->io_iter;
389 call->iov_len = min(call->remaining, subreq->len - subreq->transferred);
390 call->unmarshall++;
391 fallthrough;
393 /* extract the returned data */
394 case 2:
395 count_before = call->iov_len;
396 _debug("extract data %zu/%llu", count_before, call->remaining);
398 ret = afs_extract_data(call, true);
399 subreq->transferred += count_before - call->iov_len;
400 if (ret < 0)
401 return ret;
403 call->iter = &call->def_iter;
404 if (call->remaining)
405 goto no_more_data;
407 /* Discard any excess data the server gave us */
408 afs_extract_discard(call, call->remaining);
409 call->unmarshall = 3;
410 fallthrough;
412 case 3:
413 _debug("extract discard %zu/%llu",
414 iov_iter_count(call->iter), call->remaining);
416 ret = afs_extract_data(call, true);
417 if (ret < 0)
418 return ret;
420 no_more_data:
421 call->unmarshall = 4;
422 afs_extract_to_buf(call,
423 sizeof(struct yfs_xdr_YFSFetchStatus) +
424 sizeof(struct yfs_xdr_YFSCallBack) +
425 sizeof(struct yfs_xdr_YFSVolSync));
426 fallthrough;
428 /* extract the metadata */
429 case 4:
430 ret = afs_extract_data(call, false);
431 if (ret < 0)
432 return ret;
434 bp = call->buffer;
435 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
436 xdr_decode_YFSCallBack(&bp, call, &vp->scb);
437 xdr_decode_YFSVolSync(&bp, &op->volsync);
439 if (subreq->start + subreq->transferred >= vp->scb.status.size)
440 __set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
442 call->unmarshall++;
443 fallthrough;
445 case 5:
446 break;
449 _leave(" = 0 [done]");
450 return 0;
454 * YFS.FetchData64 operation type
456 static const struct afs_call_type yfs_RXYFSFetchData64 = {
457 .name = "YFS.FetchData64",
458 .op = yfs_FS_FetchData64,
459 .async_rx = afs_fetch_data_async_rx,
460 .deliver = yfs_deliver_fs_fetch_data64,
461 .immediate_cancel = afs_fetch_data_immediate_cancel,
462 .destructor = afs_flat_call_destructor,
466 * Fetch data from a file.
468 void yfs_fs_fetch_data(struct afs_operation *op)
470 struct netfs_io_subrequest *subreq = op->fetch.subreq;
471 struct afs_vnode_param *vp = &op->file[0];
472 struct afs_call *call;
473 __be32 *bp;
475 _enter(",%x,{%llx:%llu},%llx,%zx",
476 key_serial(op->key), vp->fid.vid, vp->fid.vnode,
477 subreq->start + subreq->transferred,
478 subreq->len - subreq->transferred);
480 call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchData64,
481 sizeof(__be32) * 2 +
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));
487 if (!call)
488 return afs_op_nomem(op);
490 if (op->flags & AFS_OPERATION_ASYNC)
491 call->async = true;
493 /* marshall the parameters */
494 bp = call->request;
495 bp = xdr_encode_u32(bp, YFSFETCHDATA64);
496 bp = xdr_encode_u32(bp, 0); /* RPC flags */
497 bp = xdr_encode_YFSFid(bp, &vp->fid);
498 bp = xdr_encode_u64(bp, subreq->start + subreq->transferred);
499 bp = xdr_encode_u64(bp, subreq->len - subreq->transferred);
500 yfs_check_req(call, bp);
502 call->fid = vp->fid;
503 trace_afs_make_fs_call(call, &vp->fid);
504 afs_make_op_call(op, call, GFP_NOFS);
508 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
510 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
512 struct afs_operation *op = call->op;
513 struct afs_vnode_param *dvp = &op->file[0];
514 struct afs_vnode_param *vp = &op->file[1];
515 const __be32 *bp;
516 int ret;
518 _enter("{%u}", call->unmarshall);
520 ret = afs_transfer_reply(call);
521 if (ret < 0)
522 return ret;
524 /* unmarshall the reply once we've received all of it */
525 bp = call->buffer;
526 xdr_decode_YFSFid(&bp, &op->file[1].fid);
527 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
528 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
529 xdr_decode_YFSCallBack(&bp, call, &vp->scb);
530 xdr_decode_YFSVolSync(&bp, &op->volsync);
532 _leave(" = 0 [done]");
533 return 0;
537 * FS.CreateFile and FS.MakeDir operation type
539 static const struct afs_call_type afs_RXFSCreateFile = {
540 .name = "YFS.CreateFile",
541 .op = yfs_FS_CreateFile,
542 .deliver = yfs_deliver_fs_create_vnode,
543 .destructor = afs_flat_call_destructor,
547 * Create a file.
549 void yfs_fs_create_file(struct afs_operation *op)
551 const struct qstr *name = &op->dentry->d_name;
552 struct afs_vnode_param *dvp = &op->file[0];
553 struct afs_call *call;
554 size_t reqsz, rplsz;
555 __be32 *bp;
557 _enter("");
559 reqsz = (sizeof(__be32) +
560 sizeof(__be32) +
561 sizeof(struct yfs_xdr_YFSFid) +
562 xdr_strlen(name->len) +
563 sizeof(struct yfs_xdr_YFSStoreStatus) +
564 sizeof(__be32));
565 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
566 sizeof(struct yfs_xdr_YFSFetchStatus) +
567 sizeof(struct yfs_xdr_YFSFetchStatus) +
568 sizeof(struct yfs_xdr_YFSCallBack) +
569 sizeof(struct yfs_xdr_YFSVolSync));
571 call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, reqsz, rplsz);
572 if (!call)
573 return afs_op_nomem(op);
575 /* marshall the parameters */
576 bp = call->request;
577 bp = xdr_encode_u32(bp, YFSCREATEFILE);
578 bp = xdr_encode_u32(bp, 0); /* RPC flags */
579 bp = xdr_encode_YFSFid(bp, &dvp->fid);
580 bp = xdr_encode_name(bp, name);
581 bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
582 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
583 yfs_check_req(call, bp);
585 call->fid = dvp->fid;
586 trace_afs_make_fs_call1(call, &dvp->fid, name);
587 afs_make_op_call(op, call, GFP_NOFS);
590 static const struct afs_call_type yfs_RXFSMakeDir = {
591 .name = "YFS.MakeDir",
592 .op = yfs_FS_MakeDir,
593 .deliver = yfs_deliver_fs_create_vnode,
594 .destructor = afs_flat_call_destructor,
598 * Make a directory.
600 void yfs_fs_make_dir(struct afs_operation *op)
602 const struct qstr *name = &op->dentry->d_name;
603 struct afs_vnode_param *dvp = &op->file[0];
604 struct afs_call *call;
605 size_t reqsz, rplsz;
606 __be32 *bp;
608 _enter("");
610 reqsz = (sizeof(__be32) +
611 sizeof(struct yfs_xdr_RPCFlags) +
612 sizeof(struct yfs_xdr_YFSFid) +
613 xdr_strlen(name->len) +
614 sizeof(struct yfs_xdr_YFSStoreStatus));
615 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
616 sizeof(struct yfs_xdr_YFSFetchStatus) +
617 sizeof(struct yfs_xdr_YFSFetchStatus) +
618 sizeof(struct yfs_xdr_YFSCallBack) +
619 sizeof(struct yfs_xdr_YFSVolSync));
621 call = afs_alloc_flat_call(op->net, &yfs_RXFSMakeDir, reqsz, rplsz);
622 if (!call)
623 return afs_op_nomem(op);
625 /* marshall the parameters */
626 bp = call->request;
627 bp = xdr_encode_u32(bp, YFSMAKEDIR);
628 bp = xdr_encode_u32(bp, 0); /* RPC flags */
629 bp = xdr_encode_YFSFid(bp, &dvp->fid);
630 bp = xdr_encode_name(bp, name);
631 bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
632 yfs_check_req(call, bp);
634 call->fid = dvp->fid;
635 trace_afs_make_fs_call1(call, &dvp->fid, name);
636 afs_make_op_call(op, call, GFP_NOFS);
640 * Deliver reply data to a YFS.RemoveFile2 operation.
642 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
644 struct afs_operation *op = call->op;
645 struct afs_vnode_param *dvp = &op->file[0];
646 struct afs_vnode_param *vp = &op->file[1];
647 struct afs_fid fid;
648 const __be32 *bp;
649 int ret;
651 _enter("{%u}", call->unmarshall);
653 ret = afs_transfer_reply(call);
654 if (ret < 0)
655 return ret;
657 bp = call->buffer;
658 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
659 xdr_decode_YFSFid(&bp, &fid);
660 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
661 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
663 xdr_decode_YFSVolSync(&bp, &op->volsync);
664 return 0;
667 static void yfs_done_fs_remove_file2(struct afs_call *call)
669 if (call->error == -ECONNABORTED &&
670 (call->abort_code == RX_INVALID_OPERATION ||
671 call->abort_code == RXGEN_OPCODE)) {
672 set_bit(AFS_SERVER_FL_NO_RM2, &call->op->server->flags);
673 call->op->flags |= AFS_OPERATION_DOWNGRADE;
678 * YFS.RemoveFile2 operation type.
680 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
681 .name = "YFS.RemoveFile2",
682 .op = yfs_FS_RemoveFile2,
683 .deliver = yfs_deliver_fs_remove_file2,
684 .done = yfs_done_fs_remove_file2,
685 .destructor = afs_flat_call_destructor,
689 * Remove a file and retrieve new file status.
691 void yfs_fs_remove_file2(struct afs_operation *op)
693 struct afs_vnode_param *dvp = &op->file[0];
694 const struct qstr *name = &op->dentry->d_name;
695 struct afs_call *call;
696 __be32 *bp;
698 _enter("");
700 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile2,
701 sizeof(__be32) +
702 sizeof(struct yfs_xdr_RPCFlags) +
703 sizeof(struct yfs_xdr_YFSFid) +
704 xdr_strlen(name->len),
705 sizeof(struct yfs_xdr_YFSFetchStatus) +
706 sizeof(struct yfs_xdr_YFSFid) +
707 sizeof(struct yfs_xdr_YFSFetchStatus) +
708 sizeof(struct yfs_xdr_YFSVolSync));
709 if (!call)
710 return afs_op_nomem(op);
712 /* marshall the parameters */
713 bp = call->request;
714 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
715 bp = xdr_encode_u32(bp, 0); /* RPC flags */
716 bp = xdr_encode_YFSFid(bp, &dvp->fid);
717 bp = xdr_encode_name(bp, name);
718 yfs_check_req(call, bp);
720 call->fid = dvp->fid;
721 trace_afs_make_fs_call1(call, &dvp->fid, name);
722 afs_make_op_call(op, call, GFP_NOFS);
726 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
728 static int yfs_deliver_fs_remove(struct afs_call *call)
730 struct afs_operation *op = call->op;
731 struct afs_vnode_param *dvp = &op->file[0];
732 const __be32 *bp;
733 int ret;
735 _enter("{%u}", call->unmarshall);
737 ret = afs_transfer_reply(call);
738 if (ret < 0)
739 return ret;
741 bp = call->buffer;
742 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
743 xdr_decode_YFSVolSync(&bp, &op->volsync);
744 return 0;
748 * FS.RemoveDir and FS.RemoveFile operation types.
750 static const struct afs_call_type yfs_RXYFSRemoveFile = {
751 .name = "YFS.RemoveFile",
752 .op = yfs_FS_RemoveFile,
753 .deliver = yfs_deliver_fs_remove,
754 .destructor = afs_flat_call_destructor,
758 * Remove a file.
760 void yfs_fs_remove_file(struct afs_operation *op)
762 const struct qstr *name = &op->dentry->d_name;
763 struct afs_vnode_param *dvp = &op->file[0];
764 struct afs_call *call;
765 __be32 *bp;
767 _enter("");
769 if (!test_bit(AFS_SERVER_FL_NO_RM2, &op->server->flags))
770 return yfs_fs_remove_file2(op);
772 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile,
773 sizeof(__be32) +
774 sizeof(struct yfs_xdr_RPCFlags) +
775 sizeof(struct yfs_xdr_YFSFid) +
776 xdr_strlen(name->len),
777 sizeof(struct yfs_xdr_YFSFetchStatus) +
778 sizeof(struct yfs_xdr_YFSVolSync));
779 if (!call)
780 return afs_op_nomem(op);
782 /* marshall the parameters */
783 bp = call->request;
784 bp = xdr_encode_u32(bp, YFSREMOVEFILE);
785 bp = xdr_encode_u32(bp, 0); /* RPC flags */
786 bp = xdr_encode_YFSFid(bp, &dvp->fid);
787 bp = xdr_encode_name(bp, name);
788 yfs_check_req(call, bp);
790 call->fid = dvp->fid;
791 trace_afs_make_fs_call1(call, &dvp->fid, name);
792 afs_make_op_call(op, call, GFP_NOFS);
795 static const struct afs_call_type yfs_RXYFSRemoveDir = {
796 .name = "YFS.RemoveDir",
797 .op = yfs_FS_RemoveDir,
798 .deliver = yfs_deliver_fs_remove,
799 .destructor = afs_flat_call_destructor,
803 * Remove a directory.
805 void yfs_fs_remove_dir(struct afs_operation *op)
807 const struct qstr *name = &op->dentry->d_name;
808 struct afs_vnode_param *dvp = &op->file[0];
809 struct afs_call *call;
810 __be32 *bp;
812 _enter("");
814 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveDir,
815 sizeof(__be32) +
816 sizeof(struct yfs_xdr_RPCFlags) +
817 sizeof(struct yfs_xdr_YFSFid) +
818 xdr_strlen(name->len),
819 sizeof(struct yfs_xdr_YFSFetchStatus) +
820 sizeof(struct yfs_xdr_YFSVolSync));
821 if (!call)
822 return afs_op_nomem(op);
824 /* marshall the parameters */
825 bp = call->request;
826 bp = xdr_encode_u32(bp, YFSREMOVEDIR);
827 bp = xdr_encode_u32(bp, 0); /* RPC flags */
828 bp = xdr_encode_YFSFid(bp, &dvp->fid);
829 bp = xdr_encode_name(bp, name);
830 yfs_check_req(call, bp);
832 call->fid = dvp->fid;
833 trace_afs_make_fs_call1(call, &dvp->fid, name);
834 afs_make_op_call(op, call, GFP_NOFS);
838 * Deliver reply data to a YFS.Link operation.
840 static int yfs_deliver_fs_link(struct afs_call *call)
842 struct afs_operation *op = call->op;
843 struct afs_vnode_param *dvp = &op->file[0];
844 struct afs_vnode_param *vp = &op->file[1];
845 const __be32 *bp;
846 int ret;
848 _enter("{%u}", call->unmarshall);
850 ret = afs_transfer_reply(call);
851 if (ret < 0)
852 return ret;
854 bp = call->buffer;
855 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
856 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
857 xdr_decode_YFSVolSync(&bp, &op->volsync);
858 _leave(" = 0 [done]");
859 return 0;
863 * YFS.Link operation type.
865 static const struct afs_call_type yfs_RXYFSLink = {
866 .name = "YFS.Link",
867 .op = yfs_FS_Link,
868 .deliver = yfs_deliver_fs_link,
869 .destructor = afs_flat_call_destructor,
873 * Make a hard link.
875 void yfs_fs_link(struct afs_operation *op)
877 const struct qstr *name = &op->dentry->d_name;
878 struct afs_vnode_param *dvp = &op->file[0];
879 struct afs_vnode_param *vp = &op->file[1];
880 struct afs_call *call;
881 __be32 *bp;
883 _enter("");
885 call = afs_alloc_flat_call(op->net, &yfs_RXYFSLink,
886 sizeof(__be32) +
887 sizeof(struct yfs_xdr_RPCFlags) +
888 sizeof(struct yfs_xdr_YFSFid) +
889 xdr_strlen(name->len) +
890 sizeof(struct yfs_xdr_YFSFid),
891 sizeof(struct yfs_xdr_YFSFetchStatus) +
892 sizeof(struct yfs_xdr_YFSFetchStatus) +
893 sizeof(struct yfs_xdr_YFSVolSync));
894 if (!call)
895 return afs_op_nomem(op);
897 /* marshall the parameters */
898 bp = call->request;
899 bp = xdr_encode_u32(bp, YFSLINK);
900 bp = xdr_encode_u32(bp, 0); /* RPC flags */
901 bp = xdr_encode_YFSFid(bp, &dvp->fid);
902 bp = xdr_encode_name(bp, name);
903 bp = xdr_encode_YFSFid(bp, &vp->fid);
904 yfs_check_req(call, bp);
906 call->fid = vp->fid;
907 trace_afs_make_fs_call1(call, &vp->fid, name);
908 afs_make_op_call(op, call, GFP_NOFS);
912 * Deliver reply data to a YFS.Symlink operation.
914 static int yfs_deliver_fs_symlink(struct afs_call *call)
916 struct afs_operation *op = call->op;
917 struct afs_vnode_param *dvp = &op->file[0];
918 struct afs_vnode_param *vp = &op->file[1];
919 const __be32 *bp;
920 int ret;
922 _enter("{%u}", call->unmarshall);
924 ret = afs_transfer_reply(call);
925 if (ret < 0)
926 return ret;
928 /* unmarshall the reply once we've received all of it */
929 bp = call->buffer;
930 xdr_decode_YFSFid(&bp, &vp->fid);
931 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
932 xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
933 xdr_decode_YFSVolSync(&bp, &op->volsync);
935 _leave(" = 0 [done]");
936 return 0;
940 * YFS.Symlink operation type
942 static const struct afs_call_type yfs_RXYFSSymlink = {
943 .name = "YFS.Symlink",
944 .op = yfs_FS_Symlink,
945 .deliver = yfs_deliver_fs_symlink,
946 .destructor = afs_flat_call_destructor,
950 * Create a symbolic link.
952 void yfs_fs_symlink(struct afs_operation *op)
954 const struct qstr *name = &op->dentry->d_name;
955 struct afs_vnode_param *dvp = &op->file[0];
956 struct afs_call *call;
957 size_t contents_sz;
958 mode_t mode = 0777;
959 __be32 *bp;
961 _enter("");
963 contents_sz = strlen(op->create.symlink);
964 call = afs_alloc_flat_call(op->net, &yfs_RXYFSSymlink,
965 sizeof(__be32) +
966 sizeof(struct yfs_xdr_RPCFlags) +
967 sizeof(struct yfs_xdr_YFSFid) +
968 xdr_strlen(name->len) +
969 xdr_strlen(contents_sz) +
970 sizeof(struct yfs_xdr_YFSStoreStatus),
971 sizeof(struct yfs_xdr_YFSFid) +
972 sizeof(struct yfs_xdr_YFSFetchStatus) +
973 sizeof(struct yfs_xdr_YFSFetchStatus) +
974 sizeof(struct yfs_xdr_YFSVolSync));
975 if (!call)
976 return afs_op_nomem(op);
978 /* marshall the parameters */
979 bp = call->request;
980 bp = xdr_encode_u32(bp, YFSSYMLINK);
981 bp = xdr_encode_u32(bp, 0); /* RPC flags */
982 bp = xdr_encode_YFSFid(bp, &dvp->fid);
983 bp = xdr_encode_name(bp, name);
984 bp = xdr_encode_string(bp, op->create.symlink, contents_sz);
985 bp = xdr_encode_YFSStoreStatus(bp, &mode, &op->mtime);
986 yfs_check_req(call, bp);
988 call->fid = dvp->fid;
989 trace_afs_make_fs_call1(call, &dvp->fid, name);
990 afs_make_op_call(op, call, GFP_NOFS);
994 * Deliver reply data to a YFS.Rename operation.
996 static int yfs_deliver_fs_rename(struct afs_call *call)
998 struct afs_operation *op = call->op;
999 struct afs_vnode_param *orig_dvp = &op->file[0];
1000 struct afs_vnode_param *new_dvp = &op->file[1];
1001 const __be32 *bp;
1002 int ret;
1004 _enter("{%u}", call->unmarshall);
1006 ret = afs_transfer_reply(call);
1007 if (ret < 0)
1008 return ret;
1010 bp = call->buffer;
1011 /* If the two dirs are the same, we have two copies of the same status
1012 * report, so we just decode it twice.
1014 xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1015 xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1016 xdr_decode_YFSVolSync(&bp, &op->volsync);
1017 _leave(" = 0 [done]");
1018 return 0;
1022 * YFS.Rename operation type
1024 static const struct afs_call_type yfs_RXYFSRename = {
1025 .name = "FS.Rename",
1026 .op = yfs_FS_Rename,
1027 .deliver = yfs_deliver_fs_rename,
1028 .destructor = afs_flat_call_destructor,
1032 * Rename a file or directory.
1034 void yfs_fs_rename(struct afs_operation *op)
1036 struct afs_vnode_param *orig_dvp = &op->file[0];
1037 struct afs_vnode_param *new_dvp = &op->file[1];
1038 const struct qstr *orig_name = &op->dentry->d_name;
1039 const struct qstr *new_name = &op->dentry_2->d_name;
1040 struct afs_call *call;
1041 __be32 *bp;
1043 _enter("");
1045 call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename,
1046 sizeof(__be32) +
1047 sizeof(struct yfs_xdr_RPCFlags) +
1048 sizeof(struct yfs_xdr_YFSFid) +
1049 xdr_strlen(orig_name->len) +
1050 sizeof(struct yfs_xdr_YFSFid) +
1051 xdr_strlen(new_name->len),
1052 sizeof(struct yfs_xdr_YFSFetchStatus) +
1053 sizeof(struct yfs_xdr_YFSFetchStatus) +
1054 sizeof(struct yfs_xdr_YFSVolSync));
1055 if (!call)
1056 return afs_op_nomem(op);
1058 /* marshall the parameters */
1059 bp = call->request;
1060 bp = xdr_encode_u32(bp, YFSRENAME);
1061 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1062 bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1063 bp = xdr_encode_name(bp, orig_name);
1064 bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1065 bp = xdr_encode_name(bp, new_name);
1066 yfs_check_req(call, bp);
1068 call->fid = orig_dvp->fid;
1069 trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1070 afs_make_op_call(op, call, GFP_NOFS);
1074 * YFS.StoreData64 operation type.
1076 static const struct afs_call_type yfs_RXYFSStoreData64 = {
1077 .name = "YFS.StoreData64",
1078 .op = yfs_FS_StoreData64,
1079 .deliver = yfs_deliver_status_and_volsync,
1080 .destructor = afs_flat_call_destructor,
1084 * Store a set of pages to a large file.
1086 void yfs_fs_store_data(struct afs_operation *op)
1088 struct afs_vnode_param *vp = &op->file[0];
1089 struct afs_call *call;
1090 __be32 *bp;
1092 _enter(",%x,{%llx:%llu},,",
1093 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1095 _debug("size %llx, at %llx, i_size %llx",
1096 (unsigned long long)op->store.size,
1097 (unsigned long long)op->store.pos,
1098 (unsigned long long)op->store.i_size);
1100 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64,
1101 sizeof(__be32) +
1102 sizeof(__be32) +
1103 sizeof(struct yfs_xdr_YFSFid) +
1104 sizeof(struct yfs_xdr_YFSStoreStatus) +
1105 sizeof(struct yfs_xdr_u64) * 3,
1106 sizeof(struct yfs_xdr_YFSFetchStatus) +
1107 sizeof(struct yfs_xdr_YFSVolSync));
1108 if (!call)
1109 return afs_op_nomem(op);
1111 call->write_iter = op->store.write_iter;
1113 /* marshall the parameters */
1114 bp = call->request;
1115 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1116 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1117 bp = xdr_encode_YFSFid(bp, &vp->fid);
1118 bp = xdr_encode_YFSStoreStatus(bp, NULL, &op->mtime);
1119 bp = xdr_encode_u64(bp, op->store.pos);
1120 bp = xdr_encode_u64(bp, op->store.size);
1121 bp = xdr_encode_u64(bp, op->store.i_size);
1122 yfs_check_req(call, bp);
1124 call->fid = vp->fid;
1125 trace_afs_make_fs_call(call, &vp->fid);
1126 afs_make_op_call(op, call, GFP_NOFS);
1130 * YFS.StoreStatus operation type
1132 static const struct afs_call_type yfs_RXYFSStoreStatus = {
1133 .name = "YFS.StoreStatus",
1134 .op = yfs_FS_StoreStatus,
1135 .deliver = yfs_deliver_status_and_volsync,
1136 .destructor = afs_flat_call_destructor,
1139 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1140 .name = "YFS.StoreData64",
1141 .op = yfs_FS_StoreData64,
1142 .deliver = yfs_deliver_status_and_volsync,
1143 .destructor = afs_flat_call_destructor,
1147 * Set the attributes on a file, using YFS.StoreData64 rather than
1148 * YFS.StoreStatus so as to alter the file size also.
1150 static void yfs_fs_setattr_size(struct afs_operation *op)
1152 struct afs_vnode_param *vp = &op->file[0];
1153 struct afs_call *call;
1154 struct iattr *attr = op->setattr.attr;
1155 __be32 *bp;
1157 _enter(",%x,{%llx:%llu},,",
1158 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1160 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64_as_Status,
1161 sizeof(__be32) * 2 +
1162 sizeof(struct yfs_xdr_YFSFid) +
1163 sizeof(struct yfs_xdr_YFSStoreStatus) +
1164 sizeof(struct yfs_xdr_u64) * 3,
1165 sizeof(struct yfs_xdr_YFSFetchStatus) +
1166 sizeof(struct yfs_xdr_YFSVolSync));
1167 if (!call)
1168 return afs_op_nomem(op);
1170 /* marshall the parameters */
1171 bp = call->request;
1172 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1173 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1174 bp = xdr_encode_YFSFid(bp, &vp->fid);
1175 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1176 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1177 bp = xdr_encode_u64(bp, 0); /* size of write */
1178 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1179 yfs_check_req(call, bp);
1181 call->fid = vp->fid;
1182 trace_afs_make_fs_call(call, &vp->fid);
1183 afs_make_op_call(op, call, GFP_NOFS);
1187 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1188 * file size, and YFS.StoreStatus otherwise.
1190 void yfs_fs_setattr(struct afs_operation *op)
1192 struct afs_vnode_param *vp = &op->file[0];
1193 struct afs_call *call;
1194 struct iattr *attr = op->setattr.attr;
1195 __be32 *bp;
1197 if (attr->ia_valid & ATTR_SIZE)
1198 return yfs_fs_setattr_size(op);
1200 _enter(",%x,{%llx:%llu},,",
1201 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1203 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreStatus,
1204 sizeof(__be32) * 2 +
1205 sizeof(struct yfs_xdr_YFSFid) +
1206 sizeof(struct yfs_xdr_YFSStoreStatus),
1207 sizeof(struct yfs_xdr_YFSFetchStatus) +
1208 sizeof(struct yfs_xdr_YFSVolSync));
1209 if (!call)
1210 return afs_op_nomem(op);
1212 /* marshall the parameters */
1213 bp = call->request;
1214 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1215 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1216 bp = xdr_encode_YFSFid(bp, &vp->fid);
1217 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1218 yfs_check_req(call, bp);
1220 call->fid = vp->fid;
1221 trace_afs_make_fs_call(call, &vp->fid);
1222 afs_make_op_call(op, call, GFP_NOFS);
1226 * Deliver reply data to a YFS.GetVolumeStatus operation.
1228 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1230 struct afs_operation *op = call->op;
1231 const __be32 *bp;
1232 char *p;
1233 u32 size;
1234 int ret;
1236 _enter("{%u}", call->unmarshall);
1238 switch (call->unmarshall) {
1239 case 0:
1240 call->unmarshall++;
1241 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1242 fallthrough;
1244 /* extract the returned status record */
1245 case 1:
1246 _debug("extract status");
1247 ret = afs_extract_data(call, true);
1248 if (ret < 0)
1249 return ret;
1251 bp = call->buffer;
1252 xdr_decode_YFSFetchVolumeStatus(&bp, &op->volstatus.vs);
1253 call->unmarshall++;
1254 afs_extract_to_tmp(call);
1255 fallthrough;
1257 /* extract the volume name length */
1258 case 2:
1259 ret = afs_extract_data(call, true);
1260 if (ret < 0)
1261 return ret;
1263 call->count = ntohl(call->tmp);
1264 _debug("volname length: %u", call->count);
1265 if (call->count >= AFSNAMEMAX)
1266 return afs_protocol_error(call, afs_eproto_volname_len);
1267 size = (call->count + 3) & ~3; /* It's padded */
1268 afs_extract_to_buf(call, size);
1269 call->unmarshall++;
1270 fallthrough;
1272 /* extract the volume name */
1273 case 3:
1274 _debug("extract volname");
1275 ret = afs_extract_data(call, true);
1276 if (ret < 0)
1277 return ret;
1279 p = call->buffer;
1280 p[call->count] = 0;
1281 _debug("volname '%s'", p);
1282 afs_extract_to_tmp(call);
1283 call->unmarshall++;
1284 fallthrough;
1286 /* extract the offline message length */
1287 case 4:
1288 ret = afs_extract_data(call, true);
1289 if (ret < 0)
1290 return ret;
1292 call->count = ntohl(call->tmp);
1293 _debug("offline msg length: %u", call->count);
1294 if (call->count >= AFSNAMEMAX)
1295 return afs_protocol_error(call, afs_eproto_offline_msg_len);
1296 size = (call->count + 3) & ~3; /* It's padded */
1297 afs_extract_to_buf(call, size);
1298 call->unmarshall++;
1299 fallthrough;
1301 /* extract the offline message */
1302 case 5:
1303 _debug("extract offline");
1304 ret = afs_extract_data(call, true);
1305 if (ret < 0)
1306 return ret;
1308 p = call->buffer;
1309 p[call->count] = 0;
1310 _debug("offline '%s'", p);
1312 afs_extract_to_tmp(call);
1313 call->unmarshall++;
1314 fallthrough;
1316 /* extract the message of the day length */
1317 case 6:
1318 ret = afs_extract_data(call, true);
1319 if (ret < 0)
1320 return ret;
1322 call->count = ntohl(call->tmp);
1323 _debug("motd length: %u", call->count);
1324 if (call->count >= AFSNAMEMAX)
1325 return afs_protocol_error(call, afs_eproto_motd_len);
1326 size = (call->count + 3) & ~3; /* It's padded */
1327 afs_extract_to_buf(call, size);
1328 call->unmarshall++;
1329 fallthrough;
1331 /* extract the message of the day */
1332 case 7:
1333 _debug("extract motd");
1334 ret = afs_extract_data(call, false);
1335 if (ret < 0)
1336 return ret;
1338 p = call->buffer;
1339 p[call->count] = 0;
1340 _debug("motd '%s'", p);
1342 call->unmarshall++;
1343 fallthrough;
1345 case 8:
1346 break;
1349 _leave(" = 0 [done]");
1350 return 0;
1354 * YFS.GetVolumeStatus operation type
1356 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1357 .name = "YFS.GetVolumeStatus",
1358 .op = yfs_FS_GetVolumeStatus,
1359 .deliver = yfs_deliver_fs_get_volume_status,
1360 .destructor = afs_flat_call_destructor,
1364 * fetch the status of a volume
1366 void yfs_fs_get_volume_status(struct afs_operation *op)
1368 struct afs_vnode_param *vp = &op->file[0];
1369 struct afs_call *call;
1370 __be32 *bp;
1372 _enter("");
1374 call = afs_alloc_flat_call(op->net, &yfs_RXYFSGetVolumeStatus,
1375 sizeof(__be32) * 2 +
1376 sizeof(struct yfs_xdr_u64),
1377 max_t(size_t,
1378 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1379 sizeof(__be32),
1380 AFSOPAQUEMAX + 1));
1381 if (!call)
1382 return afs_op_nomem(op);
1384 /* marshall the parameters */
1385 bp = call->request;
1386 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1387 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1388 bp = xdr_encode_u64(bp, vp->fid.vid);
1389 yfs_check_req(call, bp);
1391 call->fid = vp->fid;
1392 trace_afs_make_fs_call(call, &vp->fid);
1393 afs_make_op_call(op, call, GFP_NOFS);
1397 * YFS.SetLock operation type
1399 static const struct afs_call_type yfs_RXYFSSetLock = {
1400 .name = "YFS.SetLock",
1401 .op = yfs_FS_SetLock,
1402 .deliver = yfs_deliver_status_and_volsync,
1403 .done = afs_lock_op_done,
1404 .destructor = afs_flat_call_destructor,
1408 * YFS.ExtendLock operation type
1410 static const struct afs_call_type yfs_RXYFSExtendLock = {
1411 .name = "YFS.ExtendLock",
1412 .op = yfs_FS_ExtendLock,
1413 .deliver = yfs_deliver_status_and_volsync,
1414 .done = afs_lock_op_done,
1415 .destructor = afs_flat_call_destructor,
1419 * YFS.ReleaseLock operation type
1421 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1422 .name = "YFS.ReleaseLock",
1423 .op = yfs_FS_ReleaseLock,
1424 .deliver = yfs_deliver_status_and_volsync,
1425 .destructor = afs_flat_call_destructor,
1429 * Set a lock on a file
1431 void yfs_fs_set_lock(struct afs_operation *op)
1433 struct afs_vnode_param *vp = &op->file[0];
1434 struct afs_call *call;
1435 __be32 *bp;
1437 _enter("");
1439 call = afs_alloc_flat_call(op->net, &yfs_RXYFSSetLock,
1440 sizeof(__be32) * 2 +
1441 sizeof(struct yfs_xdr_YFSFid) +
1442 sizeof(__be32),
1443 sizeof(struct yfs_xdr_YFSFetchStatus) +
1444 sizeof(struct yfs_xdr_YFSVolSync));
1445 if (!call)
1446 return afs_op_nomem(op);
1448 /* marshall the parameters */
1449 bp = call->request;
1450 bp = xdr_encode_u32(bp, YFSSETLOCK);
1451 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1452 bp = xdr_encode_YFSFid(bp, &vp->fid);
1453 bp = xdr_encode_u32(bp, op->lock.type);
1454 yfs_check_req(call, bp);
1456 call->fid = vp->fid;
1457 trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);
1458 afs_make_op_call(op, call, GFP_NOFS);
1462 * extend a lock on a file
1464 void yfs_fs_extend_lock(struct afs_operation *op)
1466 struct afs_vnode_param *vp = &op->file[0];
1467 struct afs_call *call;
1468 __be32 *bp;
1470 _enter("");
1472 call = afs_alloc_flat_call(op->net, &yfs_RXYFSExtendLock,
1473 sizeof(__be32) * 2 +
1474 sizeof(struct yfs_xdr_YFSFid),
1475 sizeof(struct yfs_xdr_YFSFetchStatus) +
1476 sizeof(struct yfs_xdr_YFSVolSync));
1477 if (!call)
1478 return afs_op_nomem(op);
1480 /* marshall the parameters */
1481 bp = call->request;
1482 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1483 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1484 bp = xdr_encode_YFSFid(bp, &vp->fid);
1485 yfs_check_req(call, bp);
1487 call->fid = vp->fid;
1488 trace_afs_make_fs_call(call, &vp->fid);
1489 afs_make_op_call(op, call, GFP_NOFS);
1493 * release a lock on a file
1495 void yfs_fs_release_lock(struct afs_operation *op)
1497 struct afs_vnode_param *vp = &op->file[0];
1498 struct afs_call *call;
1499 __be32 *bp;
1501 _enter("");
1503 call = afs_alloc_flat_call(op->net, &yfs_RXYFSReleaseLock,
1504 sizeof(__be32) * 2 +
1505 sizeof(struct yfs_xdr_YFSFid),
1506 sizeof(struct yfs_xdr_YFSFetchStatus) +
1507 sizeof(struct yfs_xdr_YFSVolSync));
1508 if (!call)
1509 return afs_op_nomem(op);
1511 /* marshall the parameters */
1512 bp = call->request;
1513 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1514 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1515 bp = xdr_encode_YFSFid(bp, &vp->fid);
1516 yfs_check_req(call, bp);
1518 call->fid = vp->fid;
1519 trace_afs_make_fs_call(call, &vp->fid);
1520 afs_make_op_call(op, call, GFP_NOFS);
1524 * Deliver a reply to YFS.FetchStatus
1526 static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1528 struct afs_operation *op = call->op;
1529 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1530 const __be32 *bp;
1531 int ret;
1533 ret = afs_transfer_reply(call);
1534 if (ret < 0)
1535 return ret;
1537 /* unmarshall the reply once we've received all of it */
1538 bp = call->buffer;
1539 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
1540 xdr_decode_YFSCallBack(&bp, call, &vp->scb);
1541 xdr_decode_YFSVolSync(&bp, &op->volsync);
1543 _leave(" = 0 [done]");
1544 return 0;
1548 * YFS.FetchStatus operation type
1550 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1551 .name = "YFS.FetchStatus",
1552 .op = yfs_FS_FetchStatus,
1553 .deliver = yfs_deliver_fs_fetch_status,
1554 .destructor = afs_flat_call_destructor,
1558 * Fetch the status information for a fid without needing a vnode handle.
1560 void yfs_fs_fetch_status(struct afs_operation *op)
1562 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1563 struct afs_call *call;
1564 __be32 *bp;
1566 _enter(",%x,{%llx:%llu},,",
1567 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1569 call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus,
1570 sizeof(__be32) * 2 +
1571 sizeof(struct yfs_xdr_YFSFid),
1572 sizeof(struct yfs_xdr_YFSFetchStatus) +
1573 sizeof(struct yfs_xdr_YFSCallBack) +
1574 sizeof(struct yfs_xdr_YFSVolSync));
1575 if (!call)
1576 return afs_op_nomem(op);
1578 /* marshall the parameters */
1579 bp = call->request;
1580 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1581 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1582 bp = xdr_encode_YFSFid(bp, &vp->fid);
1583 yfs_check_req(call, bp);
1585 call->fid = vp->fid;
1586 trace_afs_make_fs_call(call, &vp->fid);
1587 afs_make_op_call(op, call, GFP_NOFS);
1591 * Deliver reply data to an YFS.InlineBulkStatus call
1593 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1595 struct afs_operation *op = call->op;
1596 struct afs_status_cb *scb;
1597 const __be32 *bp;
1598 u32 tmp;
1599 int ret;
1601 _enter("{%u}", call->unmarshall);
1603 switch (call->unmarshall) {
1604 case 0:
1605 afs_extract_to_tmp(call);
1606 call->unmarshall++;
1607 fallthrough;
1609 /* Extract the file status count and array in two steps */
1610 case 1:
1611 _debug("extract status count");
1612 ret = afs_extract_data(call, true);
1613 if (ret < 0)
1614 return ret;
1616 tmp = ntohl(call->tmp);
1617 _debug("status count: %u/%u", tmp, op->nr_files);
1618 if (tmp != op->nr_files)
1619 return afs_protocol_error(call, afs_eproto_ibulkst_count);
1621 call->count = 0;
1622 call->unmarshall++;
1623 more_counts:
1624 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1625 fallthrough;
1627 case 2:
1628 _debug("extract status array %u", call->count);
1629 ret = afs_extract_data(call, true);
1630 if (ret < 0)
1631 return ret;
1633 switch (call->count) {
1634 case 0:
1635 scb = &op->file[0].scb;
1636 break;
1637 case 1:
1638 scb = &op->file[1].scb;
1639 break;
1640 default:
1641 scb = &op->more_files[call->count - 2].scb;
1642 break;
1645 bp = call->buffer;
1646 xdr_decode_YFSFetchStatus(&bp, call, scb);
1648 call->count++;
1649 if (call->count < op->nr_files)
1650 goto more_counts;
1652 call->count = 0;
1653 call->unmarshall++;
1654 afs_extract_to_tmp(call);
1655 fallthrough;
1657 /* Extract the callback count and array in two steps */
1658 case 3:
1659 _debug("extract CB count");
1660 ret = afs_extract_data(call, true);
1661 if (ret < 0)
1662 return ret;
1664 tmp = ntohl(call->tmp);
1665 _debug("CB count: %u", tmp);
1666 if (tmp != op->nr_files)
1667 return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
1668 call->count = 0;
1669 call->unmarshall++;
1670 more_cbs:
1671 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1672 fallthrough;
1674 case 4:
1675 _debug("extract CB array");
1676 ret = afs_extract_data(call, true);
1677 if (ret < 0)
1678 return ret;
1680 _debug("unmarshall CB array");
1681 switch (call->count) {
1682 case 0:
1683 scb = &op->file[0].scb;
1684 break;
1685 case 1:
1686 scb = &op->file[1].scb;
1687 break;
1688 default:
1689 scb = &op->more_files[call->count - 2].scb;
1690 break;
1693 bp = call->buffer;
1694 xdr_decode_YFSCallBack(&bp, call, scb);
1695 call->count++;
1696 if (call->count < op->nr_files)
1697 goto more_cbs;
1699 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1700 call->unmarshall++;
1701 fallthrough;
1703 case 5:
1704 ret = afs_extract_data(call, false);
1705 if (ret < 0)
1706 return ret;
1708 bp = call->buffer;
1709 xdr_decode_YFSVolSync(&bp, &op->volsync);
1711 call->unmarshall++;
1712 fallthrough;
1714 case 6:
1715 break;
1718 _leave(" = 0 [done]");
1719 return 0;
1723 * FS.InlineBulkStatus operation type
1725 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1726 .name = "YFS.InlineBulkStatus",
1727 .op = yfs_FS_InlineBulkStatus,
1728 .deliver = yfs_deliver_fs_inline_bulk_status,
1729 .destructor = afs_flat_call_destructor,
1733 * Fetch the status information for up to 1024 files
1735 void yfs_fs_inline_bulk_status(struct afs_operation *op)
1737 struct afs_vnode_param *dvp = &op->file[0];
1738 struct afs_vnode_param *vp = &op->file[1];
1739 struct afs_call *call;
1740 __be32 *bp;
1741 int i;
1743 _enter(",%x,{%llx:%llu},%u",
1744 key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);
1746 call = afs_alloc_flat_call(op->net, &yfs_RXYFSInlineBulkStatus,
1747 sizeof(__be32) +
1748 sizeof(__be32) +
1749 sizeof(__be32) +
1750 sizeof(struct yfs_xdr_YFSFid) * op->nr_files,
1751 sizeof(struct yfs_xdr_YFSFetchStatus));
1752 if (!call)
1753 return afs_op_nomem(op);
1755 /* marshall the parameters */
1756 bp = call->request;
1757 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1758 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1759 bp = xdr_encode_u32(bp, op->nr_files);
1760 bp = xdr_encode_YFSFid(bp, &dvp->fid);
1761 bp = xdr_encode_YFSFid(bp, &vp->fid);
1762 for (i = 0; i < op->nr_files - 2; i++)
1763 bp = xdr_encode_YFSFid(bp, &op->more_files[i].fid);
1764 yfs_check_req(call, bp);
1766 call->fid = vp->fid;
1767 trace_afs_make_fs_call(call, &vp->fid);
1768 afs_make_op_call(op, call, GFP_NOFS);
1772 * Deliver reply data to an YFS.FetchOpaqueACL.
1774 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1776 struct afs_operation *op = call->op;
1777 struct afs_vnode_param *vp = &op->file[0];
1778 struct yfs_acl *yacl = op->yacl;
1779 struct afs_acl *acl;
1780 const __be32 *bp;
1781 unsigned int size;
1782 int ret;
1784 _enter("{%u}", call->unmarshall);
1786 switch (call->unmarshall) {
1787 case 0:
1788 afs_extract_to_tmp(call);
1789 call->unmarshall++;
1790 fallthrough;
1792 /* Extract the file ACL length */
1793 case 1:
1794 ret = afs_extract_data(call, true);
1795 if (ret < 0)
1796 return ret;
1798 size = call->count2 = ntohl(call->tmp);
1799 size = round_up(size, 4);
1801 if (yacl->flags & YFS_ACL_WANT_ACL) {
1802 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1803 if (!acl)
1804 return -ENOMEM;
1805 yacl->acl = acl;
1806 acl->size = call->count2;
1807 afs_extract_begin(call, acl->data, size);
1808 } else {
1809 afs_extract_discard(call, size);
1811 call->unmarshall++;
1812 fallthrough;
1814 /* Extract the file ACL */
1815 case 2:
1816 ret = afs_extract_data(call, true);
1817 if (ret < 0)
1818 return ret;
1820 afs_extract_to_tmp(call);
1821 call->unmarshall++;
1822 fallthrough;
1824 /* Extract the volume ACL length */
1825 case 3:
1826 ret = afs_extract_data(call, true);
1827 if (ret < 0)
1828 return ret;
1830 size = call->count2 = ntohl(call->tmp);
1831 size = round_up(size, 4);
1833 if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
1834 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1835 if (!acl)
1836 return -ENOMEM;
1837 yacl->vol_acl = acl;
1838 acl->size = call->count2;
1839 afs_extract_begin(call, acl->data, size);
1840 } else {
1841 afs_extract_discard(call, size);
1843 call->unmarshall++;
1844 fallthrough;
1846 /* Extract the volume ACL */
1847 case 4:
1848 ret = afs_extract_data(call, true);
1849 if (ret < 0)
1850 return ret;
1852 afs_extract_to_buf(call,
1853 sizeof(__be32) * 2 +
1854 sizeof(struct yfs_xdr_YFSFetchStatus) +
1855 sizeof(struct yfs_xdr_YFSVolSync));
1856 call->unmarshall++;
1857 fallthrough;
1859 /* extract the metadata */
1860 case 5:
1861 ret = afs_extract_data(call, false);
1862 if (ret < 0)
1863 return ret;
1865 bp = call->buffer;
1866 yacl->inherit_flag = ntohl(*bp++);
1867 yacl->num_cleaned = ntohl(*bp++);
1868 xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
1869 xdr_decode_YFSVolSync(&bp, &op->volsync);
1871 call->unmarshall++;
1872 fallthrough;
1874 case 6:
1875 break;
1878 _leave(" = 0 [done]");
1879 return 0;
1882 void yfs_free_opaque_acl(struct yfs_acl *yacl)
1884 if (yacl) {
1885 kfree(yacl->acl);
1886 kfree(yacl->vol_acl);
1887 kfree(yacl);
1892 * YFS.FetchOpaqueACL operation type
1894 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
1895 .name = "YFS.FetchOpaqueACL",
1896 .op = yfs_FS_FetchOpaqueACL,
1897 .deliver = yfs_deliver_fs_fetch_opaque_acl,
1898 .destructor = afs_flat_call_destructor,
1902 * Fetch the YFS advanced ACLs for a file.
1904 void yfs_fs_fetch_opaque_acl(struct afs_operation *op)
1906 struct afs_vnode_param *vp = &op->file[0];
1907 struct afs_call *call;
1908 __be32 *bp;
1910 _enter(",%x,{%llx:%llu},,",
1911 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1913 call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchOpaqueACL,
1914 sizeof(__be32) * 2 +
1915 sizeof(struct yfs_xdr_YFSFid),
1916 sizeof(__be32) * 2 +
1917 sizeof(struct yfs_xdr_YFSFetchStatus) +
1918 sizeof(struct yfs_xdr_YFSVolSync));
1919 if (!call)
1920 return afs_op_nomem(op);
1922 /* marshall the parameters */
1923 bp = call->request;
1924 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
1925 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1926 bp = xdr_encode_YFSFid(bp, &vp->fid);
1927 yfs_check_req(call, bp);
1929 call->fid = vp->fid;
1930 trace_afs_make_fs_call(call, &vp->fid);
1931 afs_make_op_call(op, call, GFP_KERNEL);
1935 * YFS.StoreOpaqueACL2 operation type
1937 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
1938 .name = "YFS.StoreOpaqueACL2",
1939 .op = yfs_FS_StoreOpaqueACL2,
1940 .deliver = yfs_deliver_status_and_volsync,
1941 .destructor = afs_flat_call_destructor,
1945 * Fetch the YFS ACL for a file.
1947 void yfs_fs_store_opaque_acl2(struct afs_operation *op)
1949 struct afs_vnode_param *vp = &op->file[0];
1950 struct afs_call *call;
1951 struct afs_acl *acl = op->acl;
1952 size_t size;
1953 __be32 *bp;
1955 _enter(",%x,{%llx:%llu},,",
1956 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1958 size = round_up(acl->size, 4);
1959 call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreOpaqueACL2,
1960 sizeof(__be32) * 2 +
1961 sizeof(struct yfs_xdr_YFSFid) +
1962 sizeof(__be32) + size,
1963 sizeof(struct yfs_xdr_YFSFetchStatus) +
1964 sizeof(struct yfs_xdr_YFSVolSync));
1965 if (!call)
1966 return afs_op_nomem(op);
1968 /* marshall the parameters */
1969 bp = call->request;
1970 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
1971 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1972 bp = xdr_encode_YFSFid(bp, &vp->fid);
1973 bp = xdr_encode_u32(bp, acl->size);
1974 memcpy(bp, acl->data, acl->size);
1975 if (acl->size != size)
1976 memset((void *)bp + acl->size, 0, size - acl->size);
1977 bp += size / sizeof(__be32);
1978 yfs_check_req(call, bp);
1980 call->fid = vp->fid;
1981 trace_afs_make_fs_call(call, &vp->fid);
1982 afs_make_op_call(op, call, GFP_KERNEL);