blob: 3b19b009452a23bcebbce25e4c1bf66aa49b777c [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001// SPDX-License-Identifier: GPL-2.0-or-later
2/* YFS File Server client stubs
3 *
4 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
6 */
7
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"
17
18static const struct afs_fid afs_zero_fid;
19
20static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
21{
22 call->cbi = afs_get_cb_interest(cbi);
23}
24
25#define xdr_size(x) (sizeof(*x) / sizeof(__be32))
26
27static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
28{
29 const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
30
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);
35 *_bp += xdr_size(x);
36}
37
38static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
39{
40 *bp++ = htonl(n);
41 return bp;
42}
43
44static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
45{
46 struct yfs_xdr_u64 *x = (void *)bp;
47
48 *x = u64_to_xdr(n);
49 return bp + xdr_size(x);
50}
51
52static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
53{
54 struct yfs_xdr_YFSFid *x = (void *)bp;
55
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);
61}
62
63static size_t xdr_strlen(unsigned int len)
64{
65 return sizeof(__be32) + round_up(len, sizeof(__be32));
66}
67
68static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
69{
70 bp = xdr_encode_u32(bp, len);
71 bp = memcpy(bp, p, len);
72 if (len & 3) {
73 unsigned int pad = 4 - (len & 3);
74
75 memset((u8 *)bp + len, 0, pad);
76 len += pad;
77 }
78
79 return bp + len / sizeof(__be32);
80}
81
82static s64 linux_to_yfs_time(const struct timespec64 *t)
83{
84 /* Convert to 100ns intervals. */
85 return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
86}
87
88static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
89{
90 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
91
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);
98}
99
100static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
101{
102 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
103 s64 mtime = linux_to_yfs_time(t);
104
105 x->mask = htonl(AFS_SET_MTIME);
106 x->mode = htonl(0);
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);
111}
112
113/*
114 * Convert a signed 100ns-resolution 64-bit time into a timespec.
115 */
116static struct timespec64 yfs_time_to_linux(s64 t)
117{
118 struct timespec64 ts;
119 u64 abs_t;
120
121 /*
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
125 */
126 if (t < 0) {
127 abs_t = -t;
128 ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
129 ts.tv_nsec = -ts.tv_nsec;
130 ts.tv_sec = -abs_t;
131 } else {
132 abs_t = t;
133 ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
134 ts.tv_sec = abs_t;
135 }
136
137 return ts;
138}
139
140static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
141{
142 s64 t = xdr_to_u64(xdr);
143
144 return yfs_time_to_linux(t);
145}
146
147static void yfs_check_req(struct afs_call *call, __be32 *bp)
148{
149 size_t len = (void *)bp - call->request;
150
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);
157}
158
159/*
160 * Dump a bad file status record.
161 */
162static void xdr_dump_bad(const __be32 *bp)
163{
164 __be32 x[4];
165 int i;
166
167 pr_notice("YFS XDR: Bad status record\n");
Olivier Deprez0e641232021-09-23 10:07:05 +0200168 for (i = 0; i < 6 * 4 * 4; i += 16) {
David Brazdil0f672f62019-12-10 10:32:29 +0000169 memcpy(x, bp, 16);
170 bp += 4;
171 pr_notice("%03x: %08x %08x %08x %08x\n",
172 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
173 }
174
Olivier Deprez0e641232021-09-23 10:07:05 +0200175 memcpy(x, bp, 8);
176 pr_notice("0x60: %08x %08x\n", ntohl(x[0]), ntohl(x[1]));
David Brazdil0f672f62019-12-10 10:32:29 +0000177}
178
179/*
180 * Decode a YFSFetchStatus block
181 */
Olivier Deprez0e641232021-09-23 10:07:05 +0200182static void xdr_decode_YFSFetchStatus(const __be32 **_bp,
183 struct afs_call *call,
184 struct afs_status_cb *scb)
David Brazdil0f672f62019-12-10 10:32:29 +0000185{
186 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
187 struct afs_file_status *status = &scb->status;
188 u32 type;
189
190 status->abort_code = ntohl(xdr->abort_code);
191 if (status->abort_code != 0) {
192 if (status->abort_code == VNOVNODE)
193 status->nlink = 0;
194 scb->have_error = true;
Olivier Deprez0e641232021-09-23 10:07:05 +0200195 goto advance;
David Brazdil0f672f62019-12-10 10:32:29 +0000196 }
197
198 type = ntohl(xdr->type);
199 switch (type) {
200 case AFS_FTYPE_FILE:
201 case AFS_FTYPE_DIR:
202 case AFS_FTYPE_SYMLINK:
203 status->type = type;
204 break;
205 default:
206 goto bad;
207 }
208
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);
217
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;
Olivier Deprez0e641232021-09-23 10:07:05 +0200223advance:
David Brazdil0f672f62019-12-10 10:32:29 +0000224 *_bp += xdr_size(xdr);
Olivier Deprez0e641232021-09-23 10:07:05 +0200225 return;
David Brazdil0f672f62019-12-10 10:32:29 +0000226
227bad:
228 xdr_dump_bad(*_bp);
Olivier Deprez0e641232021-09-23 10:07:05 +0200229 afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
230 goto advance;
David Brazdil0f672f62019-12-10 10:32:29 +0000231}
232
233/*
234 * Decode a YFSCallBack block
235 */
236static void xdr_decode_YFSCallBack(const __be32 **_bp,
237 struct afs_call *call,
238 struct afs_status_cb *scb)
239{
240 struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
241 struct afs_callback *cb = &scb->callback;
242 ktime_t cb_expiry;
243
244 cb_expiry = call->reply_time;
245 cb_expiry = ktime_add(cb_expiry, xdr_to_u64(x->expiration_time) * 100);
246 cb->expires_at = ktime_divns(cb_expiry, NSEC_PER_SEC);
247 scb->have_cb = true;
248 *_bp += xdr_size(x);
249}
250
251/*
252 * Decode a YFSVolSync block
253 */
254static void xdr_decode_YFSVolSync(const __be32 **_bp,
255 struct afs_volsync *volsync)
256{
257 struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
258 u64 creation;
259
260 if (volsync) {
261 creation = xdr_to_u64(x->vol_creation_date);
262 do_div(creation, 10 * 1000 * 1000);
263 volsync->creation = creation;
264 }
265
266 *_bp += xdr_size(x);
267}
268
269/*
270 * Encode the requested attributes into a YFSStoreStatus block
271 */
272static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
273{
274 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
275 s64 mtime = 0, owner = 0, group = 0;
276 u32 mask = 0, mode = 0;
277
278 mask = 0;
279 if (attr->ia_valid & ATTR_MTIME) {
280 mask |= AFS_SET_MTIME;
281 mtime = linux_to_yfs_time(&attr->ia_mtime);
282 }
283
284 if (attr->ia_valid & ATTR_UID) {
285 mask |= AFS_SET_OWNER;
286 owner = from_kuid(&init_user_ns, attr->ia_uid);
287 }
288
289 if (attr->ia_valid & ATTR_GID) {
290 mask |= AFS_SET_GROUP;
291 group = from_kgid(&init_user_ns, attr->ia_gid);
292 }
293
294 if (attr->ia_valid & ATTR_MODE) {
295 mask |= AFS_SET_MODE;
296 mode = attr->ia_mode & S_IALLUGO;
297 }
298
299 x->mask = htonl(mask);
300 x->mode = htonl(mode);
301 x->mtime_client = u64_to_xdr(mtime);
302 x->owner = u64_to_xdr(owner);
303 x->group = u64_to_xdr(group);
304 return bp + xdr_size(x);
305}
306
307/*
308 * Decode a YFSFetchVolumeStatus block.
309 */
310static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
311 struct afs_volume_status *vs)
312{
313 const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
314 u32 flags;
315
316 vs->vid = xdr_to_u64(x->vid);
317 vs->parent_id = xdr_to_u64(x->parent_id);
318 flags = ntohl(x->flags);
319 vs->online = flags & yfs_FVSOnline;
320 vs->in_service = flags & yfs_FVSInservice;
321 vs->blessed = flags & yfs_FVSBlessed;
322 vs->needs_salvage = flags & yfs_FVSNeedsSalvage;
323 vs->type = ntohl(x->type);
324 vs->min_quota = 0;
325 vs->max_quota = xdr_to_u64(x->max_quota);
326 vs->blocks_in_use = xdr_to_u64(x->blocks_in_use);
327 vs->part_blocks_avail = xdr_to_u64(x->part_blocks_avail);
328 vs->part_max_blocks = xdr_to_u64(x->part_max_blocks);
329 vs->vol_copy_date = xdr_to_u64(x->vol_copy_date);
330 vs->vol_backup_date = xdr_to_u64(x->vol_backup_date);
331 *_bp += sizeof(*x) / sizeof(__be32);
332}
333
334/*
335 * Deliver a reply that's a status, callback and volsync.
336 */
337static int yfs_deliver_fs_status_cb_and_volsync(struct afs_call *call)
338{
339 const __be32 *bp;
340 int ret;
341
342 ret = afs_transfer_reply(call);
343 if (ret < 0)
344 return ret;
345
346 /* unmarshall the reply once we've received all of it */
347 bp = call->buffer;
Olivier Deprez0e641232021-09-23 10:07:05 +0200348 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000349 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
350 xdr_decode_YFSVolSync(&bp, call->out_volsync);
351
352 _leave(" = 0 [done]");
353 return 0;
354}
355
356/*
357 * Deliver reply data to operations that just return a file status and a volume
358 * sync record.
359 */
360static int yfs_deliver_status_and_volsync(struct afs_call *call)
361{
362 const __be32 *bp;
363 int ret;
364
365 ret = afs_transfer_reply(call);
366 if (ret < 0)
367 return ret;
368
369 bp = call->buffer;
Olivier Deprez0e641232021-09-23 10:07:05 +0200370 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000371 xdr_decode_YFSVolSync(&bp, call->out_volsync);
372
373 _leave(" = 0 [done]");
374 return 0;
375}
376
377/*
378 * YFS.FetchStatus operation type
379 */
380static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = {
381 .name = "YFS.FetchStatus(vnode)",
382 .op = yfs_FS_FetchStatus,
383 .deliver = yfs_deliver_fs_status_cb_and_volsync,
384 .destructor = afs_flat_call_destructor,
385};
386
387/*
388 * Fetch the status information for a file.
389 */
390int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
391 struct afs_volsync *volsync)
392{
393 struct afs_vnode *vnode = fc->vnode;
394 struct afs_call *call;
395 struct afs_net *net = afs_v2net(vnode);
396 __be32 *bp;
397
398 _enter(",%x,{%llx:%llu},,",
399 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
400
401 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode,
402 sizeof(__be32) * 2 +
403 sizeof(struct yfs_xdr_YFSFid),
404 sizeof(struct yfs_xdr_YFSFetchStatus) +
405 sizeof(struct yfs_xdr_YFSCallBack) +
406 sizeof(struct yfs_xdr_YFSVolSync));
407 if (!call) {
408 fc->ac.error = -ENOMEM;
409 return -ENOMEM;
410 }
411
412 call->key = fc->key;
413 call->out_scb = scb;
414 call->out_volsync = volsync;
415
416 /* marshall the parameters */
417 bp = call->request;
418 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
419 bp = xdr_encode_u32(bp, 0); /* RPC flags */
420 bp = xdr_encode_YFSFid(bp, &vnode->fid);
421 yfs_check_req(call, bp);
422
423 afs_use_fs_server(call, fc->cbi);
424 trace_afs_make_fs_call(call, &vnode->fid);
425 afs_set_fc_call(call, fc);
426 afs_make_call(&fc->ac, call, GFP_NOFS);
427 return afs_wait_for_call_to_complete(call, &fc->ac);
428}
429
430/*
431 * Deliver reply data to an YFS.FetchData64.
432 */
433static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
434{
435 struct afs_read *req = call->read_request;
436 const __be32 *bp;
437 unsigned int size;
438 int ret;
439
440 _enter("{%u,%zu/%llu}",
441 call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
442
443 switch (call->unmarshall) {
444 case 0:
445 req->actual_len = 0;
446 req->index = 0;
447 req->offset = req->pos & (PAGE_SIZE - 1);
448 afs_extract_to_tmp64(call);
449 call->unmarshall++;
450 /* Fall through */
451
452 /* extract the returned data length */
453 case 1:
454 _debug("extract data length");
455 ret = afs_extract_data(call, true);
456 if (ret < 0)
457 return ret;
458
459 req->actual_len = be64_to_cpu(call->tmp64);
460 _debug("DATA length: %llu", req->actual_len);
461 req->remain = min(req->len, req->actual_len);
462 if (req->remain == 0)
463 goto no_more_data;
464
465 call->unmarshall++;
466
467 begin_page:
468 ASSERTCMP(req->index, <, req->nr_pages);
469 if (req->remain > PAGE_SIZE - req->offset)
470 size = PAGE_SIZE - req->offset;
471 else
472 size = req->remain;
473 call->bvec[0].bv_len = size;
474 call->bvec[0].bv_offset = req->offset;
475 call->bvec[0].bv_page = req->pages[req->index];
476 iov_iter_bvec(&call->iter, READ, call->bvec, 1, size);
477 ASSERTCMP(size, <=, PAGE_SIZE);
478 /* Fall through */
479
480 /* extract the returned data */
481 case 2:
482 _debug("extract data %zu/%llu",
483 iov_iter_count(&call->iter), req->remain);
484
485 ret = afs_extract_data(call, true);
486 if (ret < 0)
487 return ret;
488 req->remain -= call->bvec[0].bv_len;
489 req->offset += call->bvec[0].bv_len;
490 ASSERTCMP(req->offset, <=, PAGE_SIZE);
491 if (req->offset == PAGE_SIZE) {
492 req->offset = 0;
David Brazdil0f672f62019-12-10 10:32:29 +0000493 req->index++;
494 if (req->remain > 0)
495 goto begin_page;
496 }
497
498 ASSERTCMP(req->remain, ==, 0);
499 if (req->actual_len <= req->len)
500 goto no_more_data;
501
502 /* Discard any excess data the server gave us */
503 afs_extract_discard(call, req->actual_len - req->len);
504 call->unmarshall = 3;
505 /* Fall through */
506
507 case 3:
508 _debug("extract discard %zu/%llu",
509 iov_iter_count(&call->iter), req->actual_len - req->len);
510
511 ret = afs_extract_data(call, true);
512 if (ret < 0)
513 return ret;
514
515 no_more_data:
516 call->unmarshall = 4;
517 afs_extract_to_buf(call,
518 sizeof(struct yfs_xdr_YFSFetchStatus) +
519 sizeof(struct yfs_xdr_YFSCallBack) +
520 sizeof(struct yfs_xdr_YFSVolSync));
521 /* Fall through */
522
523 /* extract the metadata */
524 case 4:
525 ret = afs_extract_data(call, false);
526 if (ret < 0)
527 return ret;
528
529 bp = call->buffer;
Olivier Deprez0e641232021-09-23 10:07:05 +0200530 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000531 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
532 xdr_decode_YFSVolSync(&bp, call->out_volsync);
533
534 req->data_version = call->out_scb->status.data_version;
535 req->file_size = call->out_scb->status.size;
536
537 call->unmarshall++;
538 /* Fall through */
539
540 case 5:
541 break;
542 }
543
544 for (; req->index < req->nr_pages; req->index++) {
545 if (req->offset < PAGE_SIZE)
546 zero_user_segment(req->pages[req->index],
547 req->offset, PAGE_SIZE);
David Brazdil0f672f62019-12-10 10:32:29 +0000548 req->offset = 0;
549 }
550
Olivier Deprez0e641232021-09-23 10:07:05 +0200551 if (req->page_done)
552 for (req->index = 0; req->index < req->nr_pages; req->index++)
553 req->page_done(req);
554
David Brazdil0f672f62019-12-10 10:32:29 +0000555 _leave(" = 0 [done]");
556 return 0;
557}
558
559static void yfs_fetch_data_destructor(struct afs_call *call)
560{
561 afs_put_read(call->read_request);
562 afs_flat_call_destructor(call);
563}
564
565/*
566 * YFS.FetchData64 operation type
567 */
568static const struct afs_call_type yfs_RXYFSFetchData64 = {
569 .name = "YFS.FetchData64",
570 .op = yfs_FS_FetchData64,
571 .deliver = yfs_deliver_fs_fetch_data64,
572 .destructor = yfs_fetch_data_destructor,
573};
574
575/*
576 * Fetch data from a file.
577 */
578int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_status_cb *scb,
579 struct afs_read *req)
580{
581 struct afs_vnode *vnode = fc->vnode;
582 struct afs_call *call;
583 struct afs_net *net = afs_v2net(vnode);
584 __be32 *bp;
585
586 _enter(",%x,{%llx:%llu},%llx,%llx",
587 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
588 req->pos, req->len);
589
590 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
591 sizeof(__be32) * 2 +
592 sizeof(struct yfs_xdr_YFSFid) +
593 sizeof(struct yfs_xdr_u64) * 2,
594 sizeof(struct yfs_xdr_YFSFetchStatus) +
595 sizeof(struct yfs_xdr_YFSCallBack) +
596 sizeof(struct yfs_xdr_YFSVolSync));
597 if (!call)
598 return -ENOMEM;
599
600 call->key = fc->key;
601 call->out_scb = scb;
602 call->out_volsync = NULL;
603 call->read_request = req;
604
605 /* marshall the parameters */
606 bp = call->request;
607 bp = xdr_encode_u32(bp, YFSFETCHDATA64);
608 bp = xdr_encode_u32(bp, 0); /* RPC flags */
609 bp = xdr_encode_YFSFid(bp, &vnode->fid);
610 bp = xdr_encode_u64(bp, req->pos);
611 bp = xdr_encode_u64(bp, req->len);
612 yfs_check_req(call, bp);
613
614 refcount_inc(&req->usage);
615 afs_use_fs_server(call, fc->cbi);
616 trace_afs_make_fs_call(call, &vnode->fid);
617 afs_set_fc_call(call, fc);
618 afs_make_call(&fc->ac, call, GFP_NOFS);
619 return afs_wait_for_call_to_complete(call, &fc->ac);
620}
621
622/*
623 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
624 */
625static int yfs_deliver_fs_create_vnode(struct afs_call *call)
626{
627 const __be32 *bp;
628 int ret;
629
630 _enter("{%u}", call->unmarshall);
631
632 ret = afs_transfer_reply(call);
633 if (ret < 0)
634 return ret;
635
636 /* unmarshall the reply once we've received all of it */
637 bp = call->buffer;
638 xdr_decode_YFSFid(&bp, call->out_fid);
Olivier Deprez0e641232021-09-23 10:07:05 +0200639 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
640 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000641 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
642 xdr_decode_YFSVolSync(&bp, call->out_volsync);
643
644 _leave(" = 0 [done]");
645 return 0;
646}
647
648/*
649 * FS.CreateFile and FS.MakeDir operation type
650 */
651static const struct afs_call_type afs_RXFSCreateFile = {
652 .name = "YFS.CreateFile",
653 .op = yfs_FS_CreateFile,
654 .deliver = yfs_deliver_fs_create_vnode,
655 .destructor = afs_flat_call_destructor,
656};
657
658/*
659 * Create a file.
660 */
661int yfs_fs_create_file(struct afs_fs_cursor *fc,
662 const char *name,
663 umode_t mode,
664 struct afs_status_cb *dvnode_scb,
665 struct afs_fid *newfid,
666 struct afs_status_cb *new_scb)
667{
668 struct afs_vnode *dvnode = fc->vnode;
669 struct afs_call *call;
670 struct afs_net *net = afs_v2net(dvnode);
671 size_t namesz, reqsz, rplsz;
672 __be32 *bp;
673
674 _enter("");
675
676 namesz = strlen(name);
677 reqsz = (sizeof(__be32) +
678 sizeof(__be32) +
679 sizeof(struct yfs_xdr_YFSFid) +
680 xdr_strlen(namesz) +
681 sizeof(struct yfs_xdr_YFSStoreStatus) +
682 sizeof(__be32));
683 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
684 sizeof(struct yfs_xdr_YFSFetchStatus) +
685 sizeof(struct yfs_xdr_YFSFetchStatus) +
686 sizeof(struct yfs_xdr_YFSCallBack) +
687 sizeof(struct yfs_xdr_YFSVolSync));
688
689 call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
690 if (!call)
691 return -ENOMEM;
692
693 call->key = fc->key;
694 call->out_dir_scb = dvnode_scb;
695 call->out_fid = newfid;
696 call->out_scb = new_scb;
697
698 /* marshall the parameters */
699 bp = call->request;
700 bp = xdr_encode_u32(bp, YFSCREATEFILE);
701 bp = xdr_encode_u32(bp, 0); /* RPC flags */
702 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
703 bp = xdr_encode_string(bp, name, namesz);
704 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
705 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
706 yfs_check_req(call, bp);
707
708 afs_use_fs_server(call, fc->cbi);
709 trace_afs_make_fs_call1(call, &dvnode->fid, name);
710 afs_set_fc_call(call, fc);
711 afs_make_call(&fc->ac, call, GFP_NOFS);
712 return afs_wait_for_call_to_complete(call, &fc->ac);
713}
714
715static const struct afs_call_type yfs_RXFSMakeDir = {
716 .name = "YFS.MakeDir",
717 .op = yfs_FS_MakeDir,
718 .deliver = yfs_deliver_fs_create_vnode,
719 .destructor = afs_flat_call_destructor,
720};
721
722/*
723 * Make a directory.
724 */
725int yfs_fs_make_dir(struct afs_fs_cursor *fc,
726 const char *name,
727 umode_t mode,
728 struct afs_status_cb *dvnode_scb,
729 struct afs_fid *newfid,
730 struct afs_status_cb *new_scb)
731{
732 struct afs_vnode *dvnode = fc->vnode;
733 struct afs_call *call;
734 struct afs_net *net = afs_v2net(dvnode);
735 size_t namesz, reqsz, rplsz;
736 __be32 *bp;
737
738 _enter("");
739
740 namesz = strlen(name);
741 reqsz = (sizeof(__be32) +
742 sizeof(struct yfs_xdr_RPCFlags) +
743 sizeof(struct yfs_xdr_YFSFid) +
744 xdr_strlen(namesz) +
745 sizeof(struct yfs_xdr_YFSStoreStatus));
746 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
747 sizeof(struct yfs_xdr_YFSFetchStatus) +
748 sizeof(struct yfs_xdr_YFSFetchStatus) +
749 sizeof(struct yfs_xdr_YFSCallBack) +
750 sizeof(struct yfs_xdr_YFSVolSync));
751
752 call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
753 if (!call)
754 return -ENOMEM;
755
756 call->key = fc->key;
757 call->out_dir_scb = dvnode_scb;
758 call->out_fid = newfid;
759 call->out_scb = new_scb;
760
761 /* marshall the parameters */
762 bp = call->request;
763 bp = xdr_encode_u32(bp, YFSMAKEDIR);
764 bp = xdr_encode_u32(bp, 0); /* RPC flags */
765 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
766 bp = xdr_encode_string(bp, name, namesz);
767 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
768 yfs_check_req(call, bp);
769
770 afs_use_fs_server(call, fc->cbi);
771 trace_afs_make_fs_call1(call, &dvnode->fid, name);
772 afs_set_fc_call(call, fc);
773 afs_make_call(&fc->ac, call, GFP_NOFS);
774 return afs_wait_for_call_to_complete(call, &fc->ac);
775}
776
777/*
778 * Deliver reply data to a YFS.RemoveFile2 operation.
779 */
780static int yfs_deliver_fs_remove_file2(struct afs_call *call)
781{
782 struct afs_fid fid;
783 const __be32 *bp;
784 int ret;
785
786 _enter("{%u}", call->unmarshall);
787
788 ret = afs_transfer_reply(call);
789 if (ret < 0)
790 return ret;
791
792 bp = call->buffer;
Olivier Deprez0e641232021-09-23 10:07:05 +0200793 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000794 xdr_decode_YFSFid(&bp, &fid);
Olivier Deprez0e641232021-09-23 10:07:05 +0200795 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000796 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
797
798 xdr_decode_YFSVolSync(&bp, call->out_volsync);
799 return 0;
800}
801
802/*
803 * YFS.RemoveFile2 operation type.
804 */
805static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
806 .name = "YFS.RemoveFile2",
807 .op = yfs_FS_RemoveFile2,
808 .deliver = yfs_deliver_fs_remove_file2,
809 .destructor = afs_flat_call_destructor,
810};
811
812/*
813 * Remove a file and retrieve new file status.
814 */
815int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
816 const char *name, struct afs_status_cb *dvnode_scb,
817 struct afs_status_cb *vnode_scb)
818{
819 struct afs_vnode *dvnode = fc->vnode;
820 struct afs_call *call;
821 struct afs_net *net = afs_v2net(dvnode);
822 size_t namesz;
823 __be32 *bp;
824
825 _enter("");
826
827 namesz = strlen(name);
828
829 call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
830 sizeof(__be32) +
831 sizeof(struct yfs_xdr_RPCFlags) +
832 sizeof(struct yfs_xdr_YFSFid) +
833 xdr_strlen(namesz),
834 sizeof(struct yfs_xdr_YFSFetchStatus) +
835 sizeof(struct yfs_xdr_YFSFid) +
836 sizeof(struct yfs_xdr_YFSFetchStatus) +
837 sizeof(struct yfs_xdr_YFSVolSync));
838 if (!call)
839 return -ENOMEM;
840
841 call->key = fc->key;
842 call->out_dir_scb = dvnode_scb;
843 call->out_scb = vnode_scb;
844
845 /* marshall the parameters */
846 bp = call->request;
847 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
848 bp = xdr_encode_u32(bp, 0); /* RPC flags */
849 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
850 bp = xdr_encode_string(bp, name, namesz);
851 yfs_check_req(call, bp);
852
853 afs_use_fs_server(call, fc->cbi);
854 trace_afs_make_fs_call1(call, &dvnode->fid, name);
855 afs_set_fc_call(call, fc);
856 afs_make_call(&fc->ac, call, GFP_NOFS);
857 return afs_wait_for_call_to_complete(call, &fc->ac);
858}
859
860/*
861 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
862 */
863static int yfs_deliver_fs_remove(struct afs_call *call)
864{
865 const __be32 *bp;
866 int ret;
867
868 _enter("{%u}", call->unmarshall);
869
870 ret = afs_transfer_reply(call);
871 if (ret < 0)
872 return ret;
873
874 bp = call->buffer;
Olivier Deprez0e641232021-09-23 10:07:05 +0200875 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000876 xdr_decode_YFSVolSync(&bp, call->out_volsync);
877 return 0;
878}
879
880/*
881 * FS.RemoveDir and FS.RemoveFile operation types.
882 */
883static const struct afs_call_type yfs_RXYFSRemoveFile = {
884 .name = "YFS.RemoveFile",
885 .op = yfs_FS_RemoveFile,
886 .deliver = yfs_deliver_fs_remove,
887 .destructor = afs_flat_call_destructor,
888};
889
890static const struct afs_call_type yfs_RXYFSRemoveDir = {
891 .name = "YFS.RemoveDir",
892 .op = yfs_FS_RemoveDir,
893 .deliver = yfs_deliver_fs_remove,
894 .destructor = afs_flat_call_destructor,
895};
896
897/*
898 * remove a file or directory
899 */
900int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
901 const char *name, bool isdir,
902 struct afs_status_cb *dvnode_scb)
903{
904 struct afs_vnode *dvnode = fc->vnode;
905 struct afs_call *call;
906 struct afs_net *net = afs_v2net(dvnode);
907 size_t namesz;
908 __be32 *bp;
909
910 _enter("");
911
912 namesz = strlen(name);
913 call = afs_alloc_flat_call(
914 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
915 sizeof(__be32) +
916 sizeof(struct yfs_xdr_RPCFlags) +
917 sizeof(struct yfs_xdr_YFSFid) +
918 xdr_strlen(namesz),
919 sizeof(struct yfs_xdr_YFSFetchStatus) +
920 sizeof(struct yfs_xdr_YFSVolSync));
921 if (!call)
922 return -ENOMEM;
923
924 call->key = fc->key;
925 call->out_dir_scb = dvnode_scb;
926
927 /* marshall the parameters */
928 bp = call->request;
929 bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
930 bp = xdr_encode_u32(bp, 0); /* RPC flags */
931 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
932 bp = xdr_encode_string(bp, name, namesz);
933 yfs_check_req(call, bp);
934
935 afs_use_fs_server(call, fc->cbi);
936 trace_afs_make_fs_call1(call, &dvnode->fid, name);
937 afs_set_fc_call(call, fc);
938 afs_make_call(&fc->ac, call, GFP_NOFS);
939 return afs_wait_for_call_to_complete(call, &fc->ac);
940}
941
942/*
943 * Deliver reply data to a YFS.Link operation.
944 */
945static int yfs_deliver_fs_link(struct afs_call *call)
946{
947 const __be32 *bp;
948 int ret;
949
950 _enter("{%u}", call->unmarshall);
951
952 ret = afs_transfer_reply(call);
953 if (ret < 0)
954 return ret;
955
956 bp = call->buffer;
Olivier Deprez0e641232021-09-23 10:07:05 +0200957 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
958 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
David Brazdil0f672f62019-12-10 10:32:29 +0000959 xdr_decode_YFSVolSync(&bp, call->out_volsync);
960 _leave(" = 0 [done]");
961 return 0;
962}
963
964/*
965 * YFS.Link operation type.
966 */
967static const struct afs_call_type yfs_RXYFSLink = {
968 .name = "YFS.Link",
969 .op = yfs_FS_Link,
970 .deliver = yfs_deliver_fs_link,
971 .destructor = afs_flat_call_destructor,
972};
973
974/*
975 * Make a hard link.
976 */
977int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
978 const char *name,
979 struct afs_status_cb *dvnode_scb,
980 struct afs_status_cb *vnode_scb)
981{
982 struct afs_vnode *dvnode = fc->vnode;
983 struct afs_call *call;
984 struct afs_net *net = afs_v2net(vnode);
985 size_t namesz;
986 __be32 *bp;
987
988 _enter("");
989
990 namesz = strlen(name);
991 call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
992 sizeof(__be32) +
993 sizeof(struct yfs_xdr_RPCFlags) +
994 sizeof(struct yfs_xdr_YFSFid) +
995 xdr_strlen(namesz) +
996 sizeof(struct yfs_xdr_YFSFid),
997 sizeof(struct yfs_xdr_YFSFetchStatus) +
998 sizeof(struct yfs_xdr_YFSFetchStatus) +
999 sizeof(struct yfs_xdr_YFSVolSync));
1000 if (!call)
1001 return -ENOMEM;
1002
1003 call->key = fc->key;
1004 call->out_dir_scb = dvnode_scb;
1005 call->out_scb = vnode_scb;
1006
1007 /* marshall the parameters */
1008 bp = call->request;
1009 bp = xdr_encode_u32(bp, YFSLINK);
1010 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1011 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1012 bp = xdr_encode_string(bp, name, namesz);
1013 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1014 yfs_check_req(call, bp);
1015
1016 afs_use_fs_server(call, fc->cbi);
1017 trace_afs_make_fs_call1(call, &vnode->fid, name);
1018 afs_set_fc_call(call, fc);
1019 afs_make_call(&fc->ac, call, GFP_NOFS);
1020 return afs_wait_for_call_to_complete(call, &fc->ac);
1021}
1022
1023/*
1024 * Deliver reply data to a YFS.Symlink operation.
1025 */
1026static int yfs_deliver_fs_symlink(struct afs_call *call)
1027{
1028 const __be32 *bp;
1029 int ret;
1030
1031 _enter("{%u}", call->unmarshall);
1032
1033 ret = afs_transfer_reply(call);
1034 if (ret < 0)
1035 return ret;
1036
1037 /* unmarshall the reply once we've received all of it */
1038 bp = call->buffer;
1039 xdr_decode_YFSFid(&bp, call->out_fid);
Olivier Deprez0e641232021-09-23 10:07:05 +02001040 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1041 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
David Brazdil0f672f62019-12-10 10:32:29 +00001042 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1043
1044 _leave(" = 0 [done]");
1045 return 0;
1046}
1047
1048/*
1049 * YFS.Symlink operation type
1050 */
1051static const struct afs_call_type yfs_RXYFSSymlink = {
1052 .name = "YFS.Symlink",
1053 .op = yfs_FS_Symlink,
1054 .deliver = yfs_deliver_fs_symlink,
1055 .destructor = afs_flat_call_destructor,
1056};
1057
1058/*
1059 * Create a symbolic link.
1060 */
1061int yfs_fs_symlink(struct afs_fs_cursor *fc,
1062 const char *name,
1063 const char *contents,
1064 struct afs_status_cb *dvnode_scb,
1065 struct afs_fid *newfid,
1066 struct afs_status_cb *vnode_scb)
1067{
1068 struct afs_vnode *dvnode = fc->vnode;
1069 struct afs_call *call;
1070 struct afs_net *net = afs_v2net(dvnode);
1071 size_t namesz, contents_sz;
1072 __be32 *bp;
1073
1074 _enter("");
1075
1076 namesz = strlen(name);
1077 contents_sz = strlen(contents);
1078 call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1079 sizeof(__be32) +
1080 sizeof(struct yfs_xdr_RPCFlags) +
1081 sizeof(struct yfs_xdr_YFSFid) +
1082 xdr_strlen(namesz) +
1083 xdr_strlen(contents_sz) +
1084 sizeof(struct yfs_xdr_YFSStoreStatus),
1085 sizeof(struct yfs_xdr_YFSFid) +
1086 sizeof(struct yfs_xdr_YFSFetchStatus) +
1087 sizeof(struct yfs_xdr_YFSFetchStatus) +
1088 sizeof(struct yfs_xdr_YFSVolSync));
1089 if (!call)
1090 return -ENOMEM;
1091
1092 call->key = fc->key;
1093 call->out_dir_scb = dvnode_scb;
1094 call->out_fid = newfid;
1095 call->out_scb = vnode_scb;
1096
1097 /* marshall the parameters */
1098 bp = call->request;
1099 bp = xdr_encode_u32(bp, YFSSYMLINK);
1100 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1101 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1102 bp = xdr_encode_string(bp, name, namesz);
1103 bp = xdr_encode_string(bp, contents, contents_sz);
1104 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1105 yfs_check_req(call, bp);
1106
1107 afs_use_fs_server(call, fc->cbi);
1108 trace_afs_make_fs_call1(call, &dvnode->fid, name);
1109 afs_set_fc_call(call, fc);
1110 afs_make_call(&fc->ac, call, GFP_NOFS);
1111 return afs_wait_for_call_to_complete(call, &fc->ac);
1112}
1113
1114/*
1115 * Deliver reply data to a YFS.Rename operation.
1116 */
1117static int yfs_deliver_fs_rename(struct afs_call *call)
1118{
1119 const __be32 *bp;
1120 int ret;
1121
1122 _enter("{%u}", call->unmarshall);
1123
1124 ret = afs_transfer_reply(call);
1125 if (ret < 0)
1126 return ret;
1127
1128 bp = call->buffer;
Olivier Deprez0e641232021-09-23 10:07:05 +02001129 /* If the two dirs are the same, we have two copies of the same status
1130 * report, so we just decode it twice.
1131 */
1132 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1133 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
David Brazdil0f672f62019-12-10 10:32:29 +00001134 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1135 _leave(" = 0 [done]");
1136 return 0;
1137}
1138
1139/*
1140 * YFS.Rename operation type
1141 */
1142static const struct afs_call_type yfs_RXYFSRename = {
1143 .name = "FS.Rename",
1144 .op = yfs_FS_Rename,
1145 .deliver = yfs_deliver_fs_rename,
1146 .destructor = afs_flat_call_destructor,
1147};
1148
1149/*
1150 * Rename a file or directory.
1151 */
1152int yfs_fs_rename(struct afs_fs_cursor *fc,
1153 const char *orig_name,
1154 struct afs_vnode *new_dvnode,
1155 const char *new_name,
1156 struct afs_status_cb *orig_dvnode_scb,
1157 struct afs_status_cb *new_dvnode_scb)
1158{
1159 struct afs_vnode *orig_dvnode = fc->vnode;
1160 struct afs_call *call;
1161 struct afs_net *net = afs_v2net(orig_dvnode);
1162 size_t o_namesz, n_namesz;
1163 __be32 *bp;
1164
1165 _enter("");
1166
1167 o_namesz = strlen(orig_name);
1168 n_namesz = strlen(new_name);
1169 call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1170 sizeof(__be32) +
1171 sizeof(struct yfs_xdr_RPCFlags) +
1172 sizeof(struct yfs_xdr_YFSFid) +
1173 xdr_strlen(o_namesz) +
1174 sizeof(struct yfs_xdr_YFSFid) +
1175 xdr_strlen(n_namesz),
1176 sizeof(struct yfs_xdr_YFSFetchStatus) +
1177 sizeof(struct yfs_xdr_YFSFetchStatus) +
1178 sizeof(struct yfs_xdr_YFSVolSync));
1179 if (!call)
1180 return -ENOMEM;
1181
1182 call->key = fc->key;
1183 call->out_dir_scb = orig_dvnode_scb;
1184 call->out_scb = new_dvnode_scb;
1185
1186 /* marshall the parameters */
1187 bp = call->request;
1188 bp = xdr_encode_u32(bp, YFSRENAME);
1189 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1190 bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1191 bp = xdr_encode_string(bp, orig_name, o_namesz);
1192 bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1193 bp = xdr_encode_string(bp, new_name, n_namesz);
1194 yfs_check_req(call, bp);
1195
1196 afs_use_fs_server(call, fc->cbi);
1197 trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
1198 afs_set_fc_call(call, fc);
1199 afs_make_call(&fc->ac, call, GFP_NOFS);
1200 return afs_wait_for_call_to_complete(call, &fc->ac);
1201}
1202
1203/*
1204 * YFS.StoreData64 operation type.
1205 */
1206static const struct afs_call_type yfs_RXYFSStoreData64 = {
1207 .name = "YFS.StoreData64",
1208 .op = yfs_FS_StoreData64,
1209 .deliver = yfs_deliver_status_and_volsync,
1210 .destructor = afs_flat_call_destructor,
1211};
1212
1213/*
1214 * Store a set of pages to a large file.
1215 */
1216int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1217 pgoff_t first, pgoff_t last,
1218 unsigned offset, unsigned to,
1219 struct afs_status_cb *scb)
1220{
1221 struct afs_vnode *vnode = fc->vnode;
1222 struct afs_call *call;
1223 struct afs_net *net = afs_v2net(vnode);
1224 loff_t size, pos, i_size;
1225 __be32 *bp;
1226
1227 _enter(",%x,{%llx:%llu},,",
1228 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1229
1230 size = (loff_t)to - (loff_t)offset;
1231 if (first != last)
1232 size += (loff_t)(last - first) << PAGE_SHIFT;
1233 pos = (loff_t)first << PAGE_SHIFT;
1234 pos += offset;
1235
1236 i_size = i_size_read(&vnode->vfs_inode);
1237 if (pos + size > i_size)
1238 i_size = size + pos;
1239
1240 _debug("size %llx, at %llx, i_size %llx",
1241 (unsigned long long)size, (unsigned long long)pos,
1242 (unsigned long long)i_size);
1243
1244 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1245 sizeof(__be32) +
1246 sizeof(__be32) +
1247 sizeof(struct yfs_xdr_YFSFid) +
1248 sizeof(struct yfs_xdr_YFSStoreStatus) +
1249 sizeof(struct yfs_xdr_u64) * 3,
1250 sizeof(struct yfs_xdr_YFSFetchStatus) +
1251 sizeof(struct yfs_xdr_YFSVolSync));
1252 if (!call)
1253 return -ENOMEM;
1254
1255 call->key = fc->key;
1256 call->mapping = mapping;
1257 call->first = first;
1258 call->last = last;
1259 call->first_offset = offset;
1260 call->last_to = to;
1261 call->send_pages = true;
1262 call->out_scb = scb;
1263
1264 /* marshall the parameters */
1265 bp = call->request;
1266 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1267 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1268 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1269 bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1270 bp = xdr_encode_u64(bp, pos);
1271 bp = xdr_encode_u64(bp, size);
1272 bp = xdr_encode_u64(bp, i_size);
1273 yfs_check_req(call, bp);
1274
1275 afs_use_fs_server(call, fc->cbi);
1276 trace_afs_make_fs_call(call, &vnode->fid);
1277 afs_set_fc_call(call, fc);
1278 afs_make_call(&fc->ac, call, GFP_NOFS);
1279 return afs_wait_for_call_to_complete(call, &fc->ac);
1280}
1281
1282/*
1283 * YFS.StoreStatus operation type
1284 */
1285static const struct afs_call_type yfs_RXYFSStoreStatus = {
1286 .name = "YFS.StoreStatus",
1287 .op = yfs_FS_StoreStatus,
1288 .deliver = yfs_deliver_status_and_volsync,
1289 .destructor = afs_flat_call_destructor,
1290};
1291
1292static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1293 .name = "YFS.StoreData64",
1294 .op = yfs_FS_StoreData64,
1295 .deliver = yfs_deliver_status_and_volsync,
1296 .destructor = afs_flat_call_destructor,
1297};
1298
1299/*
1300 * Set the attributes on a file, using YFS.StoreData64 rather than
1301 * YFS.StoreStatus so as to alter the file size also.
1302 */
1303static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr,
1304 struct afs_status_cb *scb)
1305{
1306 struct afs_vnode *vnode = fc->vnode;
1307 struct afs_call *call;
1308 struct afs_net *net = afs_v2net(vnode);
1309 __be32 *bp;
1310
1311 _enter(",%x,{%llx:%llu},,",
1312 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1313
1314 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1315 sizeof(__be32) * 2 +
1316 sizeof(struct yfs_xdr_YFSFid) +
1317 sizeof(struct yfs_xdr_YFSStoreStatus) +
1318 sizeof(struct yfs_xdr_u64) * 3,
1319 sizeof(struct yfs_xdr_YFSFetchStatus) +
1320 sizeof(struct yfs_xdr_YFSVolSync));
1321 if (!call)
1322 return -ENOMEM;
1323
1324 call->key = fc->key;
1325 call->out_scb = scb;
1326
1327 /* marshall the parameters */
1328 bp = call->request;
1329 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1330 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1331 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1332 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1333 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1334 bp = xdr_encode_u64(bp, 0); /* size of write */
1335 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1336 yfs_check_req(call, bp);
1337
1338 afs_use_fs_server(call, fc->cbi);
1339 trace_afs_make_fs_call(call, &vnode->fid);
1340 afs_set_fc_call(call, fc);
1341 afs_make_call(&fc->ac, call, GFP_NOFS);
1342 return afs_wait_for_call_to_complete(call, &fc->ac);
1343}
1344
1345/*
1346 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1347 * file size, and YFS.StoreStatus otherwise.
1348 */
1349int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr,
1350 struct afs_status_cb *scb)
1351{
1352 struct afs_vnode *vnode = fc->vnode;
1353 struct afs_call *call;
1354 struct afs_net *net = afs_v2net(vnode);
1355 __be32 *bp;
1356
1357 if (attr->ia_valid & ATTR_SIZE)
1358 return yfs_fs_setattr_size(fc, attr, scb);
1359
1360 _enter(",%x,{%llx:%llu},,",
1361 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1362
1363 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1364 sizeof(__be32) * 2 +
1365 sizeof(struct yfs_xdr_YFSFid) +
1366 sizeof(struct yfs_xdr_YFSStoreStatus),
1367 sizeof(struct yfs_xdr_YFSFetchStatus) +
1368 sizeof(struct yfs_xdr_YFSVolSync));
1369 if (!call)
1370 return -ENOMEM;
1371
1372 call->key = fc->key;
1373 call->out_scb = scb;
1374
1375 /* marshall the parameters */
1376 bp = call->request;
1377 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1378 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1379 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1380 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1381 yfs_check_req(call, bp);
1382
1383 afs_use_fs_server(call, fc->cbi);
1384 trace_afs_make_fs_call(call, &vnode->fid);
1385 afs_set_fc_call(call, fc);
1386 afs_make_call(&fc->ac, call, GFP_NOFS);
1387 return afs_wait_for_call_to_complete(call, &fc->ac);
1388}
1389
1390/*
1391 * Deliver reply data to a YFS.GetVolumeStatus operation.
1392 */
1393static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1394{
1395 const __be32 *bp;
1396 char *p;
1397 u32 size;
1398 int ret;
1399
1400 _enter("{%u}", call->unmarshall);
1401
1402 switch (call->unmarshall) {
1403 case 0:
1404 call->unmarshall++;
1405 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1406 /* Fall through */
1407
1408 /* extract the returned status record */
1409 case 1:
1410 _debug("extract status");
1411 ret = afs_extract_data(call, true);
1412 if (ret < 0)
1413 return ret;
1414
1415 bp = call->buffer;
1416 xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus);
1417 call->unmarshall++;
1418 afs_extract_to_tmp(call);
1419 /* Fall through */
1420
1421 /* extract the volume name length */
1422 case 2:
1423 ret = afs_extract_data(call, true);
1424 if (ret < 0)
1425 return ret;
1426
1427 call->count = ntohl(call->tmp);
1428 _debug("volname length: %u", call->count);
1429 if (call->count >= AFSNAMEMAX)
1430 return afs_protocol_error(call, -EBADMSG,
1431 afs_eproto_volname_len);
1432 size = (call->count + 3) & ~3; /* It's padded */
1433 afs_extract_to_buf(call, size);
1434 call->unmarshall++;
1435 /* Fall through */
1436
1437 /* extract the volume name */
1438 case 3:
1439 _debug("extract volname");
1440 ret = afs_extract_data(call, true);
1441 if (ret < 0)
1442 return ret;
1443
1444 p = call->buffer;
1445 p[call->count] = 0;
1446 _debug("volname '%s'", p);
1447 afs_extract_to_tmp(call);
1448 call->unmarshall++;
1449 /* Fall through */
1450
1451 /* extract the offline message length */
1452 case 4:
1453 ret = afs_extract_data(call, true);
1454 if (ret < 0)
1455 return ret;
1456
1457 call->count = ntohl(call->tmp);
1458 _debug("offline msg length: %u", call->count);
1459 if (call->count >= AFSNAMEMAX)
1460 return afs_protocol_error(call, -EBADMSG,
1461 afs_eproto_offline_msg_len);
1462 size = (call->count + 3) & ~3; /* It's padded */
1463 afs_extract_to_buf(call, size);
1464 call->unmarshall++;
1465 /* Fall through */
1466
1467 /* extract the offline message */
1468 case 5:
1469 _debug("extract offline");
1470 ret = afs_extract_data(call, true);
1471 if (ret < 0)
1472 return ret;
1473
1474 p = call->buffer;
1475 p[call->count] = 0;
1476 _debug("offline '%s'", p);
1477
1478 afs_extract_to_tmp(call);
1479 call->unmarshall++;
1480 /* Fall through */
1481
1482 /* extract the message of the day length */
1483 case 6:
1484 ret = afs_extract_data(call, true);
1485 if (ret < 0)
1486 return ret;
1487
1488 call->count = ntohl(call->tmp);
1489 _debug("motd length: %u", call->count);
1490 if (call->count >= AFSNAMEMAX)
1491 return afs_protocol_error(call, -EBADMSG,
1492 afs_eproto_motd_len);
1493 size = (call->count + 3) & ~3; /* It's padded */
1494 afs_extract_to_buf(call, size);
1495 call->unmarshall++;
1496 /* Fall through */
1497
1498 /* extract the message of the day */
1499 case 7:
1500 _debug("extract motd");
1501 ret = afs_extract_data(call, false);
1502 if (ret < 0)
1503 return ret;
1504
1505 p = call->buffer;
1506 p[call->count] = 0;
1507 _debug("motd '%s'", p);
1508
1509 call->unmarshall++;
1510 /* Fall through */
1511
1512 case 8:
1513 break;
1514 }
1515
1516 _leave(" = 0 [done]");
1517 return 0;
1518}
1519
1520/*
1521 * YFS.GetVolumeStatus operation type
1522 */
1523static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1524 .name = "YFS.GetVolumeStatus",
1525 .op = yfs_FS_GetVolumeStatus,
1526 .deliver = yfs_deliver_fs_get_volume_status,
1527 .destructor = afs_flat_call_destructor,
1528};
1529
1530/*
1531 * fetch the status of a volume
1532 */
1533int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1534 struct afs_volume_status *vs)
1535{
1536 struct afs_vnode *vnode = fc->vnode;
1537 struct afs_call *call;
1538 struct afs_net *net = afs_v2net(vnode);
1539 __be32 *bp;
1540
1541 _enter("");
1542
1543 call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1544 sizeof(__be32) * 2 +
1545 sizeof(struct yfs_xdr_u64),
1546 max_t(size_t,
1547 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1548 sizeof(__be32),
1549 AFSOPAQUEMAX + 1));
1550 if (!call)
1551 return -ENOMEM;
1552
1553 call->key = fc->key;
1554 call->out_volstatus = vs;
1555
1556 /* marshall the parameters */
1557 bp = call->request;
1558 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1559 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1560 bp = xdr_encode_u64(bp, vnode->fid.vid);
1561 yfs_check_req(call, bp);
1562
1563 afs_use_fs_server(call, fc->cbi);
1564 trace_afs_make_fs_call(call, &vnode->fid);
1565 afs_set_fc_call(call, fc);
1566 afs_make_call(&fc->ac, call, GFP_NOFS);
1567 return afs_wait_for_call_to_complete(call, &fc->ac);
1568}
1569
1570/*
1571 * YFS.SetLock operation type
1572 */
1573static const struct afs_call_type yfs_RXYFSSetLock = {
1574 .name = "YFS.SetLock",
1575 .op = yfs_FS_SetLock,
1576 .deliver = yfs_deliver_status_and_volsync,
1577 .done = afs_lock_op_done,
1578 .destructor = afs_flat_call_destructor,
1579};
1580
1581/*
1582 * YFS.ExtendLock operation type
1583 */
1584static const struct afs_call_type yfs_RXYFSExtendLock = {
1585 .name = "YFS.ExtendLock",
1586 .op = yfs_FS_ExtendLock,
1587 .deliver = yfs_deliver_status_and_volsync,
1588 .done = afs_lock_op_done,
1589 .destructor = afs_flat_call_destructor,
1590};
1591
1592/*
1593 * YFS.ReleaseLock operation type
1594 */
1595static const struct afs_call_type yfs_RXYFSReleaseLock = {
1596 .name = "YFS.ReleaseLock",
1597 .op = yfs_FS_ReleaseLock,
1598 .deliver = yfs_deliver_status_and_volsync,
1599 .destructor = afs_flat_call_destructor,
1600};
1601
1602/*
1603 * Set a lock on a file
1604 */
1605int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,
1606 struct afs_status_cb *scb)
1607{
1608 struct afs_vnode *vnode = fc->vnode;
1609 struct afs_call *call;
1610 struct afs_net *net = afs_v2net(vnode);
1611 __be32 *bp;
1612
1613 _enter("");
1614
1615 call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1616 sizeof(__be32) * 2 +
1617 sizeof(struct yfs_xdr_YFSFid) +
1618 sizeof(__be32),
1619 sizeof(struct yfs_xdr_YFSFetchStatus) +
1620 sizeof(struct yfs_xdr_YFSVolSync));
1621 if (!call)
1622 return -ENOMEM;
1623
1624 call->key = fc->key;
1625 call->lvnode = vnode;
1626 call->out_scb = scb;
1627
1628 /* marshall the parameters */
1629 bp = call->request;
1630 bp = xdr_encode_u32(bp, YFSSETLOCK);
1631 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1632 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1633 bp = xdr_encode_u32(bp, type);
1634 yfs_check_req(call, bp);
1635
1636 afs_use_fs_server(call, fc->cbi);
1637 trace_afs_make_fs_calli(call, &vnode->fid, type);
1638 afs_set_fc_call(call, fc);
1639 afs_make_call(&fc->ac, call, GFP_NOFS);
1640 return afs_wait_for_call_to_complete(call, &fc->ac);
1641}
1642
1643/*
1644 * extend a lock on a file
1645 */
1646int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1647{
1648 struct afs_vnode *vnode = fc->vnode;
1649 struct afs_call *call;
1650 struct afs_net *net = afs_v2net(vnode);
1651 __be32 *bp;
1652
1653 _enter("");
1654
1655 call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1656 sizeof(__be32) * 2 +
1657 sizeof(struct yfs_xdr_YFSFid),
1658 sizeof(struct yfs_xdr_YFSFetchStatus) +
1659 sizeof(struct yfs_xdr_YFSVolSync));
1660 if (!call)
1661 return -ENOMEM;
1662
1663 call->key = fc->key;
1664 call->lvnode = vnode;
1665 call->out_scb = scb;
1666
1667 /* marshall the parameters */
1668 bp = call->request;
1669 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1670 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1671 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1672 yfs_check_req(call, bp);
1673
1674 afs_use_fs_server(call, fc->cbi);
1675 trace_afs_make_fs_call(call, &vnode->fid);
1676 afs_set_fc_call(call, fc);
1677 afs_make_call(&fc->ac, call, GFP_NOFS);
1678 return afs_wait_for_call_to_complete(call, &fc->ac);
1679}
1680
1681/*
1682 * release a lock on a file
1683 */
1684int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1685{
1686 struct afs_vnode *vnode = fc->vnode;
1687 struct afs_call *call;
1688 struct afs_net *net = afs_v2net(vnode);
1689 __be32 *bp;
1690
1691 _enter("");
1692
1693 call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1694 sizeof(__be32) * 2 +
1695 sizeof(struct yfs_xdr_YFSFid),
1696 sizeof(struct yfs_xdr_YFSFetchStatus) +
1697 sizeof(struct yfs_xdr_YFSVolSync));
1698 if (!call)
1699 return -ENOMEM;
1700
1701 call->key = fc->key;
1702 call->lvnode = vnode;
1703 call->out_scb = scb;
1704
1705 /* marshall the parameters */
1706 bp = call->request;
1707 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1708 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1709 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1710 yfs_check_req(call, bp);
1711
1712 afs_use_fs_server(call, fc->cbi);
1713 trace_afs_make_fs_call(call, &vnode->fid);
1714 afs_set_fc_call(call, fc);
1715 afs_make_call(&fc->ac, call, GFP_NOFS);
1716 return afs_wait_for_call_to_complete(call, &fc->ac);
1717}
1718
1719/*
1720 * YFS.FetchStatus operation type
1721 */
1722static const struct afs_call_type yfs_RXYFSFetchStatus = {
1723 .name = "YFS.FetchStatus",
1724 .op = yfs_FS_FetchStatus,
1725 .deliver = yfs_deliver_fs_status_cb_and_volsync,
1726 .destructor = afs_flat_call_destructor,
1727};
1728
1729/*
1730 * Fetch the status information for a fid without needing a vnode handle.
1731 */
1732int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1733 struct afs_net *net,
1734 struct afs_fid *fid,
1735 struct afs_status_cb *scb,
1736 struct afs_volsync *volsync)
1737{
1738 struct afs_call *call;
1739 __be32 *bp;
1740
1741 _enter(",%x,{%llx:%llu},,",
1742 key_serial(fc->key), fid->vid, fid->vnode);
1743
1744 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1745 sizeof(__be32) * 2 +
1746 sizeof(struct yfs_xdr_YFSFid),
1747 sizeof(struct yfs_xdr_YFSFetchStatus) +
1748 sizeof(struct yfs_xdr_YFSCallBack) +
1749 sizeof(struct yfs_xdr_YFSVolSync));
1750 if (!call) {
1751 fc->ac.error = -ENOMEM;
1752 return -ENOMEM;
1753 }
1754
1755 call->key = fc->key;
1756 call->out_scb = scb;
1757 call->out_volsync = volsync;
1758
1759 /* marshall the parameters */
1760 bp = call->request;
1761 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1762 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1763 bp = xdr_encode_YFSFid(bp, fid);
1764 yfs_check_req(call, bp);
1765
1766 afs_use_fs_server(call, fc->cbi);
1767 trace_afs_make_fs_call(call, fid);
1768 afs_set_fc_call(call, fc);
1769 afs_make_call(&fc->ac, call, GFP_NOFS);
1770 return afs_wait_for_call_to_complete(call, &fc->ac);
1771}
1772
1773/*
1774 * Deliver reply data to an YFS.InlineBulkStatus call
1775 */
1776static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1777{
1778 struct afs_status_cb *scb;
1779 const __be32 *bp;
1780 u32 tmp;
1781 int ret;
1782
1783 _enter("{%u}", call->unmarshall);
1784
1785 switch (call->unmarshall) {
1786 case 0:
1787 afs_extract_to_tmp(call);
1788 call->unmarshall++;
1789 /* Fall through */
1790
1791 /* Extract the file status count and array in two steps */
1792 case 1:
1793 _debug("extract status count");
1794 ret = afs_extract_data(call, true);
1795 if (ret < 0)
1796 return ret;
1797
1798 tmp = ntohl(call->tmp);
1799 _debug("status count: %u/%u", tmp, call->count2);
1800 if (tmp != call->count2)
1801 return afs_protocol_error(call, -EBADMSG,
1802 afs_eproto_ibulkst_count);
1803
1804 call->count = 0;
1805 call->unmarshall++;
1806 more_counts:
1807 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1808 /* Fall through */
1809
1810 case 2:
1811 _debug("extract status array %u", call->count);
1812 ret = afs_extract_data(call, true);
1813 if (ret < 0)
1814 return ret;
1815
1816 bp = call->buffer;
1817 scb = &call->out_scb[call->count];
Olivier Deprez0e641232021-09-23 10:07:05 +02001818 xdr_decode_YFSFetchStatus(&bp, call, scb);
David Brazdil0f672f62019-12-10 10:32:29 +00001819
1820 call->count++;
1821 if (call->count < call->count2)
1822 goto more_counts;
1823
1824 call->count = 0;
1825 call->unmarshall++;
1826 afs_extract_to_tmp(call);
1827 /* Fall through */
1828
1829 /* Extract the callback count and array in two steps */
1830 case 3:
1831 _debug("extract CB count");
1832 ret = afs_extract_data(call, true);
1833 if (ret < 0)
1834 return ret;
1835
1836 tmp = ntohl(call->tmp);
1837 _debug("CB count: %u", tmp);
1838 if (tmp != call->count2)
1839 return afs_protocol_error(call, -EBADMSG,
1840 afs_eproto_ibulkst_cb_count);
1841 call->count = 0;
1842 call->unmarshall++;
1843 more_cbs:
1844 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1845 /* Fall through */
1846
1847 case 4:
1848 _debug("extract CB array");
1849 ret = afs_extract_data(call, true);
1850 if (ret < 0)
1851 return ret;
1852
1853 _debug("unmarshall CB array");
1854 bp = call->buffer;
1855 scb = &call->out_scb[call->count];
1856 xdr_decode_YFSCallBack(&bp, call, scb);
1857 call->count++;
1858 if (call->count < call->count2)
1859 goto more_cbs;
1860
1861 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1862 call->unmarshall++;
1863 /* Fall through */
1864
1865 case 5:
1866 ret = afs_extract_data(call, false);
1867 if (ret < 0)
1868 return ret;
1869
1870 bp = call->buffer;
1871 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1872
1873 call->unmarshall++;
1874 /* Fall through */
1875
1876 case 6:
1877 break;
1878 }
1879
1880 _leave(" = 0 [done]");
1881 return 0;
1882}
1883
1884/*
1885 * FS.InlineBulkStatus operation type
1886 */
1887static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1888 .name = "YFS.InlineBulkStatus",
1889 .op = yfs_FS_InlineBulkStatus,
1890 .deliver = yfs_deliver_fs_inline_bulk_status,
1891 .destructor = afs_flat_call_destructor,
1892};
1893
1894/*
1895 * Fetch the status information for up to 1024 files
1896 */
1897int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
1898 struct afs_net *net,
1899 struct afs_fid *fids,
1900 struct afs_status_cb *statuses,
1901 unsigned int nr_fids,
1902 struct afs_volsync *volsync)
1903{
1904 struct afs_call *call;
1905 __be32 *bp;
1906 int i;
1907
1908 _enter(",%x,{%llx:%llu},%u",
1909 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
1910
1911 call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
1912 sizeof(__be32) +
1913 sizeof(__be32) +
1914 sizeof(__be32) +
1915 sizeof(struct yfs_xdr_YFSFid) * nr_fids,
1916 sizeof(struct yfs_xdr_YFSFetchStatus));
1917 if (!call) {
1918 fc->ac.error = -ENOMEM;
1919 return -ENOMEM;
1920 }
1921
1922 call->key = fc->key;
1923 call->out_scb = statuses;
1924 call->out_volsync = volsync;
1925 call->count2 = nr_fids;
1926
1927 /* marshall the parameters */
1928 bp = call->request;
1929 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1930 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1931 bp = xdr_encode_u32(bp, nr_fids);
1932 for (i = 0; i < nr_fids; i++)
1933 bp = xdr_encode_YFSFid(bp, &fids[i]);
1934 yfs_check_req(call, bp);
1935
1936 afs_use_fs_server(call, fc->cbi);
1937 trace_afs_make_fs_call(call, &fids[0]);
1938 afs_set_fc_call(call, fc);
1939 afs_make_call(&fc->ac, call, GFP_NOFS);
1940 return afs_wait_for_call_to_complete(call, &fc->ac);
1941}
1942
1943/*
1944 * Deliver reply data to an YFS.FetchOpaqueACL.
1945 */
1946static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1947{
1948 struct yfs_acl *yacl = call->out_yacl;
1949 struct afs_acl *acl;
1950 const __be32 *bp;
1951 unsigned int size;
1952 int ret;
1953
1954 _enter("{%u}", call->unmarshall);
1955
1956 switch (call->unmarshall) {
1957 case 0:
1958 afs_extract_to_tmp(call);
1959 call->unmarshall++;
1960 /* Fall through */
1961
1962 /* Extract the file ACL length */
1963 case 1:
1964 ret = afs_extract_data(call, true);
1965 if (ret < 0)
1966 return ret;
1967
1968 size = call->count2 = ntohl(call->tmp);
1969 size = round_up(size, 4);
1970
1971 if (yacl->flags & YFS_ACL_WANT_ACL) {
1972 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1973 if (!acl)
1974 return -ENOMEM;
1975 yacl->acl = acl;
1976 acl->size = call->count2;
1977 afs_extract_begin(call, acl->data, size);
1978 } else {
1979 afs_extract_discard(call, size);
1980 }
1981 call->unmarshall++;
1982 /* Fall through */
1983
1984 /* Extract the file ACL */
1985 case 2:
1986 ret = afs_extract_data(call, true);
1987 if (ret < 0)
1988 return ret;
1989
1990 afs_extract_to_tmp(call);
1991 call->unmarshall++;
1992 /* Fall through */
1993
1994 /* Extract the volume ACL length */
1995 case 3:
1996 ret = afs_extract_data(call, true);
1997 if (ret < 0)
1998 return ret;
1999
2000 size = call->count2 = ntohl(call->tmp);
2001 size = round_up(size, 4);
2002
2003 if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2004 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2005 if (!acl)
2006 return -ENOMEM;
2007 yacl->vol_acl = acl;
2008 acl->size = call->count2;
2009 afs_extract_begin(call, acl->data, size);
2010 } else {
2011 afs_extract_discard(call, size);
2012 }
2013 call->unmarshall++;
2014 /* Fall through */
2015
2016 /* Extract the volume ACL */
2017 case 4:
2018 ret = afs_extract_data(call, true);
2019 if (ret < 0)
2020 return ret;
2021
2022 afs_extract_to_buf(call,
2023 sizeof(__be32) * 2 +
2024 sizeof(struct yfs_xdr_YFSFetchStatus) +
2025 sizeof(struct yfs_xdr_YFSVolSync));
2026 call->unmarshall++;
2027 /* Fall through */
2028
2029 /* extract the metadata */
2030 case 5:
2031 ret = afs_extract_data(call, false);
2032 if (ret < 0)
2033 return ret;
2034
2035 bp = call->buffer;
2036 yacl->inherit_flag = ntohl(*bp++);
2037 yacl->num_cleaned = ntohl(*bp++);
Olivier Deprez0e641232021-09-23 10:07:05 +02002038 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
David Brazdil0f672f62019-12-10 10:32:29 +00002039 xdr_decode_YFSVolSync(&bp, call->out_volsync);
2040
2041 call->unmarshall++;
2042 /* Fall through */
2043
2044 case 6:
2045 break;
2046 }
2047
2048 _leave(" = 0 [done]");
2049 return 0;
2050}
2051
2052void yfs_free_opaque_acl(struct yfs_acl *yacl)
2053{
2054 if (yacl) {
2055 kfree(yacl->acl);
2056 kfree(yacl->vol_acl);
2057 kfree(yacl);
2058 }
2059}
2060
2061/*
2062 * YFS.FetchOpaqueACL operation type
2063 */
2064static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2065 .name = "YFS.FetchOpaqueACL",
2066 .op = yfs_FS_FetchOpaqueACL,
2067 .deliver = yfs_deliver_fs_fetch_opaque_acl,
2068 .destructor = afs_flat_call_destructor,
2069};
2070
2071/*
2072 * Fetch the YFS advanced ACLs for a file.
2073 */
2074struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
2075 struct yfs_acl *yacl,
2076 struct afs_status_cb *scb)
2077{
2078 struct afs_vnode *vnode = fc->vnode;
2079 struct afs_call *call;
2080 struct afs_net *net = afs_v2net(vnode);
2081 __be32 *bp;
2082
2083 _enter(",%x,{%llx:%llu},,",
2084 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2085
2086 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,
2087 sizeof(__be32) * 2 +
2088 sizeof(struct yfs_xdr_YFSFid),
2089 sizeof(__be32) * 2 +
2090 sizeof(struct yfs_xdr_YFSFetchStatus) +
2091 sizeof(struct yfs_xdr_YFSVolSync));
2092 if (!call) {
2093 fc->ac.error = -ENOMEM;
2094 return ERR_PTR(-ENOMEM);
2095 }
2096
2097 call->key = fc->key;
2098 call->out_yacl = yacl;
2099 call->out_scb = scb;
2100 call->out_volsync = NULL;
2101
2102 /* marshall the parameters */
2103 bp = call->request;
2104 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2105 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2106 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2107 yfs_check_req(call, bp);
2108
2109 afs_use_fs_server(call, fc->cbi);
2110 trace_afs_make_fs_call(call, &vnode->fid);
2111 afs_make_call(&fc->ac, call, GFP_KERNEL);
2112 return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2113}
2114
2115/*
2116 * YFS.StoreOpaqueACL2 operation type
2117 */
2118static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2119 .name = "YFS.StoreOpaqueACL2",
2120 .op = yfs_FS_StoreOpaqueACL2,
2121 .deliver = yfs_deliver_status_and_volsync,
2122 .destructor = afs_flat_call_destructor,
2123};
2124
2125/*
2126 * Fetch the YFS ACL for a file.
2127 */
2128int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl,
2129 struct afs_status_cb *scb)
2130{
2131 struct afs_vnode *vnode = fc->vnode;
2132 struct afs_call *call;
2133 struct afs_net *net = afs_v2net(vnode);
2134 size_t size;
2135 __be32 *bp;
2136
2137 _enter(",%x,{%llx:%llu},,",
2138 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2139
2140 size = round_up(acl->size, 4);
2141 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreOpaqueACL2,
2142 sizeof(__be32) * 2 +
2143 sizeof(struct yfs_xdr_YFSFid) +
2144 sizeof(__be32) + size,
2145 sizeof(struct yfs_xdr_YFSFetchStatus) +
2146 sizeof(struct yfs_xdr_YFSVolSync));
2147 if (!call) {
2148 fc->ac.error = -ENOMEM;
2149 return -ENOMEM;
2150 }
2151
2152 call->key = fc->key;
2153 call->out_scb = scb;
2154 call->out_volsync = NULL;
2155
2156 /* marshall the parameters */
2157 bp = call->request;
2158 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2159 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2160 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2161 bp = xdr_encode_u32(bp, acl->size);
2162 memcpy(bp, acl->data, acl->size);
2163 if (acl->size != size)
2164 memset((void *)bp + acl->size, 0, size - acl->size);
Olivier Deprez0e641232021-09-23 10:07:05 +02002165 bp += size / sizeof(__be32);
David Brazdil0f672f62019-12-10 10:32:29 +00002166 yfs_check_req(call, bp);
2167
2168 trace_afs_make_fs_call(call, &vnode->fid);
2169 afs_make_call(&fc->ac, call, GFP_KERNEL);
2170 return afs_wait_for_call_to_complete(call, &fc->ac);
2171}