blob: 3ba33d415a743c397c61f0af0a928a3442b56a79 [file] [log] [blame]
David Howells30062bd2018-10-20 00:57:58 +01001/* YFS File Server client stubs
2 *
3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/sched.h>
15#include <linux/circ_buf.h>
16#include <linux/iversion.h>
17#include "internal.h"
18#include "afs_fs.h"
19#include "xdr_fs.h"
20#include "protocol_yfs.h"
21
22static const struct afs_fid afs_zero_fid;
23
24static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
25{
26 call->cbi = afs_get_cb_interest(cbi);
27}
28
29#define xdr_size(x) (sizeof(*x) / sizeof(__be32))
30
31static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
32{
33 const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
34
35 fid->vid = xdr_to_u64(x->volume);
36 fid->vnode = xdr_to_u64(x->vnode.lo);
37 fid->vnode_hi = ntohl(x->vnode.hi);
38 fid->unique = ntohl(x->vnode.unique);
39 *_bp += xdr_size(x);
40}
41
42static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
43{
44 *bp++ = htonl(n);
45 return bp;
46}
47
48static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
49{
50 struct yfs_xdr_u64 *x = (void *)bp;
51
52 *x = u64_to_xdr(n);
53 return bp + xdr_size(x);
54}
55
56static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
57{
58 struct yfs_xdr_YFSFid *x = (void *)bp;
59
60 x->volume = u64_to_xdr(fid->vid);
61 x->vnode.lo = u64_to_xdr(fid->vnode);
62 x->vnode.hi = htonl(fid->vnode_hi);
63 x->vnode.unique = htonl(fid->unique);
64 return bp + xdr_size(x);
65}
66
67static size_t xdr_strlen(unsigned int len)
68{
69 return sizeof(__be32) + round_up(len, sizeof(__be32));
70}
71
72static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
73{
74 bp = xdr_encode_u32(bp, len);
75 bp = memcpy(bp, p, len);
76 if (len & 3) {
77 unsigned int pad = 4 - (len & 3);
78
79 memset((u8 *)bp + len, 0, pad);
80 len += pad;
81 }
82
83 return bp + len / sizeof(__be32);
84}
85
86static s64 linux_to_yfs_time(const struct timespec64 *t)
87{
88 /* Convert to 100ns intervals. */
89 return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
90}
91
92static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
93{
94 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
95
96 x->mask = htonl(AFS_SET_MODE);
97 x->mode = htonl(mode & S_IALLUGO);
98 x->mtime_client = u64_to_xdr(0);
99 x->owner = u64_to_xdr(0);
100 x->group = u64_to_xdr(0);
101 return bp + xdr_size(x);
102}
103
104static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
105{
106 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
107 s64 mtime = linux_to_yfs_time(t);
108
109 x->mask = htonl(AFS_SET_MTIME);
110 x->mode = htonl(0);
111 x->mtime_client = u64_to_xdr(mtime);
112 x->owner = u64_to_xdr(0);
113 x->group = u64_to_xdr(0);
114 return bp + xdr_size(x);
115}
116
117/*
118 * Convert a signed 100ns-resolution 64-bit time into a timespec.
119 */
120static struct timespec64 yfs_time_to_linux(s64 t)
121{
122 struct timespec64 ts;
123 u64 abs_t;
124
125 /*
126 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
127 * the alternative, do_div, does not work with negative numbers so have
128 * to special case them
129 */
130 if (t < 0) {
131 abs_t = -t;
132 ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
133 ts.tv_nsec = -ts.tv_nsec;
134 ts.tv_sec = -abs_t;
135 } else {
136 abs_t = t;
137 ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
138 ts.tv_sec = abs_t;
139 }
140
141 return ts;
142}
143
144static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
145{
146 s64 t = xdr_to_u64(xdr);
147
148 return yfs_time_to_linux(t);
149}
150
151static void yfs_check_req(struct afs_call *call, __be32 *bp)
152{
153 size_t len = (void *)bp - call->request;
154
155 if (len > call->request_size)
156 pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
157 call->type->name, len, call->request_size);
158 else if (len < call->request_size)
159 pr_warning("kAFS: %s: Request buffer underflow (%zu<%u)\n",
160 call->type->name, len, call->request_size);
161}
162
163/*
164 * Dump a bad file status record.
165 */
166static void xdr_dump_bad(const __be32 *bp)
167{
168 __be32 x[4];
169 int i;
170
171 pr_notice("YFS XDR: Bad status record\n");
172 for (i = 0; i < 5 * 4 * 4; i += 16) {
173 memcpy(x, bp, 16);
174 bp += 4;
175 pr_notice("%03x: %08x %08x %08x %08x\n",
176 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
177 }
178
179 memcpy(x, bp, 4);
180 pr_notice("0x50: %08x\n", ntohl(x[0]));
181}
182
183/*
184 * Decode a YFSFetchStatus block
185 */
186static int xdr_decode_YFSFetchStatus(struct afs_call *call,
187 const __be32 **_bp,
188 struct afs_file_status *status,
189 struct afs_vnode *vnode,
190 const afs_dataversion_t *expected_version,
191 struct afs_read *read_req)
192{
193 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
194 u32 type;
195 u8 flags = 0;
196
197 status->abort_code = ntohl(xdr->abort_code);
198 if (status->abort_code != 0) {
199 if (vnode && status->abort_code == VNOVNODE) {
200 set_bit(AFS_VNODE_DELETED, &vnode->flags);
201 status->nlink = 0;
202 __afs_break_callback(vnode);
203 }
204 return 0;
205 }
206
207 type = ntohl(xdr->type);
208 switch (type) {
209 case AFS_FTYPE_FILE:
210 case AFS_FTYPE_DIR:
211 case AFS_FTYPE_SYMLINK:
212 if (type != status->type &&
213 vnode &&
214 !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
215 pr_warning("Vnode %llx:%llx:%x changed type %u to %u\n",
216 vnode->fid.vid,
217 vnode->fid.vnode,
218 vnode->fid.unique,
219 status->type, type);
220 goto bad;
221 }
222 status->type = type;
223 break;
224 default:
225 goto bad;
226 }
227
228#define EXTRACT_M4(FIELD) \
229 do { \
230 u32 x = ntohl(xdr->FIELD); \
231 if (status->FIELD != x) { \
232 flags |= AFS_VNODE_META_CHANGED; \
233 status->FIELD = x; \
234 } \
235 } while (0)
236
237#define EXTRACT_M8(FIELD) \
238 do { \
239 u64 x = xdr_to_u64(xdr->FIELD); \
240 if (status->FIELD != x) { \
241 flags |= AFS_VNODE_META_CHANGED; \
242 status->FIELD = x; \
243 } \
244 } while (0)
245
246#define EXTRACT_D8(FIELD) \
247 do { \
248 u64 x = xdr_to_u64(xdr->FIELD); \
249 if (status->FIELD != x) { \
250 flags |= AFS_VNODE_DATA_CHANGED; \
251 status->FIELD = x; \
252 } \
253 } while (0)
254
255 EXTRACT_M4(nlink);
256 EXTRACT_D8(size);
257 EXTRACT_D8(data_version);
258 EXTRACT_M8(author);
259 EXTRACT_M8(owner);
260 EXTRACT_M8(group);
261 EXTRACT_M4(mode);
262 EXTRACT_M4(caller_access); /* call ticket dependent */
263 EXTRACT_M4(anon_access);
264
265 status->mtime_client = xdr_to_time(xdr->mtime_client);
266 status->mtime_server = xdr_to_time(xdr->mtime_server);
267 status->lock_count = ntohl(xdr->lock_count);
268
269 if (read_req) {
270 read_req->data_version = status->data_version;
271 read_req->file_size = status->size;
272 }
273
274 *_bp += xdr_size(xdr);
275
276 if (vnode) {
277 if (test_bit(AFS_VNODE_UNSET, &vnode->flags))
278 flags |= AFS_VNODE_NOT_YET_SET;
279 afs_update_inode_from_status(vnode, status, expected_version,
280 flags);
281 }
282
283 return 0;
284
285bad:
286 xdr_dump_bad(*_bp);
287 return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
288}
289
290/*
291 * Decode the file status. We need to lock the target vnode if we're going to
292 * update its status so that stat() sees the attributes update atomically.
293 */
294static int yfs_decode_status(struct afs_call *call,
295 const __be32 **_bp,
296 struct afs_file_status *status,
297 struct afs_vnode *vnode,
298 const afs_dataversion_t *expected_version,
299 struct afs_read *read_req)
300{
301 int ret;
302
303 if (!vnode)
304 return xdr_decode_YFSFetchStatus(call, _bp, status, vnode,
305 expected_version, read_req);
306
307 write_seqlock(&vnode->cb_lock);
308 ret = xdr_decode_YFSFetchStatus(call, _bp, status, vnode,
309 expected_version, read_req);
310 write_sequnlock(&vnode->cb_lock);
311 return ret;
312}
313
314/*
315 * Decode a YFSCallBack block
316 */
317static void xdr_decode_YFSCallBack(struct afs_call *call,
318 struct afs_vnode *vnode,
319 const __be32 **_bp)
320{
321 struct yfs_xdr_YFSCallBack *xdr = (void *)*_bp;
322 struct afs_cb_interest *old, *cbi = call->cbi;
323 u64 cb_expiry;
324
325 write_seqlock(&vnode->cb_lock);
326
David Howells18ac6182018-10-20 00:57:59 +0100327 if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) {
David Howells30062bd2018-10-20 00:57:58 +0100328 cb_expiry = xdr_to_u64(xdr->expiration_time);
329 do_div(cb_expiry, 10 * 1000 * 1000);
330 vnode->cb_version = ntohl(xdr->version);
331 vnode->cb_type = ntohl(xdr->type);
332 vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds();
333 old = vnode->cb_interest;
334 if (old != call->cbi) {
335 vnode->cb_interest = cbi;
336 cbi = old;
337 }
338 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
339 }
340
341 write_sequnlock(&vnode->cb_lock);
342 call->cbi = cbi;
343 *_bp += xdr_size(xdr);
344}
345
346static void xdr_decode_YFSCallBack_raw(const __be32 **_bp,
347 struct afs_callback *cb)
348{
349 struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
350 u64 cb_expiry;
351
352 cb_expiry = xdr_to_u64(x->expiration_time);
353 do_div(cb_expiry, 10 * 1000 * 1000);
354 cb->version = ntohl(x->version);
355 cb->type = ntohl(x->type);
356 cb->expires_at = cb_expiry + ktime_get_real_seconds();
357
358 *_bp += xdr_size(x);
359}
360
361/*
362 * Decode a YFSVolSync block
363 */
364static void xdr_decode_YFSVolSync(const __be32 **_bp,
365 struct afs_volsync *volsync)
366{
367 struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
368 u64 creation;
369
370 if (volsync) {
371 creation = xdr_to_u64(x->vol_creation_date);
372 do_div(creation, 10 * 1000 * 1000);
373 volsync->creation = creation;
374 }
375
376 *_bp += xdr_size(x);
377}
378
379/*
380 * Encode the requested attributes into a YFSStoreStatus block
381 */
382static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
383{
384 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
385 s64 mtime = 0, owner = 0, group = 0;
386 u32 mask = 0, mode = 0;
387
388 mask = 0;
389 if (attr->ia_valid & ATTR_MTIME) {
390 mask |= AFS_SET_MTIME;
391 mtime = linux_to_yfs_time(&attr->ia_mtime);
392 }
393
394 if (attr->ia_valid & ATTR_UID) {
395 mask |= AFS_SET_OWNER;
396 owner = from_kuid(&init_user_ns, attr->ia_uid);
397 }
398
399 if (attr->ia_valid & ATTR_GID) {
400 mask |= AFS_SET_GROUP;
401 group = from_kgid(&init_user_ns, attr->ia_gid);
402 }
403
404 if (attr->ia_valid & ATTR_MODE) {
405 mask |= AFS_SET_MODE;
406 mode = attr->ia_mode & S_IALLUGO;
407 }
408
409 x->mask = htonl(mask);
410 x->mode = htonl(mode);
411 x->mtime_client = u64_to_xdr(mtime);
412 x->owner = u64_to_xdr(owner);
413 x->group = u64_to_xdr(group);
414 return bp + xdr_size(x);
415}
416
417/*
418 * Decode a YFSFetchVolumeStatus block.
419 */
420static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
421 struct afs_volume_status *vs)
422{
423 const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
424 u32 flags;
425
426 vs->vid = xdr_to_u64(x->vid);
427 vs->parent_id = xdr_to_u64(x->parent_id);
428 flags = ntohl(x->flags);
429 vs->online = flags & yfs_FVSOnline;
430 vs->in_service = flags & yfs_FVSInservice;
431 vs->blessed = flags & yfs_FVSBlessed;
432 vs->needs_salvage = flags & yfs_FVSNeedsSalvage;
433 vs->type = ntohl(x->type);
434 vs->min_quota = 0;
435 vs->max_quota = xdr_to_u64(x->max_quota);
436 vs->blocks_in_use = xdr_to_u64(x->blocks_in_use);
437 vs->part_blocks_avail = xdr_to_u64(x->part_blocks_avail);
438 vs->part_max_blocks = xdr_to_u64(x->part_max_blocks);
439 vs->vol_copy_date = xdr_to_u64(x->vol_copy_date);
440 vs->vol_backup_date = xdr_to_u64(x->vol_backup_date);
441 *_bp += sizeof(*x) / sizeof(__be32);
442}
443
444/*
445 * deliver reply data to an FS.FetchStatus
446 */
447static int yfs_deliver_fs_fetch_status_vnode(struct afs_call *call)
448{
449 struct afs_vnode *vnode = call->reply[0];
450 const __be32 *bp;
451 int ret;
452
453 ret = afs_transfer_reply(call);
454 if (ret < 0)
455 return ret;
456
457 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
458
459 /* unmarshall the reply once we've received all of it */
460 bp = call->buffer;
461 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
462 &call->expected_version, NULL);
463 if (ret < 0)
464 return ret;
465 xdr_decode_YFSCallBack(call, vnode, &bp);
466 xdr_decode_YFSVolSync(&bp, call->reply[1]);
467
468 _leave(" = 0 [done]");
469 return 0;
470}
471
472/*
473 * YFS.FetchStatus operation type
474 */
475static const struct afs_call_type yfs_RXYFSFetchStatus_vnode = {
476 .name = "YFS.FetchStatus(vnode)",
477 .op = yfs_FS_FetchStatus,
478 .deliver = yfs_deliver_fs_fetch_status_vnode,
479 .destructor = afs_flat_call_destructor,
480};
481
482/*
483 * Fetch the status information for a file.
484 */
485int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
486 bool new_inode)
487{
488 struct afs_vnode *vnode = fc->vnode;
489 struct afs_call *call;
490 struct afs_net *net = afs_v2net(vnode);
491 __be32 *bp;
492
493 _enter(",%x,{%llx:%llu},,",
494 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
495
496 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus_vnode,
497 sizeof(__be32) * 2 +
498 sizeof(struct yfs_xdr_YFSFid),
499 sizeof(struct yfs_xdr_YFSFetchStatus) +
500 sizeof(struct yfs_xdr_YFSCallBack) +
501 sizeof(struct yfs_xdr_YFSVolSync));
502 if (!call) {
503 fc->ac.error = -ENOMEM;
504 return -ENOMEM;
505 }
506
507 call->key = fc->key;
508 call->reply[0] = vnode;
509 call->reply[1] = volsync;
510 call->expected_version = new_inode ? 1 : vnode->status.data_version;
511
512 /* marshall the parameters */
513 bp = call->request;
514 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
515 bp = xdr_encode_u32(bp, 0); /* RPC flags */
516 bp = xdr_encode_YFSFid(bp, &vnode->fid);
517 yfs_check_req(call, bp);
518
519 call->cb_break = fc->cb_break;
520 afs_use_fs_server(call, fc->cbi);
521 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +0100522 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +0100523 afs_make_call(&fc->ac, call, GFP_NOFS);
524 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +0100525}
526
527/*
528 * Deliver reply data to an YFS.FetchData64.
529 */
530static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
531{
532 struct afs_vnode *vnode = call->reply[0];
533 struct afs_read *req = call->reply[2];
534 const __be32 *bp;
535 unsigned int size;
536 int ret;
537
538 _enter("{%u,%zu/%llu}",
539 call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
540
541 switch (call->unmarshall) {
542 case 0:
543 req->actual_len = 0;
544 req->index = 0;
545 req->offset = req->pos & (PAGE_SIZE - 1);
546 afs_extract_to_tmp64(call);
547 call->unmarshall++;
548
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -0600549 /* Fall through - and extract the returned data length */
David Howells30062bd2018-10-20 00:57:58 +0100550 case 1:
551 _debug("extract data length");
552 ret = afs_extract_data(call, true);
553 if (ret < 0)
554 return ret;
555
556 req->actual_len = be64_to_cpu(call->tmp64);
557 _debug("DATA length: %llu", req->actual_len);
558 req->remain = min(req->len, req->actual_len);
559 if (req->remain == 0)
560 goto no_more_data;
561
562 call->unmarshall++;
563
564 begin_page:
565 ASSERTCMP(req->index, <, req->nr_pages);
566 if (req->remain > PAGE_SIZE - req->offset)
567 size = PAGE_SIZE - req->offset;
568 else
569 size = req->remain;
570 call->bvec[0].bv_len = size;
571 call->bvec[0].bv_offset = req->offset;
572 call->bvec[0].bv_page = req->pages[req->index];
573 iov_iter_bvec(&call->iter, READ, call->bvec, 1, size);
574 ASSERTCMP(size, <=, PAGE_SIZE);
575
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -0600576 /* Fall through - and extract the returned data */
David Howells30062bd2018-10-20 00:57:58 +0100577 case 2:
578 _debug("extract data %zu/%llu",
579 iov_iter_count(&call->iter), req->remain);
580
581 ret = afs_extract_data(call, true);
582 if (ret < 0)
583 return ret;
584 req->remain -= call->bvec[0].bv_len;
585 req->offset += call->bvec[0].bv_len;
586 ASSERTCMP(req->offset, <=, PAGE_SIZE);
587 if (req->offset == PAGE_SIZE) {
588 req->offset = 0;
589 if (req->page_done)
590 req->page_done(call, req);
591 req->index++;
592 if (req->remain > 0)
593 goto begin_page;
594 }
595
596 ASSERTCMP(req->remain, ==, 0);
597 if (req->actual_len <= req->len)
598 goto no_more_data;
599
600 /* Discard any excess data the server gave us */
601 iov_iter_discard(&call->iter, READ, req->actual_len - req->len);
602 call->unmarshall = 3;
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -0600603
604 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +0100605 case 3:
606 _debug("extract discard %zu/%llu",
607 iov_iter_count(&call->iter), req->actual_len - req->len);
608
609 ret = afs_extract_data(call, true);
610 if (ret < 0)
611 return ret;
612
613 no_more_data:
614 call->unmarshall = 4;
615 afs_extract_to_buf(call,
616 sizeof(struct yfs_xdr_YFSFetchStatus) +
617 sizeof(struct yfs_xdr_YFSCallBack) +
618 sizeof(struct yfs_xdr_YFSVolSync));
619
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -0600620 /* Fall through - and extract the metadata */
David Howells30062bd2018-10-20 00:57:58 +0100621 case 4:
622 ret = afs_extract_data(call, false);
623 if (ret < 0)
624 return ret;
625
626 bp = call->buffer;
627 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
628 &vnode->status.data_version, req);
629 if (ret < 0)
630 return ret;
631 xdr_decode_YFSCallBack(call, vnode, &bp);
632 xdr_decode_YFSVolSync(&bp, call->reply[1]);
633
634 call->unmarshall++;
635
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -0600636 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +0100637 case 5:
638 break;
639 }
640
641 for (; req->index < req->nr_pages; req->index++) {
642 if (req->offset < PAGE_SIZE)
643 zero_user_segment(req->pages[req->index],
644 req->offset, PAGE_SIZE);
645 if (req->page_done)
646 req->page_done(call, req);
647 req->offset = 0;
648 }
649
650 _leave(" = 0 [done]");
651 return 0;
652}
653
654static void yfs_fetch_data_destructor(struct afs_call *call)
655{
656 struct afs_read *req = call->reply[2];
657
658 afs_put_read(req);
659 afs_flat_call_destructor(call);
660}
661
662/*
663 * YFS.FetchData64 operation type
664 */
665static const struct afs_call_type yfs_RXYFSFetchData64 = {
666 .name = "YFS.FetchData64",
667 .op = yfs_FS_FetchData64,
668 .deliver = yfs_deliver_fs_fetch_data64,
669 .destructor = yfs_fetch_data_destructor,
670};
671
672/*
673 * Fetch data from a file.
674 */
675int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
676{
677 struct afs_vnode *vnode = fc->vnode;
678 struct afs_call *call;
679 struct afs_net *net = afs_v2net(vnode);
680 __be32 *bp;
681
682 _enter(",%x,{%llx:%llu},%llx,%llx",
683 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
684 req->pos, req->len);
685
686 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
687 sizeof(__be32) * 2 +
688 sizeof(struct yfs_xdr_YFSFid) +
689 sizeof(struct yfs_xdr_u64) * 2,
690 sizeof(struct yfs_xdr_YFSFetchStatus) +
691 sizeof(struct yfs_xdr_YFSCallBack) +
692 sizeof(struct yfs_xdr_YFSVolSync));
693 if (!call)
694 return -ENOMEM;
695
696 call->key = fc->key;
697 call->reply[0] = vnode;
698 call->reply[1] = NULL; /* volsync */
699 call->reply[2] = req;
700 call->expected_version = vnode->status.data_version;
701 call->want_reply_time = true;
702
703 /* marshall the parameters */
704 bp = call->request;
705 bp = xdr_encode_u32(bp, YFSFETCHDATA64);
706 bp = xdr_encode_u32(bp, 0); /* RPC flags */
707 bp = xdr_encode_YFSFid(bp, &vnode->fid);
708 bp = xdr_encode_u64(bp, req->pos);
709 bp = xdr_encode_u64(bp, req->len);
710 yfs_check_req(call, bp);
711
712 refcount_inc(&req->usage);
713 call->cb_break = fc->cb_break;
714 afs_use_fs_server(call, fc->cbi);
715 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +0100716 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +0100717 afs_make_call(&fc->ac, call, GFP_NOFS);
718 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +0100719}
720
721/*
722 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
723 */
724static int yfs_deliver_fs_create_vnode(struct afs_call *call)
725{
726 struct afs_vnode *vnode = call->reply[0];
727 const __be32 *bp;
728 int ret;
729
730 _enter("{%u}", call->unmarshall);
731
732 ret = afs_transfer_reply(call);
733 if (ret < 0)
734 return ret;
735
736 /* unmarshall the reply once we've received all of it */
737 bp = call->buffer;
738 xdr_decode_YFSFid(&bp, call->reply[1]);
739 ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
740 if (ret < 0)
741 return ret;
742 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
743 &call->expected_version, NULL);
744 if (ret < 0)
745 return ret;
746 xdr_decode_YFSCallBack_raw(&bp, call->reply[3]);
747 xdr_decode_YFSVolSync(&bp, NULL);
748
749 _leave(" = 0 [done]");
750 return 0;
751}
752
753/*
754 * FS.CreateFile and FS.MakeDir operation type
755 */
756static const struct afs_call_type afs_RXFSCreateFile = {
757 .name = "YFS.CreateFile",
758 .op = yfs_FS_CreateFile,
759 .deliver = yfs_deliver_fs_create_vnode,
760 .destructor = afs_flat_call_destructor,
761};
762
763/*
764 * Create a file.
765 */
766int yfs_fs_create_file(struct afs_fs_cursor *fc,
767 const char *name,
768 umode_t mode,
769 u64 current_data_version,
770 struct afs_fid *newfid,
771 struct afs_file_status *newstatus,
772 struct afs_callback *newcb)
773{
774 struct afs_vnode *vnode = fc->vnode;
775 struct afs_call *call;
776 struct afs_net *net = afs_v2net(vnode);
777 size_t namesz, reqsz, rplsz;
778 __be32 *bp;
779
780 _enter("");
781
782 namesz = strlen(name);
783 reqsz = (sizeof(__be32) +
784 sizeof(__be32) +
785 sizeof(struct yfs_xdr_YFSFid) +
786 xdr_strlen(namesz) +
787 sizeof(struct yfs_xdr_YFSStoreStatus) +
788 sizeof(__be32));
789 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
790 sizeof(struct yfs_xdr_YFSFetchStatus) +
791 sizeof(struct yfs_xdr_YFSFetchStatus) +
792 sizeof(struct yfs_xdr_YFSCallBack) +
793 sizeof(struct yfs_xdr_YFSVolSync));
794
795 call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
796 if (!call)
797 return -ENOMEM;
798
799 call->key = fc->key;
800 call->reply[0] = vnode;
801 call->reply[1] = newfid;
802 call->reply[2] = newstatus;
803 call->reply[3] = newcb;
804 call->expected_version = current_data_version + 1;
805
806 /* marshall the parameters */
807 bp = call->request;
808 bp = xdr_encode_u32(bp, YFSCREATEFILE);
809 bp = xdr_encode_u32(bp, 0); /* RPC flags */
810 bp = xdr_encode_YFSFid(bp, &vnode->fid);
811 bp = xdr_encode_string(bp, name, namesz);
812 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
Marc Dionne5edc22c2019-01-09 17:23:54 +0000813 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
David Howells30062bd2018-10-20 00:57:58 +0100814 yfs_check_req(call, bp);
815
816 afs_use_fs_server(call, fc->cbi);
David Howells80548b02019-04-25 14:26:51 +0100817 trace_afs_make_fs_call1(call, &vnode->fid, name);
David Howells20b83912019-05-08 16:16:31 +0100818 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +0100819 afs_make_call(&fc->ac, call, GFP_NOFS);
820 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +0100821}
822
823static const struct afs_call_type yfs_RXFSMakeDir = {
824 .name = "YFS.MakeDir",
825 .op = yfs_FS_MakeDir,
826 .deliver = yfs_deliver_fs_create_vnode,
827 .destructor = afs_flat_call_destructor,
828};
829
830/*
831 * Make a directory.
832 */
833int yfs_fs_make_dir(struct afs_fs_cursor *fc,
834 const char *name,
835 umode_t mode,
836 u64 current_data_version,
837 struct afs_fid *newfid,
838 struct afs_file_status *newstatus,
839 struct afs_callback *newcb)
840{
841 struct afs_vnode *vnode = fc->vnode;
842 struct afs_call *call;
843 struct afs_net *net = afs_v2net(vnode);
844 size_t namesz, reqsz, rplsz;
845 __be32 *bp;
846
847 _enter("");
848
849 namesz = strlen(name);
850 reqsz = (sizeof(__be32) +
851 sizeof(struct yfs_xdr_RPCFlags) +
852 sizeof(struct yfs_xdr_YFSFid) +
853 xdr_strlen(namesz) +
854 sizeof(struct yfs_xdr_YFSStoreStatus));
855 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
856 sizeof(struct yfs_xdr_YFSFetchStatus) +
857 sizeof(struct yfs_xdr_YFSFetchStatus) +
858 sizeof(struct yfs_xdr_YFSCallBack) +
859 sizeof(struct yfs_xdr_YFSVolSync));
860
861 call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
862 if (!call)
863 return -ENOMEM;
864
865 call->key = fc->key;
866 call->reply[0] = vnode;
867 call->reply[1] = newfid;
868 call->reply[2] = newstatus;
869 call->reply[3] = newcb;
870 call->expected_version = current_data_version + 1;
871
872 /* marshall the parameters */
873 bp = call->request;
874 bp = xdr_encode_u32(bp, YFSMAKEDIR);
875 bp = xdr_encode_u32(bp, 0); /* RPC flags */
876 bp = xdr_encode_YFSFid(bp, &vnode->fid);
877 bp = xdr_encode_string(bp, name, namesz);
878 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
879 yfs_check_req(call, bp);
880
881 afs_use_fs_server(call, fc->cbi);
David Howells80548b02019-04-25 14:26:51 +0100882 trace_afs_make_fs_call1(call, &vnode->fid, name);
David Howells20b83912019-05-08 16:16:31 +0100883 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +0100884 afs_make_call(&fc->ac, call, GFP_NOFS);
885 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +0100886}
887
888/*
889 * Deliver reply data to a YFS.RemoveFile2 operation.
890 */
891static int yfs_deliver_fs_remove_file2(struct afs_call *call)
892{
893 struct afs_vnode *dvnode = call->reply[0];
894 struct afs_vnode *vnode = call->reply[1];
895 struct afs_fid fid;
896 const __be32 *bp;
897 int ret;
898
899 _enter("{%u}", call->unmarshall);
900
901 ret = afs_transfer_reply(call);
902 if (ret < 0)
903 return ret;
904
905 /* unmarshall the reply once we've received all of it */
906 bp = call->buffer;
907 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
908 &call->expected_version, NULL);
909 if (ret < 0)
910 return ret;
911
912 xdr_decode_YFSFid(&bp, &fid);
913 ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
914 if (ret < 0)
915 return ret;
916 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
917
918 xdr_decode_YFSVolSync(&bp, NULL);
919 return 0;
920}
921
922/*
923 * YFS.RemoveFile2 operation type.
924 */
925static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
926 .name = "YFS.RemoveFile2",
927 .op = yfs_FS_RemoveFile2,
928 .deliver = yfs_deliver_fs_remove_file2,
929 .destructor = afs_flat_call_destructor,
930};
931
932/*
933 * Remove a file and retrieve new file status.
934 */
935int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
936 const char *name, u64 current_data_version)
937{
938 struct afs_vnode *dvnode = fc->vnode;
939 struct afs_call *call;
940 struct afs_net *net = afs_v2net(dvnode);
941 size_t namesz;
942 __be32 *bp;
943
944 _enter("");
945
946 namesz = strlen(name);
947
948 call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
949 sizeof(__be32) +
950 sizeof(struct yfs_xdr_RPCFlags) +
951 sizeof(struct yfs_xdr_YFSFid) +
952 xdr_strlen(namesz),
953 sizeof(struct yfs_xdr_YFSFetchStatus) +
954 sizeof(struct yfs_xdr_YFSFid) +
955 sizeof(struct yfs_xdr_YFSFetchStatus) +
956 sizeof(struct yfs_xdr_YFSVolSync));
957 if (!call)
958 return -ENOMEM;
959
960 call->key = fc->key;
961 call->reply[0] = dvnode;
962 call->reply[1] = vnode;
963 call->expected_version = current_data_version + 1;
964
965 /* marshall the parameters */
966 bp = call->request;
967 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
968 bp = xdr_encode_u32(bp, 0); /* RPC flags */
969 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
970 bp = xdr_encode_string(bp, name, namesz);
971 yfs_check_req(call, bp);
972
973 afs_use_fs_server(call, fc->cbi);
David Howells80548b02019-04-25 14:26:51 +0100974 trace_afs_make_fs_call1(call, &dvnode->fid, name);
David Howells20b83912019-05-08 16:16:31 +0100975 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +0100976 afs_make_call(&fc->ac, call, GFP_NOFS);
977 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +0100978}
979
980/*
981 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
982 */
983static int yfs_deliver_fs_remove(struct afs_call *call)
984{
985 struct afs_vnode *dvnode = call->reply[0];
986 const __be32 *bp;
987 int ret;
988
989 _enter("{%u}", call->unmarshall);
990
991 ret = afs_transfer_reply(call);
992 if (ret < 0)
993 return ret;
994
995 /* unmarshall the reply once we've received all of it */
996 bp = call->buffer;
997 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
998 &call->expected_version, NULL);
999 if (ret < 0)
1000 return ret;
1001
1002 xdr_decode_YFSVolSync(&bp, NULL);
1003 return 0;
1004}
1005
1006/*
1007 * FS.RemoveDir and FS.RemoveFile operation types.
1008 */
1009static const struct afs_call_type yfs_RXYFSRemoveFile = {
1010 .name = "YFS.RemoveFile",
1011 .op = yfs_FS_RemoveFile,
1012 .deliver = yfs_deliver_fs_remove,
1013 .destructor = afs_flat_call_destructor,
1014};
1015
1016static const struct afs_call_type yfs_RXYFSRemoveDir = {
1017 .name = "YFS.RemoveDir",
1018 .op = yfs_FS_RemoveDir,
1019 .deliver = yfs_deliver_fs_remove,
1020 .destructor = afs_flat_call_destructor,
1021};
1022
1023/*
1024 * remove a file or directory
1025 */
1026int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1027 const char *name, bool isdir, u64 current_data_version)
1028{
1029 struct afs_vnode *dvnode = fc->vnode;
1030 struct afs_call *call;
1031 struct afs_net *net = afs_v2net(dvnode);
1032 size_t namesz;
1033 __be32 *bp;
1034
1035 _enter("");
1036
1037 namesz = strlen(name);
1038 call = afs_alloc_flat_call(
1039 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
1040 sizeof(__be32) +
1041 sizeof(struct yfs_xdr_RPCFlags) +
1042 sizeof(struct yfs_xdr_YFSFid) +
1043 xdr_strlen(namesz),
1044 sizeof(struct yfs_xdr_YFSFetchStatus) +
1045 sizeof(struct yfs_xdr_YFSVolSync));
1046 if (!call)
1047 return -ENOMEM;
1048
1049 call->key = fc->key;
1050 call->reply[0] = dvnode;
1051 call->reply[1] = vnode;
1052 call->expected_version = current_data_version + 1;
1053
1054 /* marshall the parameters */
1055 bp = call->request;
1056 bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
1057 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1058 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1059 bp = xdr_encode_string(bp, name, namesz);
1060 yfs_check_req(call, bp);
1061
1062 afs_use_fs_server(call, fc->cbi);
David Howells80548b02019-04-25 14:26:51 +01001063 trace_afs_make_fs_call1(call, &dvnode->fid, name);
David Howells20b83912019-05-08 16:16:31 +01001064 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001065 afs_make_call(&fc->ac, call, GFP_NOFS);
1066 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001067}
1068
1069/*
1070 * Deliver reply data to a YFS.Link operation.
1071 */
1072static int yfs_deliver_fs_link(struct afs_call *call)
1073{
1074 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
1075 const __be32 *bp;
1076 int ret;
1077
1078 _enter("{%u}", call->unmarshall);
1079
1080 ret = afs_transfer_reply(call);
1081 if (ret < 0)
1082 return ret;
1083
1084 /* unmarshall the reply once we've received all of it */
1085 bp = call->buffer;
1086 ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
1087 if (ret < 0)
1088 return ret;
1089 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
1090 &call->expected_version, NULL);
1091 if (ret < 0)
1092 return ret;
1093 xdr_decode_YFSVolSync(&bp, NULL);
1094 _leave(" = 0 [done]");
1095 return 0;
1096}
1097
1098/*
1099 * YFS.Link operation type.
1100 */
1101static const struct afs_call_type yfs_RXYFSLink = {
1102 .name = "YFS.Link",
1103 .op = yfs_FS_Link,
1104 .deliver = yfs_deliver_fs_link,
1105 .destructor = afs_flat_call_destructor,
1106};
1107
1108/*
1109 * Make a hard link.
1110 */
1111int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1112 const char *name, u64 current_data_version)
1113{
1114 struct afs_vnode *dvnode = fc->vnode;
1115 struct afs_call *call;
1116 struct afs_net *net = afs_v2net(vnode);
1117 size_t namesz;
1118 __be32 *bp;
1119
1120 _enter("");
1121
1122 namesz = strlen(name);
1123 call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1124 sizeof(__be32) +
1125 sizeof(struct yfs_xdr_RPCFlags) +
1126 sizeof(struct yfs_xdr_YFSFid) +
1127 xdr_strlen(namesz) +
1128 sizeof(struct yfs_xdr_YFSFid),
1129 sizeof(struct yfs_xdr_YFSFetchStatus) +
1130 sizeof(struct yfs_xdr_YFSFetchStatus) +
1131 sizeof(struct yfs_xdr_YFSVolSync));
1132 if (!call)
1133 return -ENOMEM;
1134
1135 call->key = fc->key;
1136 call->reply[0] = dvnode;
1137 call->reply[1] = vnode;
1138 call->expected_version = current_data_version + 1;
1139
1140 /* marshall the parameters */
1141 bp = call->request;
1142 bp = xdr_encode_u32(bp, YFSLINK);
1143 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1144 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1145 bp = xdr_encode_string(bp, name, namesz);
1146 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1147 yfs_check_req(call, bp);
1148
1149 afs_use_fs_server(call, fc->cbi);
David Howells80548b02019-04-25 14:26:51 +01001150 trace_afs_make_fs_call1(call, &vnode->fid, name);
David Howells20b83912019-05-08 16:16:31 +01001151 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001152 afs_make_call(&fc->ac, call, GFP_NOFS);
1153 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001154}
1155
1156/*
1157 * Deliver reply data to a YFS.Symlink operation.
1158 */
1159static int yfs_deliver_fs_symlink(struct afs_call *call)
1160{
1161 struct afs_vnode *vnode = call->reply[0];
1162 const __be32 *bp;
1163 int ret;
1164
1165 _enter("{%u}", call->unmarshall);
1166
1167 ret = afs_transfer_reply(call);
1168 if (ret < 0)
1169 return ret;
1170
1171 /* unmarshall the reply once we've received all of it */
1172 bp = call->buffer;
1173 xdr_decode_YFSFid(&bp, call->reply[1]);
1174 ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
1175 if (ret < 0)
1176 return ret;
1177 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1178 &call->expected_version, NULL);
1179 if (ret < 0)
1180 return ret;
1181 xdr_decode_YFSVolSync(&bp, NULL);
1182
1183 _leave(" = 0 [done]");
1184 return 0;
1185}
1186
1187/*
1188 * YFS.Symlink operation type
1189 */
1190static const struct afs_call_type yfs_RXYFSSymlink = {
1191 .name = "YFS.Symlink",
1192 .op = yfs_FS_Symlink,
1193 .deliver = yfs_deliver_fs_symlink,
1194 .destructor = afs_flat_call_destructor,
1195};
1196
1197/*
1198 * Create a symbolic link.
1199 */
1200int yfs_fs_symlink(struct afs_fs_cursor *fc,
1201 const char *name,
1202 const char *contents,
1203 u64 current_data_version,
1204 struct afs_fid *newfid,
1205 struct afs_file_status *newstatus)
1206{
1207 struct afs_vnode *dvnode = fc->vnode;
1208 struct afs_call *call;
1209 struct afs_net *net = afs_v2net(dvnode);
1210 size_t namesz, contents_sz;
1211 __be32 *bp;
1212
1213 _enter("");
1214
1215 namesz = strlen(name);
1216 contents_sz = strlen(contents);
1217 call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1218 sizeof(__be32) +
1219 sizeof(struct yfs_xdr_RPCFlags) +
1220 sizeof(struct yfs_xdr_YFSFid) +
1221 xdr_strlen(namesz) +
1222 xdr_strlen(contents_sz) +
1223 sizeof(struct yfs_xdr_YFSStoreStatus),
1224 sizeof(struct yfs_xdr_YFSFid) +
1225 sizeof(struct yfs_xdr_YFSFetchStatus) +
1226 sizeof(struct yfs_xdr_YFSFetchStatus) +
1227 sizeof(struct yfs_xdr_YFSVolSync));
1228 if (!call)
1229 return -ENOMEM;
1230
1231 call->key = fc->key;
1232 call->reply[0] = dvnode;
1233 call->reply[1] = newfid;
1234 call->reply[2] = newstatus;
1235 call->expected_version = current_data_version + 1;
1236
1237 /* marshall the parameters */
1238 bp = call->request;
1239 bp = xdr_encode_u32(bp, YFSSYMLINK);
1240 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1241 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1242 bp = xdr_encode_string(bp, name, namesz);
1243 bp = xdr_encode_string(bp, contents, contents_sz);
1244 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1245 yfs_check_req(call, bp);
1246
1247 afs_use_fs_server(call, fc->cbi);
David Howells80548b02019-04-25 14:26:51 +01001248 trace_afs_make_fs_call1(call, &dvnode->fid, name);
David Howells20b83912019-05-08 16:16:31 +01001249 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001250 afs_make_call(&fc->ac, call, GFP_NOFS);
1251 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001252}
1253
1254/*
1255 * Deliver reply data to a YFS.Rename operation.
1256 */
1257static int yfs_deliver_fs_rename(struct afs_call *call)
1258{
1259 struct afs_vnode *orig_dvnode = call->reply[0];
1260 struct afs_vnode *new_dvnode = call->reply[1];
1261 const __be32 *bp;
1262 int ret;
1263
1264 _enter("{%u}", call->unmarshall);
1265
1266 ret = afs_transfer_reply(call);
1267 if (ret < 0)
1268 return ret;
1269
1270 /* unmarshall the reply once we've received all of it */
1271 bp = call->buffer;
1272 ret = yfs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
1273 &call->expected_version, NULL);
1274 if (ret < 0)
1275 return ret;
1276 if (new_dvnode != orig_dvnode) {
1277 ret = yfs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
1278 &call->expected_version_2, NULL);
1279 if (ret < 0)
1280 return ret;
1281 }
1282
1283 xdr_decode_YFSVolSync(&bp, NULL);
1284 _leave(" = 0 [done]");
1285 return 0;
1286}
1287
1288/*
1289 * YFS.Rename operation type
1290 */
1291static const struct afs_call_type yfs_RXYFSRename = {
1292 .name = "FS.Rename",
1293 .op = yfs_FS_Rename,
1294 .deliver = yfs_deliver_fs_rename,
1295 .destructor = afs_flat_call_destructor,
1296};
1297
1298/*
1299 * Rename a file or directory.
1300 */
1301int yfs_fs_rename(struct afs_fs_cursor *fc,
1302 const char *orig_name,
1303 struct afs_vnode *new_dvnode,
1304 const char *new_name,
1305 u64 current_orig_data_version,
1306 u64 current_new_data_version)
1307{
1308 struct afs_vnode *orig_dvnode = fc->vnode;
1309 struct afs_call *call;
1310 struct afs_net *net = afs_v2net(orig_dvnode);
1311 size_t o_namesz, n_namesz;
1312 __be32 *bp;
1313
1314 _enter("");
1315
1316 o_namesz = strlen(orig_name);
1317 n_namesz = strlen(new_name);
1318 call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1319 sizeof(__be32) +
1320 sizeof(struct yfs_xdr_RPCFlags) +
1321 sizeof(struct yfs_xdr_YFSFid) +
1322 xdr_strlen(o_namesz) +
1323 sizeof(struct yfs_xdr_YFSFid) +
1324 xdr_strlen(n_namesz),
1325 sizeof(struct yfs_xdr_YFSFetchStatus) +
1326 sizeof(struct yfs_xdr_YFSFetchStatus) +
1327 sizeof(struct yfs_xdr_YFSVolSync));
1328 if (!call)
1329 return -ENOMEM;
1330
1331 call->key = fc->key;
1332 call->reply[0] = orig_dvnode;
1333 call->reply[1] = new_dvnode;
1334 call->expected_version = current_orig_data_version + 1;
1335 call->expected_version_2 = current_new_data_version + 1;
1336
1337 /* marshall the parameters */
1338 bp = call->request;
1339 bp = xdr_encode_u32(bp, YFSRENAME);
1340 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1341 bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1342 bp = xdr_encode_string(bp, orig_name, o_namesz);
1343 bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1344 bp = xdr_encode_string(bp, new_name, n_namesz);
1345 yfs_check_req(call, bp);
1346
1347 afs_use_fs_server(call, fc->cbi);
David Howells80548b02019-04-25 14:26:51 +01001348 trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
David Howells20b83912019-05-08 16:16:31 +01001349 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001350 afs_make_call(&fc->ac, call, GFP_NOFS);
1351 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001352}
1353
1354/*
1355 * Deliver reply data to a YFS.StoreData64 operation.
1356 */
1357static int yfs_deliver_fs_store_data(struct afs_call *call)
1358{
1359 struct afs_vnode *vnode = call->reply[0];
1360 const __be32 *bp;
1361 int ret;
1362
1363 _enter("");
1364
1365 ret = afs_transfer_reply(call);
1366 if (ret < 0)
1367 return ret;
1368
1369 /* unmarshall the reply once we've received all of it */
1370 bp = call->buffer;
1371 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1372 &call->expected_version, NULL);
1373 if (ret < 0)
1374 return ret;
1375 xdr_decode_YFSVolSync(&bp, NULL);
1376
1377 afs_pages_written_back(vnode, call);
1378
1379 _leave(" = 0 [done]");
1380 return 0;
1381}
1382
1383/*
1384 * YFS.StoreData64 operation type.
1385 */
1386static const struct afs_call_type yfs_RXYFSStoreData64 = {
1387 .name = "YFS.StoreData64",
1388 .op = yfs_FS_StoreData64,
1389 .deliver = yfs_deliver_fs_store_data,
1390 .destructor = afs_flat_call_destructor,
1391};
1392
1393/*
1394 * Store a set of pages to a large file.
1395 */
1396int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1397 pgoff_t first, pgoff_t last,
1398 unsigned offset, unsigned to)
1399{
1400 struct afs_vnode *vnode = fc->vnode;
1401 struct afs_call *call;
1402 struct afs_net *net = afs_v2net(vnode);
1403 loff_t size, pos, i_size;
1404 __be32 *bp;
1405
1406 _enter(",%x,{%llx:%llu},,",
1407 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1408
1409 size = (loff_t)to - (loff_t)offset;
1410 if (first != last)
1411 size += (loff_t)(last - first) << PAGE_SHIFT;
1412 pos = (loff_t)first << PAGE_SHIFT;
1413 pos += offset;
1414
1415 i_size = i_size_read(&vnode->vfs_inode);
1416 if (pos + size > i_size)
1417 i_size = size + pos;
1418
1419 _debug("size %llx, at %llx, i_size %llx",
1420 (unsigned long long)size, (unsigned long long)pos,
1421 (unsigned long long)i_size);
1422
1423 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1424 sizeof(__be32) +
1425 sizeof(__be32) +
1426 sizeof(struct yfs_xdr_YFSFid) +
1427 sizeof(struct yfs_xdr_YFSStoreStatus) +
1428 sizeof(struct yfs_xdr_u64) * 3,
1429 sizeof(struct yfs_xdr_YFSFetchStatus) +
1430 sizeof(struct yfs_xdr_YFSVolSync));
1431 if (!call)
1432 return -ENOMEM;
1433
1434 call->key = fc->key;
1435 call->mapping = mapping;
1436 call->reply[0] = vnode;
1437 call->first = first;
1438 call->last = last;
1439 call->first_offset = offset;
1440 call->last_to = to;
1441 call->send_pages = true;
1442 call->expected_version = vnode->status.data_version + 1;
1443
1444 /* marshall the parameters */
1445 bp = call->request;
1446 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1447 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1448 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1449 bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1450 bp = xdr_encode_u64(bp, pos);
1451 bp = xdr_encode_u64(bp, size);
1452 bp = xdr_encode_u64(bp, i_size);
1453 yfs_check_req(call, bp);
1454
1455 afs_use_fs_server(call, fc->cbi);
1456 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +01001457 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001458 afs_make_call(&fc->ac, call, GFP_NOFS);
1459 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001460}
1461
1462/*
1463 * deliver reply data to an FS.StoreStatus
1464 */
1465static int yfs_deliver_fs_store_status(struct afs_call *call)
1466{
1467 struct afs_vnode *vnode = call->reply[0];
1468 const __be32 *bp;
1469 int ret;
1470
1471 _enter("");
1472
1473 ret = afs_transfer_reply(call);
1474 if (ret < 0)
1475 return ret;
1476
1477 /* unmarshall the reply once we've received all of it */
1478 bp = call->buffer;
1479 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1480 &call->expected_version, NULL);
1481 if (ret < 0)
1482 return ret;
1483 xdr_decode_YFSVolSync(&bp, NULL);
1484
1485 _leave(" = 0 [done]");
1486 return 0;
1487}
1488
1489/*
1490 * YFS.StoreStatus operation type
1491 */
1492static const struct afs_call_type yfs_RXYFSStoreStatus = {
1493 .name = "YFS.StoreStatus",
1494 .op = yfs_FS_StoreStatus,
1495 .deliver = yfs_deliver_fs_store_status,
1496 .destructor = afs_flat_call_destructor,
1497};
1498
1499static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1500 .name = "YFS.StoreData64",
1501 .op = yfs_FS_StoreData64,
1502 .deliver = yfs_deliver_fs_store_status,
1503 .destructor = afs_flat_call_destructor,
1504};
1505
1506/*
1507 * Set the attributes on a file, using YFS.StoreData64 rather than
1508 * YFS.StoreStatus so as to alter the file size also.
1509 */
1510static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1511{
1512 struct afs_vnode *vnode = fc->vnode;
1513 struct afs_call *call;
1514 struct afs_net *net = afs_v2net(vnode);
1515 __be32 *bp;
1516
1517 _enter(",%x,{%llx:%llu},,",
1518 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1519
1520 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1521 sizeof(__be32) * 2 +
1522 sizeof(struct yfs_xdr_YFSFid) +
1523 sizeof(struct yfs_xdr_YFSStoreStatus) +
1524 sizeof(struct yfs_xdr_u64) * 3,
1525 sizeof(struct yfs_xdr_YFSFetchStatus) +
1526 sizeof(struct yfs_xdr_YFSVolSync));
1527 if (!call)
1528 return -ENOMEM;
1529
1530 call->key = fc->key;
1531 call->reply[0] = vnode;
1532 call->expected_version = vnode->status.data_version + 1;
1533
1534 /* marshall the parameters */
1535 bp = call->request;
1536 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1537 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1538 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1539 bp = xdr_encode_YFS_StoreStatus(bp, attr);
David Howells8c7ae382019-03-27 22:48:02 +00001540 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
David Howells30062bd2018-10-20 00:57:58 +01001541 bp = xdr_encode_u64(bp, 0); /* size of write */
1542 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1543 yfs_check_req(call, bp);
1544
1545 afs_use_fs_server(call, fc->cbi);
1546 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +01001547 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001548 afs_make_call(&fc->ac, call, GFP_NOFS);
1549 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001550}
1551
1552/*
1553 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1554 * file size, and YFS.StoreStatus otherwise.
1555 */
1556int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1557{
1558 struct afs_vnode *vnode = fc->vnode;
1559 struct afs_call *call;
1560 struct afs_net *net = afs_v2net(vnode);
1561 __be32 *bp;
1562
1563 if (attr->ia_valid & ATTR_SIZE)
1564 return yfs_fs_setattr_size(fc, attr);
1565
1566 _enter(",%x,{%llx:%llu},,",
1567 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1568
1569 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1570 sizeof(__be32) * 2 +
1571 sizeof(struct yfs_xdr_YFSFid) +
1572 sizeof(struct yfs_xdr_YFSStoreStatus),
1573 sizeof(struct yfs_xdr_YFSFetchStatus) +
1574 sizeof(struct yfs_xdr_YFSVolSync));
1575 if (!call)
1576 return -ENOMEM;
1577
1578 call->key = fc->key;
1579 call->reply[0] = vnode;
1580 call->expected_version = vnode->status.data_version;
1581
1582 /* marshall the parameters */
1583 bp = call->request;
1584 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1585 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1586 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1587 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1588 yfs_check_req(call, bp);
1589
1590 afs_use_fs_server(call, fc->cbi);
1591 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +01001592 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001593 afs_make_call(&fc->ac, call, GFP_NOFS);
1594 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001595}
1596
1597/*
1598 * Deliver reply data to a YFS.GetVolumeStatus operation.
1599 */
1600static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1601{
1602 const __be32 *bp;
1603 char *p;
1604 u32 size;
1605 int ret;
1606
1607 _enter("{%u}", call->unmarshall);
1608
1609 switch (call->unmarshall) {
1610 case 0:
1611 call->unmarshall++;
1612 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1613
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001614 /* Fall through - and extract the returned status record */
David Howells30062bd2018-10-20 00:57:58 +01001615 case 1:
1616 _debug("extract status");
1617 ret = afs_extract_data(call, true);
1618 if (ret < 0)
1619 return ret;
1620
1621 bp = call->buffer;
1622 xdr_decode_YFSFetchVolumeStatus(&bp, call->reply[1]);
1623 call->unmarshall++;
1624 afs_extract_to_tmp(call);
1625
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001626 /* Fall through - and extract the volume name length */
David Howells30062bd2018-10-20 00:57:58 +01001627 case 2:
1628 ret = afs_extract_data(call, true);
1629 if (ret < 0)
1630 return ret;
1631
1632 call->count = ntohl(call->tmp);
1633 _debug("volname length: %u", call->count);
1634 if (call->count >= AFSNAMEMAX)
1635 return afs_protocol_error(call, -EBADMSG,
1636 afs_eproto_volname_len);
1637 size = (call->count + 3) & ~3; /* It's padded */
1638 afs_extract_begin(call, call->reply[2], size);
1639 call->unmarshall++;
1640
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001641 /* Fall through - and extract the volume name */
David Howells30062bd2018-10-20 00:57:58 +01001642 case 3:
1643 _debug("extract volname");
1644 ret = afs_extract_data(call, true);
1645 if (ret < 0)
1646 return ret;
1647
1648 p = call->reply[2];
1649 p[call->count] = 0;
1650 _debug("volname '%s'", p);
1651 afs_extract_to_tmp(call);
1652 call->unmarshall++;
1653
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001654 /* Fall through - and extract the offline message length */
David Howells30062bd2018-10-20 00:57:58 +01001655 case 4:
1656 ret = afs_extract_data(call, true);
1657 if (ret < 0)
1658 return ret;
1659
1660 call->count = ntohl(call->tmp);
1661 _debug("offline msg length: %u", call->count);
1662 if (call->count >= AFSNAMEMAX)
1663 return afs_protocol_error(call, -EBADMSG,
1664 afs_eproto_offline_msg_len);
1665 size = (call->count + 3) & ~3; /* It's padded */
1666 afs_extract_begin(call, call->reply[2], size);
1667 call->unmarshall++;
1668
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001669 /* Fall through - and extract the offline message */
David Howells30062bd2018-10-20 00:57:58 +01001670 case 5:
1671 _debug("extract offline");
1672 ret = afs_extract_data(call, true);
1673 if (ret < 0)
1674 return ret;
1675
1676 p = call->reply[2];
1677 p[call->count] = 0;
1678 _debug("offline '%s'", p);
1679
1680 afs_extract_to_tmp(call);
1681 call->unmarshall++;
1682
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001683 /* Fall through - and extract the message of the day length */
David Howells30062bd2018-10-20 00:57:58 +01001684 case 6:
1685 ret = afs_extract_data(call, true);
1686 if (ret < 0)
1687 return ret;
1688
1689 call->count = ntohl(call->tmp);
1690 _debug("motd length: %u", call->count);
1691 if (call->count >= AFSNAMEMAX)
1692 return afs_protocol_error(call, -EBADMSG,
1693 afs_eproto_motd_len);
1694 size = (call->count + 3) & ~3; /* It's padded */
1695 afs_extract_begin(call, call->reply[2], size);
1696 call->unmarshall++;
1697
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001698 /* Fall through - and extract the message of the day */
David Howells30062bd2018-10-20 00:57:58 +01001699 case 7:
1700 _debug("extract motd");
1701 ret = afs_extract_data(call, false);
1702 if (ret < 0)
1703 return ret;
1704
1705 p = call->reply[2];
1706 p[call->count] = 0;
1707 _debug("motd '%s'", p);
1708
1709 call->unmarshall++;
1710
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06001711 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +01001712 case 8:
1713 break;
1714 }
1715
1716 _leave(" = 0 [done]");
1717 return 0;
1718}
1719
1720/*
1721 * Destroy a YFS.GetVolumeStatus call.
1722 */
1723static void yfs_get_volume_status_call_destructor(struct afs_call *call)
1724{
1725 kfree(call->reply[2]);
1726 call->reply[2] = NULL;
1727 afs_flat_call_destructor(call);
1728}
1729
1730/*
1731 * YFS.GetVolumeStatus operation type
1732 */
1733static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1734 .name = "YFS.GetVolumeStatus",
1735 .op = yfs_FS_GetVolumeStatus,
1736 .deliver = yfs_deliver_fs_get_volume_status,
1737 .destructor = yfs_get_volume_status_call_destructor,
1738};
1739
1740/*
1741 * fetch the status of a volume
1742 */
1743int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1744 struct afs_volume_status *vs)
1745{
1746 struct afs_vnode *vnode = fc->vnode;
1747 struct afs_call *call;
1748 struct afs_net *net = afs_v2net(vnode);
1749 __be32 *bp;
1750 void *tmpbuf;
1751
1752 _enter("");
1753
1754 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1755 if (!tmpbuf)
1756 return -ENOMEM;
1757
1758 call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1759 sizeof(__be32) * 2 +
1760 sizeof(struct yfs_xdr_u64),
1761 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1762 sizeof(__be32));
1763 if (!call) {
1764 kfree(tmpbuf);
1765 return -ENOMEM;
1766 }
1767
1768 call->key = fc->key;
1769 call->reply[0] = vnode;
1770 call->reply[1] = vs;
1771 call->reply[2] = tmpbuf;
1772
1773 /* marshall the parameters */
1774 bp = call->request;
1775 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1776 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1777 bp = xdr_encode_u64(bp, vnode->fid.vid);
1778 yfs_check_req(call, bp);
1779
1780 afs_use_fs_server(call, fc->cbi);
1781 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +01001782 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001783 afs_make_call(&fc->ac, call, GFP_NOFS);
1784 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001785}
1786
1787/*
David Howellsf5e45462019-05-01 14:05:27 +01001788 * Deliver reply data to operations that just return a file status and a volume
1789 * sync record.
David Howells30062bd2018-10-20 00:57:58 +01001790 */
David Howellsf5e45462019-05-01 14:05:27 +01001791static int yfs_deliver_status_and_volsync(struct afs_call *call)
David Howells30062bd2018-10-20 00:57:58 +01001792{
1793 struct afs_vnode *vnode = call->reply[0];
1794 const __be32 *bp;
1795 int ret;
1796
1797 _enter("{%u}", call->unmarshall);
1798
1799 ret = afs_transfer_reply(call);
1800 if (ret < 0)
1801 return ret;
1802
1803 /* unmarshall the reply once we've received all of it */
1804 bp = call->buffer;
1805 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1806 &call->expected_version, NULL);
1807 if (ret < 0)
1808 return ret;
1809 xdr_decode_YFSVolSync(&bp, NULL);
1810
1811 _leave(" = 0 [done]");
1812 return 0;
1813}
1814
1815/*
1816 * YFS.SetLock operation type
1817 */
1818static const struct afs_call_type yfs_RXYFSSetLock = {
1819 .name = "YFS.SetLock",
1820 .op = yfs_FS_SetLock,
David Howellsf5e45462019-05-01 14:05:27 +01001821 .deliver = yfs_deliver_status_and_volsync,
David Howellsa690f602019-04-25 14:26:50 +01001822 .done = afs_lock_op_done,
David Howells30062bd2018-10-20 00:57:58 +01001823 .destructor = afs_flat_call_destructor,
1824};
1825
1826/*
1827 * YFS.ExtendLock operation type
1828 */
1829static const struct afs_call_type yfs_RXYFSExtendLock = {
1830 .name = "YFS.ExtendLock",
1831 .op = yfs_FS_ExtendLock,
David Howellsf5e45462019-05-01 14:05:27 +01001832 .deliver = yfs_deliver_status_and_volsync,
David Howellsa690f602019-04-25 14:26:50 +01001833 .done = afs_lock_op_done,
David Howells30062bd2018-10-20 00:57:58 +01001834 .destructor = afs_flat_call_destructor,
1835};
1836
1837/*
1838 * YFS.ReleaseLock operation type
1839 */
1840static const struct afs_call_type yfs_RXYFSReleaseLock = {
1841 .name = "YFS.ReleaseLock",
1842 .op = yfs_FS_ReleaseLock,
David Howellsf5e45462019-05-01 14:05:27 +01001843 .deliver = yfs_deliver_status_and_volsync,
David Howells30062bd2018-10-20 00:57:58 +01001844 .destructor = afs_flat_call_destructor,
1845};
1846
1847/*
1848 * Set a lock on a file
1849 */
1850int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1851{
1852 struct afs_vnode *vnode = fc->vnode;
1853 struct afs_call *call;
1854 struct afs_net *net = afs_v2net(vnode);
1855 __be32 *bp;
1856
1857 _enter("");
1858
1859 call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1860 sizeof(__be32) * 2 +
1861 sizeof(struct yfs_xdr_YFSFid) +
1862 sizeof(__be32),
1863 sizeof(struct yfs_xdr_YFSFetchStatus) +
1864 sizeof(struct yfs_xdr_YFSVolSync));
1865 if (!call)
1866 return -ENOMEM;
1867
1868 call->key = fc->key;
1869 call->reply[0] = vnode;
David Howellsa690f602019-04-25 14:26:50 +01001870 call->want_reply_time = true;
David Howells30062bd2018-10-20 00:57:58 +01001871
1872 /* marshall the parameters */
1873 bp = call->request;
1874 bp = xdr_encode_u32(bp, YFSSETLOCK);
1875 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1876 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1877 bp = xdr_encode_u32(bp, type);
1878 yfs_check_req(call, bp);
1879
1880 afs_use_fs_server(call, fc->cbi);
David Howells6c6c1d62019-04-25 14:26:52 +01001881 trace_afs_make_fs_calli(call, &vnode->fid, type);
David Howells20b83912019-05-08 16:16:31 +01001882 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001883 afs_make_call(&fc->ac, call, GFP_NOFS);
1884 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001885}
1886
1887/*
1888 * extend a lock on a file
1889 */
1890int yfs_fs_extend_lock(struct afs_fs_cursor *fc)
1891{
1892 struct afs_vnode *vnode = fc->vnode;
1893 struct afs_call *call;
1894 struct afs_net *net = afs_v2net(vnode);
1895 __be32 *bp;
1896
1897 _enter("");
1898
1899 call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1900 sizeof(__be32) * 2 +
1901 sizeof(struct yfs_xdr_YFSFid),
1902 sizeof(struct yfs_xdr_YFSFetchStatus) +
1903 sizeof(struct yfs_xdr_YFSVolSync));
1904 if (!call)
1905 return -ENOMEM;
1906
1907 call->key = fc->key;
1908 call->reply[0] = vnode;
David Howellsa690f602019-04-25 14:26:50 +01001909 call->want_reply_time = true;
David Howells30062bd2018-10-20 00:57:58 +01001910
1911 /* marshall the parameters */
1912 bp = call->request;
1913 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1914 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1915 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1916 yfs_check_req(call, bp);
1917
1918 afs_use_fs_server(call, fc->cbi);
1919 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +01001920 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001921 afs_make_call(&fc->ac, call, GFP_NOFS);
1922 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001923}
1924
1925/*
1926 * release a lock on a file
1927 */
1928int yfs_fs_release_lock(struct afs_fs_cursor *fc)
1929{
1930 struct afs_vnode *vnode = fc->vnode;
1931 struct afs_call *call;
1932 struct afs_net *net = afs_v2net(vnode);
1933 __be32 *bp;
1934
1935 _enter("");
1936
1937 call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1938 sizeof(__be32) * 2 +
1939 sizeof(struct yfs_xdr_YFSFid),
1940 sizeof(struct yfs_xdr_YFSFetchStatus) +
1941 sizeof(struct yfs_xdr_YFSVolSync));
1942 if (!call)
1943 return -ENOMEM;
1944
1945 call->key = fc->key;
1946 call->reply[0] = vnode;
1947
1948 /* marshall the parameters */
1949 bp = call->request;
1950 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1951 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1952 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1953 yfs_check_req(call, bp);
1954
1955 afs_use_fs_server(call, fc->cbi);
1956 trace_afs_make_fs_call(call, &vnode->fid);
David Howells20b83912019-05-08 16:16:31 +01001957 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01001958 afs_make_call(&fc->ac, call, GFP_NOFS);
1959 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01001960}
1961
1962/*
1963 * Deliver reply data to an FS.FetchStatus with no vnode.
1964 */
1965static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1966{
1967 struct afs_file_status *status = call->reply[1];
1968 struct afs_callback *callback = call->reply[2];
1969 struct afs_volsync *volsync = call->reply[3];
1970 struct afs_vnode *vnode = call->reply[0];
1971 const __be32 *bp;
1972 int ret;
1973
1974 ret = afs_transfer_reply(call);
1975 if (ret < 0)
1976 return ret;
1977
1978 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
1979
1980 /* unmarshall the reply once we've received all of it */
1981 bp = call->buffer;
1982 ret = yfs_decode_status(call, &bp, status, vnode,
1983 &call->expected_version, NULL);
1984 if (ret < 0)
1985 return ret;
1986 xdr_decode_YFSCallBack_raw(&bp, callback);
1987 xdr_decode_YFSVolSync(&bp, volsync);
1988
1989 _leave(" = 0 [done]");
1990 return 0;
1991}
1992
1993/*
1994 * YFS.FetchStatus operation type
1995 */
1996static const struct afs_call_type yfs_RXYFSFetchStatus = {
1997 .name = "YFS.FetchStatus",
1998 .op = yfs_FS_FetchStatus,
1999 .deliver = yfs_deliver_fs_fetch_status,
2000 .destructor = afs_flat_call_destructor,
2001};
2002
2003/*
2004 * Fetch the status information for a fid without needing a vnode handle.
2005 */
2006int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
2007 struct afs_net *net,
2008 struct afs_fid *fid,
2009 struct afs_file_status *status,
2010 struct afs_callback *callback,
2011 struct afs_volsync *volsync)
2012{
2013 struct afs_call *call;
2014 __be32 *bp;
2015
2016 _enter(",%x,{%llx:%llu},,",
2017 key_serial(fc->key), fid->vid, fid->vnode);
2018
2019 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
2020 sizeof(__be32) * 2 +
2021 sizeof(struct yfs_xdr_YFSFid),
2022 sizeof(struct yfs_xdr_YFSFetchStatus) +
2023 sizeof(struct yfs_xdr_YFSCallBack) +
2024 sizeof(struct yfs_xdr_YFSVolSync));
2025 if (!call) {
2026 fc->ac.error = -ENOMEM;
2027 return -ENOMEM;
2028 }
2029
2030 call->key = fc->key;
2031 call->reply[0] = NULL; /* vnode for fid[0] */
2032 call->reply[1] = status;
2033 call->reply[2] = callback;
2034 call->reply[3] = volsync;
2035 call->expected_version = 1; /* vnode->status.data_version */
2036
2037 /* marshall the parameters */
2038 bp = call->request;
2039 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
2040 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2041 bp = xdr_encode_YFSFid(bp, fid);
2042 yfs_check_req(call, bp);
2043
2044 call->cb_break = fc->cb_break;
2045 afs_use_fs_server(call, fc->cbi);
2046 trace_afs_make_fs_call(call, fid);
David Howells20b83912019-05-08 16:16:31 +01002047 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01002048 afs_make_call(&fc->ac, call, GFP_NOFS);
2049 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01002050}
2051
2052/*
2053 * Deliver reply data to an YFS.InlineBulkStatus call
2054 */
2055static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
2056{
2057 struct afs_file_status *statuses;
2058 struct afs_callback *callbacks;
2059 struct afs_vnode *vnode = call->reply[0];
2060 const __be32 *bp;
2061 u32 tmp;
2062 int ret;
2063
2064 _enter("{%u}", call->unmarshall);
2065
2066 switch (call->unmarshall) {
2067 case 0:
2068 afs_extract_to_tmp(call);
2069 call->unmarshall++;
2070
2071 /* Extract the file status count and array in two steps */
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06002072 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +01002073 case 1:
2074 _debug("extract status count");
2075 ret = afs_extract_data(call, true);
2076 if (ret < 0)
2077 return ret;
2078
2079 tmp = ntohl(call->tmp);
2080 _debug("status count: %u/%u", tmp, call->count2);
2081 if (tmp != call->count2)
2082 return afs_protocol_error(call, -EBADMSG,
2083 afs_eproto_ibulkst_count);
2084
2085 call->count = 0;
2086 call->unmarshall++;
2087 more_counts:
2088 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
2089
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06002090 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +01002091 case 2:
2092 _debug("extract status array %u", call->count);
2093 ret = afs_extract_data(call, true);
2094 if (ret < 0)
2095 return ret;
2096
2097 bp = call->buffer;
2098 statuses = call->reply[1];
2099 ret = yfs_decode_status(call, &bp, &statuses[call->count],
2100 call->count == 0 ? vnode : NULL,
2101 NULL, NULL);
2102 if (ret < 0)
2103 return ret;
2104
2105 call->count++;
2106 if (call->count < call->count2)
2107 goto more_counts;
2108
2109 call->count = 0;
2110 call->unmarshall++;
2111 afs_extract_to_tmp(call);
2112
2113 /* Extract the callback count and array in two steps */
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06002114 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +01002115 case 3:
2116 _debug("extract CB count");
2117 ret = afs_extract_data(call, true);
2118 if (ret < 0)
2119 return ret;
2120
2121 tmp = ntohl(call->tmp);
2122 _debug("CB count: %u", tmp);
2123 if (tmp != call->count2)
2124 return afs_protocol_error(call, -EBADMSG,
2125 afs_eproto_ibulkst_cb_count);
2126 call->count = 0;
2127 call->unmarshall++;
2128 more_cbs:
2129 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
2130
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06002131 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +01002132 case 4:
2133 _debug("extract CB array");
2134 ret = afs_extract_data(call, true);
2135 if (ret < 0)
2136 return ret;
2137
2138 _debug("unmarshall CB array");
2139 bp = call->buffer;
2140 callbacks = call->reply[2];
2141 xdr_decode_YFSCallBack_raw(&bp, &callbacks[call->count]);
2142 statuses = call->reply[1];
2143 if (call->count == 0 && vnode && statuses[0].abort_code == 0) {
2144 bp = call->buffer;
2145 xdr_decode_YFSCallBack(call, vnode, &bp);
2146 }
2147 call->count++;
2148 if (call->count < call->count2)
2149 goto more_cbs;
2150
2151 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
2152 call->unmarshall++;
2153
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06002154 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +01002155 case 5:
2156 ret = afs_extract_data(call, false);
2157 if (ret < 0)
2158 return ret;
2159
2160 bp = call->buffer;
2161 xdr_decode_YFSVolSync(&bp, call->reply[3]);
2162
2163 call->unmarshall++;
2164
Gustavo A. R. Silvae690c9e2019-01-10 15:52:25 -06002165 /* Fall through */
David Howells30062bd2018-10-20 00:57:58 +01002166 case 6:
2167 break;
2168 }
2169
2170 _leave(" = 0 [done]");
2171 return 0;
2172}
2173
2174/*
2175 * FS.InlineBulkStatus operation type
2176 */
2177static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
2178 .name = "YFS.InlineBulkStatus",
2179 .op = yfs_FS_InlineBulkStatus,
2180 .deliver = yfs_deliver_fs_inline_bulk_status,
2181 .destructor = afs_flat_call_destructor,
2182};
2183
2184/*
2185 * Fetch the status information for up to 1024 files
2186 */
2187int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2188 struct afs_net *net,
2189 struct afs_fid *fids,
2190 struct afs_file_status *statuses,
2191 struct afs_callback *callbacks,
2192 unsigned int nr_fids,
2193 struct afs_volsync *volsync)
2194{
2195 struct afs_call *call;
2196 __be32 *bp;
2197 int i;
2198
2199 _enter(",%x,{%llx:%llu},%u",
2200 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2201
2202 call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
2203 sizeof(__be32) +
2204 sizeof(__be32) +
2205 sizeof(__be32) +
2206 sizeof(struct yfs_xdr_YFSFid) * nr_fids,
2207 sizeof(struct yfs_xdr_YFSFetchStatus));
2208 if (!call) {
2209 fc->ac.error = -ENOMEM;
2210 return -ENOMEM;
2211 }
2212
2213 call->key = fc->key;
2214 call->reply[0] = NULL; /* vnode for fid[0] */
2215 call->reply[1] = statuses;
2216 call->reply[2] = callbacks;
2217 call->reply[3] = volsync;
2218 call->count2 = nr_fids;
2219
2220 /* marshall the parameters */
2221 bp = call->request;
2222 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
2223 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
2224 bp = xdr_encode_u32(bp, nr_fids);
2225 for (i = 0; i < nr_fids; i++)
2226 bp = xdr_encode_YFSFid(bp, &fids[i]);
2227 yfs_check_req(call, bp);
2228
2229 call->cb_break = fc->cb_break;
2230 afs_use_fs_server(call, fc->cbi);
2231 trace_afs_make_fs_call(call, &fids[0]);
David Howells20b83912019-05-08 16:16:31 +01002232 afs_set_fc_call(call, fc);
David Howells0b9bf382019-04-25 14:26:50 +01002233 afs_make_call(&fc->ac, call, GFP_NOFS);
2234 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01002235}
David Howellsae465782019-04-30 18:30:21 +01002236
2237/*
2238 * Deliver reply data to an YFS.FetchOpaqueACL.
2239 */
2240static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
2241{
2242 struct afs_volsync *volsync = call->reply[2];
2243 struct afs_vnode *vnode = call->reply[1];
2244 struct yfs_acl *yacl = call->reply[0];
2245 struct afs_acl *acl;
2246 const __be32 *bp;
2247 unsigned int size;
2248 int ret;
2249
2250 _enter("{%u}", call->unmarshall);
2251
2252 switch (call->unmarshall) {
2253 case 0:
2254 afs_extract_to_tmp(call);
2255 call->unmarshall++;
2256
2257 /* Extract the file ACL length */
2258 case 1:
2259 ret = afs_extract_data(call, true);
2260 if (ret < 0)
2261 return ret;
2262
2263 size = call->count2 = ntohl(call->tmp);
2264 size = round_up(size, 4);
2265
2266 if (yacl->flags & YFS_ACL_WANT_ACL) {
2267 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2268 if (!acl)
2269 return -ENOMEM;
2270 yacl->acl = acl;
2271 acl->size = call->count2;
2272 afs_extract_begin(call, acl->data, size);
2273 } else {
2274 iov_iter_discard(&call->iter, READ, size);
2275 }
2276 call->unmarshall++;
2277
2278 /* Extract the file ACL */
2279 case 2:
2280 ret = afs_extract_data(call, true);
2281 if (ret < 0)
2282 return ret;
2283
2284 afs_extract_to_tmp(call);
2285 call->unmarshall++;
2286
2287 /* Extract the volume ACL length */
2288 case 3:
2289 ret = afs_extract_data(call, true);
2290 if (ret < 0)
2291 return ret;
2292
2293 size = call->count2 = ntohl(call->tmp);
2294 size = round_up(size, 4);
2295
2296 if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2297 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2298 if (!acl)
2299 return -ENOMEM;
2300 yacl->vol_acl = acl;
2301 acl->size = call->count2;
2302 afs_extract_begin(call, acl->data, size);
2303 } else {
2304 iov_iter_discard(&call->iter, READ, size);
2305 }
2306 call->unmarshall++;
2307
2308 /* Extract the volume ACL */
2309 case 4:
2310 ret = afs_extract_data(call, true);
2311 if (ret < 0)
2312 return ret;
2313
2314 afs_extract_to_buf(call,
2315 sizeof(__be32) * 2 +
2316 sizeof(struct yfs_xdr_YFSFetchStatus) +
2317 sizeof(struct yfs_xdr_YFSVolSync));
2318 call->unmarshall++;
2319
2320 /* extract the metadata */
2321 case 5:
2322 ret = afs_extract_data(call, false);
2323 if (ret < 0)
2324 return ret;
2325
2326 bp = call->buffer;
2327 yacl->inherit_flag = ntohl(*bp++);
2328 yacl->num_cleaned = ntohl(*bp++);
2329 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
2330 &call->expected_version, NULL);
2331 if (ret < 0)
2332 return ret;
2333 xdr_decode_YFSVolSync(&bp, volsync);
2334
2335 call->unmarshall++;
2336
2337 case 6:
2338 break;
2339 }
2340
2341 _leave(" = 0 [done]");
2342 return 0;
2343}
2344
2345void yfs_free_opaque_acl(struct yfs_acl *yacl)
2346{
2347 if (yacl) {
2348 kfree(yacl->acl);
2349 kfree(yacl->vol_acl);
2350 kfree(yacl);
2351 }
2352}
2353
David Howellsae465782019-04-30 18:30:21 +01002354/*
2355 * YFS.FetchOpaqueACL operation type
2356 */
2357static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2358 .name = "YFS.FetchOpaqueACL",
2359 .op = yfs_FS_FetchOpaqueACL,
2360 .deliver = yfs_deliver_fs_fetch_opaque_acl,
David Howells773e0c42019-05-12 08:31:23 +01002361 .destructor = afs_flat_call_destructor,
David Howellsae465782019-04-30 18:30:21 +01002362};
2363
2364/*
2365 * Fetch the YFS advanced ACLs for a file.
2366 */
2367struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
David Howells773e0c42019-05-12 08:31:23 +01002368 struct yfs_acl *yacl)
David Howellsae465782019-04-30 18:30:21 +01002369{
2370 struct afs_vnode *vnode = fc->vnode;
2371 struct afs_call *call;
David Howellsae465782019-04-30 18:30:21 +01002372 struct afs_net *net = afs_v2net(vnode);
2373 __be32 *bp;
2374
2375 _enter(",%x,{%llx:%llu},,",
2376 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2377
2378 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,
2379 sizeof(__be32) * 2 +
2380 sizeof(struct yfs_xdr_YFSFid),
2381 sizeof(__be32) * 2 +
2382 sizeof(struct yfs_xdr_YFSFetchStatus) +
2383 sizeof(struct yfs_xdr_YFSVolSync));
David Howells773e0c42019-05-12 08:31:23 +01002384 if (!call) {
2385 fc->ac.error = -ENOMEM;
2386 return ERR_PTR(-ENOMEM);
2387 }
David Howellsae465782019-04-30 18:30:21 +01002388
David Howellsae465782019-04-30 18:30:21 +01002389 call->key = fc->key;
2390 call->reply[0] = yacl;
2391 call->reply[1] = vnode;
2392 call->reply[2] = NULL; /* volsync */
David Howellsae465782019-04-30 18:30:21 +01002393
2394 /* marshall the parameters */
2395 bp = call->request;
2396 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2397 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2398 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2399 yfs_check_req(call, bp);
2400
2401 call->cb_break = fc->cb_break;
2402 afs_use_fs_server(call, fc->cbi);
2403 trace_afs_make_fs_call(call, &vnode->fid);
2404 afs_make_call(&fc->ac, call, GFP_KERNEL);
2405 return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
David Howellsae465782019-04-30 18:30:21 +01002406}
David Howellsf5e45462019-05-01 14:05:27 +01002407
2408/*
2409 * YFS.StoreOpaqueACL2 operation type
2410 */
2411static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2412 .name = "YFS.StoreOpaqueACL2",
2413 .op = yfs_FS_StoreOpaqueACL2,
2414 .deliver = yfs_deliver_status_and_volsync,
2415 .destructor = afs_flat_call_destructor,
2416};
2417
2418/*
2419 * Fetch the YFS ACL for a file.
2420 */
2421int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl)
2422{
2423 struct afs_vnode *vnode = fc->vnode;
2424 struct afs_call *call;
2425 struct afs_net *net = afs_v2net(vnode);
2426 size_t size;
2427 __be32 *bp;
2428
2429 _enter(",%x,{%llx:%llu},,",
2430 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2431
2432 size = round_up(acl->size, 4);
2433 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
2434 sizeof(__be32) * 2 +
2435 sizeof(struct yfs_xdr_YFSFid) +
2436 sizeof(__be32) + size,
2437 sizeof(struct yfs_xdr_YFSFetchStatus) +
2438 sizeof(struct yfs_xdr_YFSVolSync));
2439 if (!call) {
2440 fc->ac.error = -ENOMEM;
2441 return -ENOMEM;
2442 }
2443
2444 call->key = fc->key;
2445 call->reply[0] = vnode;
2446 call->reply[2] = NULL; /* volsync */
2447
2448 /* marshall the parameters */
2449 bp = call->request;
2450 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2451 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2452 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2453 bp = xdr_encode_u32(bp, acl->size);
2454 memcpy(bp, acl->data, acl->size);
2455 if (acl->size != size)
2456 memset((void *)bp + acl->size, 0, size - acl->size);
2457 yfs_check_req(call, bp);
2458
2459 trace_afs_make_fs_call(call, &vnode->fid);
2460 afs_make_call(&fc->ac, call, GFP_KERNEL);
2461 return afs_wait_for_call_to_complete(call, &fc->ac);
David Howells30062bd2018-10-20 00:57:58 +01002462}