]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - fs/afs/yfsclient.c
afs: Remove the error argument from afs_protocol_error()
[mirror_ubuntu-jammy-kernel.git] / fs / afs / yfsclient.c
1 // 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
18 static const struct afs_fid afs_zero_fid;
19
20 static 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
27 static 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
38 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
39 {
40 *bp++ = htonl(n);
41 return bp;
42 }
43
44 static __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
52 static __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
63 static size_t xdr_strlen(unsigned int len)
64 {
65 return sizeof(__be32) + round_up(len, sizeof(__be32));
66 }
67
68 static __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
82 static 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
88 static __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
100 static __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 */
116 static 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
140 static 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
147 static 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_warn("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 */
162 static 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");
168 for (i = 0; i < 6 * 4 * 4; i += 16) {
169 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
175 memcpy(x, bp, 8);
176 pr_notice("0x60: %08x %08x\n", ntohl(x[0]), ntohl(x[1]));
177 }
178
179 /*
180 * Decode a YFSFetchStatus block
181 */
182 static void xdr_decode_YFSFetchStatus(const __be32 **_bp,
183 struct afs_call *call,
184 struct afs_status_cb *scb)
185 {
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;
195 goto advance;
196 }
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;
223 advance:
224 *_bp += xdr_size(xdr);
225 return;
226
227 bad:
228 xdr_dump_bad(*_bp);
229 afs_protocol_error(call, afs_eproto_bad_status);
230 goto advance;
231 }
232
233 /*
234 * Decode a YFSCallBack block
235 */
236 static 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 */
254 static 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 */
272 static __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 */
310 static 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 */
337 static 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;
348 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
349 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 */
360 static 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;
370 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
371 xdr_decode_YFSVolSync(&bp, call->out_volsync);
372
373 _leave(" = 0 [done]");
374 return 0;
375 }
376
377 /*
378 * YFS.FetchStatus operation type
379 */
380 static 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 */
390 int 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 */
433 static 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->def_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;
493 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;
530 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
531 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);
548 req->offset = 0;
549 }
550
551 if (req->page_done)
552 for (req->index = 0; req->index < req->nr_pages; req->index++)
553 req->page_done(req);
554
555 _leave(" = 0 [done]");
556 return 0;
557 }
558
559 static 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 */
568 static 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 */
578 int 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 = afs_get_read(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 afs_use_fs_server(call, fc->cbi);
615 trace_afs_make_fs_call(call, &vnode->fid);
616 afs_set_fc_call(call, fc);
617 afs_make_call(&fc->ac, call, GFP_NOFS);
618 return afs_wait_for_call_to_complete(call, &fc->ac);
619 }
620
621 /*
622 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
623 */
624 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
625 {
626 const __be32 *bp;
627 int ret;
628
629 _enter("{%u}", call->unmarshall);
630
631 ret = afs_transfer_reply(call);
632 if (ret < 0)
633 return ret;
634
635 /* unmarshall the reply once we've received all of it */
636 bp = call->buffer;
637 xdr_decode_YFSFid(&bp, call->out_fid);
638 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
639 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
640 xdr_decode_YFSCallBack(&bp, call, call->out_scb);
641 xdr_decode_YFSVolSync(&bp, call->out_volsync);
642
643 _leave(" = 0 [done]");
644 return 0;
645 }
646
647 /*
648 * FS.CreateFile and FS.MakeDir operation type
649 */
650 static const struct afs_call_type afs_RXFSCreateFile = {
651 .name = "YFS.CreateFile",
652 .op = yfs_FS_CreateFile,
653 .deliver = yfs_deliver_fs_create_vnode,
654 .destructor = afs_flat_call_destructor,
655 };
656
657 /*
658 * Create a file.
659 */
660 int yfs_fs_create_file(struct afs_fs_cursor *fc,
661 const char *name,
662 umode_t mode,
663 struct afs_status_cb *dvnode_scb,
664 struct afs_fid *newfid,
665 struct afs_status_cb *new_scb)
666 {
667 struct afs_vnode *dvnode = fc->vnode;
668 struct afs_call *call;
669 struct afs_net *net = afs_v2net(dvnode);
670 size_t namesz, reqsz, rplsz;
671 __be32 *bp;
672
673 _enter("");
674
675 namesz = strlen(name);
676 reqsz = (sizeof(__be32) +
677 sizeof(__be32) +
678 sizeof(struct yfs_xdr_YFSFid) +
679 xdr_strlen(namesz) +
680 sizeof(struct yfs_xdr_YFSStoreStatus) +
681 sizeof(__be32));
682 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
683 sizeof(struct yfs_xdr_YFSFetchStatus) +
684 sizeof(struct yfs_xdr_YFSFetchStatus) +
685 sizeof(struct yfs_xdr_YFSCallBack) +
686 sizeof(struct yfs_xdr_YFSVolSync));
687
688 call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
689 if (!call)
690 return -ENOMEM;
691
692 call->key = fc->key;
693 call->out_dir_scb = dvnode_scb;
694 call->out_fid = newfid;
695 call->out_scb = new_scb;
696
697 /* marshall the parameters */
698 bp = call->request;
699 bp = xdr_encode_u32(bp, YFSCREATEFILE);
700 bp = xdr_encode_u32(bp, 0); /* RPC flags */
701 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
702 bp = xdr_encode_string(bp, name, namesz);
703 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
704 bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
705 yfs_check_req(call, bp);
706
707 afs_use_fs_server(call, fc->cbi);
708 trace_afs_make_fs_call1(call, &dvnode->fid, name);
709 afs_set_fc_call(call, fc);
710 afs_make_call(&fc->ac, call, GFP_NOFS);
711 return afs_wait_for_call_to_complete(call, &fc->ac);
712 }
713
714 static const struct afs_call_type yfs_RXFSMakeDir = {
715 .name = "YFS.MakeDir",
716 .op = yfs_FS_MakeDir,
717 .deliver = yfs_deliver_fs_create_vnode,
718 .destructor = afs_flat_call_destructor,
719 };
720
721 /*
722 * Make a directory.
723 */
724 int yfs_fs_make_dir(struct afs_fs_cursor *fc,
725 const char *name,
726 umode_t mode,
727 struct afs_status_cb *dvnode_scb,
728 struct afs_fid *newfid,
729 struct afs_status_cb *new_scb)
730 {
731 struct afs_vnode *dvnode = fc->vnode;
732 struct afs_call *call;
733 struct afs_net *net = afs_v2net(dvnode);
734 size_t namesz, reqsz, rplsz;
735 __be32 *bp;
736
737 _enter("");
738
739 namesz = strlen(name);
740 reqsz = (sizeof(__be32) +
741 sizeof(struct yfs_xdr_RPCFlags) +
742 sizeof(struct yfs_xdr_YFSFid) +
743 xdr_strlen(namesz) +
744 sizeof(struct yfs_xdr_YFSStoreStatus));
745 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
746 sizeof(struct yfs_xdr_YFSFetchStatus) +
747 sizeof(struct yfs_xdr_YFSFetchStatus) +
748 sizeof(struct yfs_xdr_YFSCallBack) +
749 sizeof(struct yfs_xdr_YFSVolSync));
750
751 call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
752 if (!call)
753 return -ENOMEM;
754
755 call->key = fc->key;
756 call->out_dir_scb = dvnode_scb;
757 call->out_fid = newfid;
758 call->out_scb = new_scb;
759
760 /* marshall the parameters */
761 bp = call->request;
762 bp = xdr_encode_u32(bp, YFSMAKEDIR);
763 bp = xdr_encode_u32(bp, 0); /* RPC flags */
764 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
765 bp = xdr_encode_string(bp, name, namesz);
766 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
767 yfs_check_req(call, bp);
768
769 afs_use_fs_server(call, fc->cbi);
770 trace_afs_make_fs_call1(call, &dvnode->fid, name);
771 afs_set_fc_call(call, fc);
772 afs_make_call(&fc->ac, call, GFP_NOFS);
773 return afs_wait_for_call_to_complete(call, &fc->ac);
774 }
775
776 /*
777 * Deliver reply data to a YFS.RemoveFile2 operation.
778 */
779 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
780 {
781 struct afs_fid fid;
782 const __be32 *bp;
783 int ret;
784
785 _enter("{%u}", call->unmarshall);
786
787 ret = afs_transfer_reply(call);
788 if (ret < 0)
789 return ret;
790
791 bp = call->buffer;
792 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
793 xdr_decode_YFSFid(&bp, &fid);
794 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
795 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
796
797 xdr_decode_YFSVolSync(&bp, call->out_volsync);
798 return 0;
799 }
800
801 /*
802 * YFS.RemoveFile2 operation type.
803 */
804 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
805 .name = "YFS.RemoveFile2",
806 .op = yfs_FS_RemoveFile2,
807 .deliver = yfs_deliver_fs_remove_file2,
808 .destructor = afs_flat_call_destructor,
809 };
810
811 /*
812 * Remove a file and retrieve new file status.
813 */
814 int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
815 const char *name, struct afs_status_cb *dvnode_scb,
816 struct afs_status_cb *vnode_scb)
817 {
818 struct afs_vnode *dvnode = fc->vnode;
819 struct afs_call *call;
820 struct afs_net *net = afs_v2net(dvnode);
821 size_t namesz;
822 __be32 *bp;
823
824 _enter("");
825
826 namesz = strlen(name);
827
828 call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
829 sizeof(__be32) +
830 sizeof(struct yfs_xdr_RPCFlags) +
831 sizeof(struct yfs_xdr_YFSFid) +
832 xdr_strlen(namesz),
833 sizeof(struct yfs_xdr_YFSFetchStatus) +
834 sizeof(struct yfs_xdr_YFSFid) +
835 sizeof(struct yfs_xdr_YFSFetchStatus) +
836 sizeof(struct yfs_xdr_YFSVolSync));
837 if (!call)
838 return -ENOMEM;
839
840 call->key = fc->key;
841 call->out_dir_scb = dvnode_scb;
842 call->out_scb = vnode_scb;
843
844 /* marshall the parameters */
845 bp = call->request;
846 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
847 bp = xdr_encode_u32(bp, 0); /* RPC flags */
848 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
849 bp = xdr_encode_string(bp, name, namesz);
850 yfs_check_req(call, bp);
851
852 afs_use_fs_server(call, fc->cbi);
853 trace_afs_make_fs_call1(call, &dvnode->fid, name);
854 afs_set_fc_call(call, fc);
855 afs_make_call(&fc->ac, call, GFP_NOFS);
856 return afs_wait_for_call_to_complete(call, &fc->ac);
857 }
858
859 /*
860 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
861 */
862 static int yfs_deliver_fs_remove(struct afs_call *call)
863 {
864 const __be32 *bp;
865 int ret;
866
867 _enter("{%u}", call->unmarshall);
868
869 ret = afs_transfer_reply(call);
870 if (ret < 0)
871 return ret;
872
873 bp = call->buffer;
874 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
875 xdr_decode_YFSVolSync(&bp, call->out_volsync);
876 return 0;
877 }
878
879 /*
880 * FS.RemoveDir and FS.RemoveFile operation types.
881 */
882 static const struct afs_call_type yfs_RXYFSRemoveFile = {
883 .name = "YFS.RemoveFile",
884 .op = yfs_FS_RemoveFile,
885 .deliver = yfs_deliver_fs_remove,
886 .destructor = afs_flat_call_destructor,
887 };
888
889 static const struct afs_call_type yfs_RXYFSRemoveDir = {
890 .name = "YFS.RemoveDir",
891 .op = yfs_FS_RemoveDir,
892 .deliver = yfs_deliver_fs_remove,
893 .destructor = afs_flat_call_destructor,
894 };
895
896 /*
897 * remove a file or directory
898 */
899 int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
900 const char *name, bool isdir,
901 struct afs_status_cb *dvnode_scb)
902 {
903 struct afs_vnode *dvnode = fc->vnode;
904 struct afs_call *call;
905 struct afs_net *net = afs_v2net(dvnode);
906 size_t namesz;
907 __be32 *bp;
908
909 _enter("");
910
911 namesz = strlen(name);
912 call = afs_alloc_flat_call(
913 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
914 sizeof(__be32) +
915 sizeof(struct yfs_xdr_RPCFlags) +
916 sizeof(struct yfs_xdr_YFSFid) +
917 xdr_strlen(namesz),
918 sizeof(struct yfs_xdr_YFSFetchStatus) +
919 sizeof(struct yfs_xdr_YFSVolSync));
920 if (!call)
921 return -ENOMEM;
922
923 call->key = fc->key;
924 call->out_dir_scb = dvnode_scb;
925
926 /* marshall the parameters */
927 bp = call->request;
928 bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
929 bp = xdr_encode_u32(bp, 0); /* RPC flags */
930 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
931 bp = xdr_encode_string(bp, name, namesz);
932 yfs_check_req(call, bp);
933
934 afs_use_fs_server(call, fc->cbi);
935 trace_afs_make_fs_call1(call, &dvnode->fid, name);
936 afs_set_fc_call(call, fc);
937 afs_make_call(&fc->ac, call, GFP_NOFS);
938 return afs_wait_for_call_to_complete(call, &fc->ac);
939 }
940
941 /*
942 * Deliver reply data to a YFS.Link operation.
943 */
944 static int yfs_deliver_fs_link(struct afs_call *call)
945 {
946 const __be32 *bp;
947 int ret;
948
949 _enter("{%u}", call->unmarshall);
950
951 ret = afs_transfer_reply(call);
952 if (ret < 0)
953 return ret;
954
955 bp = call->buffer;
956 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
957 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
958 xdr_decode_YFSVolSync(&bp, call->out_volsync);
959 _leave(" = 0 [done]");
960 return 0;
961 }
962
963 /*
964 * YFS.Link operation type.
965 */
966 static const struct afs_call_type yfs_RXYFSLink = {
967 .name = "YFS.Link",
968 .op = yfs_FS_Link,
969 .deliver = yfs_deliver_fs_link,
970 .destructor = afs_flat_call_destructor,
971 };
972
973 /*
974 * Make a hard link.
975 */
976 int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
977 const char *name,
978 struct afs_status_cb *dvnode_scb,
979 struct afs_status_cb *vnode_scb)
980 {
981 struct afs_vnode *dvnode = fc->vnode;
982 struct afs_call *call;
983 struct afs_net *net = afs_v2net(vnode);
984 size_t namesz;
985 __be32 *bp;
986
987 _enter("");
988
989 namesz = strlen(name);
990 call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
991 sizeof(__be32) +
992 sizeof(struct yfs_xdr_RPCFlags) +
993 sizeof(struct yfs_xdr_YFSFid) +
994 xdr_strlen(namesz) +
995 sizeof(struct yfs_xdr_YFSFid),
996 sizeof(struct yfs_xdr_YFSFetchStatus) +
997 sizeof(struct yfs_xdr_YFSFetchStatus) +
998 sizeof(struct yfs_xdr_YFSVolSync));
999 if (!call)
1000 return -ENOMEM;
1001
1002 call->key = fc->key;
1003 call->out_dir_scb = dvnode_scb;
1004 call->out_scb = vnode_scb;
1005
1006 /* marshall the parameters */
1007 bp = call->request;
1008 bp = xdr_encode_u32(bp, YFSLINK);
1009 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1010 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1011 bp = xdr_encode_string(bp, name, namesz);
1012 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1013 yfs_check_req(call, bp);
1014
1015 afs_use_fs_server(call, fc->cbi);
1016 trace_afs_make_fs_call1(call, &vnode->fid, name);
1017 afs_set_fc_call(call, fc);
1018 afs_make_call(&fc->ac, call, GFP_NOFS);
1019 return afs_wait_for_call_to_complete(call, &fc->ac);
1020 }
1021
1022 /*
1023 * Deliver reply data to a YFS.Symlink operation.
1024 */
1025 static int yfs_deliver_fs_symlink(struct afs_call *call)
1026 {
1027 const __be32 *bp;
1028 int ret;
1029
1030 _enter("{%u}", call->unmarshall);
1031
1032 ret = afs_transfer_reply(call);
1033 if (ret < 0)
1034 return ret;
1035
1036 /* unmarshall the reply once we've received all of it */
1037 bp = call->buffer;
1038 xdr_decode_YFSFid(&bp, call->out_fid);
1039 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1040 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1041 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1042
1043 _leave(" = 0 [done]");
1044 return 0;
1045 }
1046
1047 /*
1048 * YFS.Symlink operation type
1049 */
1050 static const struct afs_call_type yfs_RXYFSSymlink = {
1051 .name = "YFS.Symlink",
1052 .op = yfs_FS_Symlink,
1053 .deliver = yfs_deliver_fs_symlink,
1054 .destructor = afs_flat_call_destructor,
1055 };
1056
1057 /*
1058 * Create a symbolic link.
1059 */
1060 int yfs_fs_symlink(struct afs_fs_cursor *fc,
1061 const char *name,
1062 const char *contents,
1063 struct afs_status_cb *dvnode_scb,
1064 struct afs_fid *newfid,
1065 struct afs_status_cb *vnode_scb)
1066 {
1067 struct afs_vnode *dvnode = fc->vnode;
1068 struct afs_call *call;
1069 struct afs_net *net = afs_v2net(dvnode);
1070 size_t namesz, contents_sz;
1071 __be32 *bp;
1072
1073 _enter("");
1074
1075 namesz = strlen(name);
1076 contents_sz = strlen(contents);
1077 call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1078 sizeof(__be32) +
1079 sizeof(struct yfs_xdr_RPCFlags) +
1080 sizeof(struct yfs_xdr_YFSFid) +
1081 xdr_strlen(namesz) +
1082 xdr_strlen(contents_sz) +
1083 sizeof(struct yfs_xdr_YFSStoreStatus),
1084 sizeof(struct yfs_xdr_YFSFid) +
1085 sizeof(struct yfs_xdr_YFSFetchStatus) +
1086 sizeof(struct yfs_xdr_YFSFetchStatus) +
1087 sizeof(struct yfs_xdr_YFSVolSync));
1088 if (!call)
1089 return -ENOMEM;
1090
1091 call->key = fc->key;
1092 call->out_dir_scb = dvnode_scb;
1093 call->out_fid = newfid;
1094 call->out_scb = vnode_scb;
1095
1096 /* marshall the parameters */
1097 bp = call->request;
1098 bp = xdr_encode_u32(bp, YFSSYMLINK);
1099 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1100 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1101 bp = xdr_encode_string(bp, name, namesz);
1102 bp = xdr_encode_string(bp, contents, contents_sz);
1103 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1104 yfs_check_req(call, bp);
1105
1106 afs_use_fs_server(call, fc->cbi);
1107 trace_afs_make_fs_call1(call, &dvnode->fid, name);
1108 afs_set_fc_call(call, fc);
1109 afs_make_call(&fc->ac, call, GFP_NOFS);
1110 return afs_wait_for_call_to_complete(call, &fc->ac);
1111 }
1112
1113 /*
1114 * Deliver reply data to a YFS.Rename operation.
1115 */
1116 static int yfs_deliver_fs_rename(struct afs_call *call)
1117 {
1118 const __be32 *bp;
1119 int ret;
1120
1121 _enter("{%u}", call->unmarshall);
1122
1123 ret = afs_transfer_reply(call);
1124 if (ret < 0)
1125 return ret;
1126
1127 bp = call->buffer;
1128 /* If the two dirs are the same, we have two copies of the same status
1129 * report, so we just decode it twice.
1130 */
1131 xdr_decode_YFSFetchStatus(&bp, call, call->out_dir_scb);
1132 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
1133 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1134 _leave(" = 0 [done]");
1135 return 0;
1136 }
1137
1138 /*
1139 * YFS.Rename operation type
1140 */
1141 static const struct afs_call_type yfs_RXYFSRename = {
1142 .name = "FS.Rename",
1143 .op = yfs_FS_Rename,
1144 .deliver = yfs_deliver_fs_rename,
1145 .destructor = afs_flat_call_destructor,
1146 };
1147
1148 /*
1149 * Rename a file or directory.
1150 */
1151 int yfs_fs_rename(struct afs_fs_cursor *fc,
1152 const char *orig_name,
1153 struct afs_vnode *new_dvnode,
1154 const char *new_name,
1155 struct afs_status_cb *orig_dvnode_scb,
1156 struct afs_status_cb *new_dvnode_scb)
1157 {
1158 struct afs_vnode *orig_dvnode = fc->vnode;
1159 struct afs_call *call;
1160 struct afs_net *net = afs_v2net(orig_dvnode);
1161 size_t o_namesz, n_namesz;
1162 __be32 *bp;
1163
1164 _enter("");
1165
1166 o_namesz = strlen(orig_name);
1167 n_namesz = strlen(new_name);
1168 call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1169 sizeof(__be32) +
1170 sizeof(struct yfs_xdr_RPCFlags) +
1171 sizeof(struct yfs_xdr_YFSFid) +
1172 xdr_strlen(o_namesz) +
1173 sizeof(struct yfs_xdr_YFSFid) +
1174 xdr_strlen(n_namesz),
1175 sizeof(struct yfs_xdr_YFSFetchStatus) +
1176 sizeof(struct yfs_xdr_YFSFetchStatus) +
1177 sizeof(struct yfs_xdr_YFSVolSync));
1178 if (!call)
1179 return -ENOMEM;
1180
1181 call->key = fc->key;
1182 call->out_dir_scb = orig_dvnode_scb;
1183 call->out_scb = new_dvnode_scb;
1184
1185 /* marshall the parameters */
1186 bp = call->request;
1187 bp = xdr_encode_u32(bp, YFSRENAME);
1188 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1189 bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1190 bp = xdr_encode_string(bp, orig_name, o_namesz);
1191 bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1192 bp = xdr_encode_string(bp, new_name, n_namesz);
1193 yfs_check_req(call, bp);
1194
1195 afs_use_fs_server(call, fc->cbi);
1196 trace_afs_make_fs_call2(call, &orig_dvnode->fid, orig_name, new_name);
1197 afs_set_fc_call(call, fc);
1198 afs_make_call(&fc->ac, call, GFP_NOFS);
1199 return afs_wait_for_call_to_complete(call, &fc->ac);
1200 }
1201
1202 /*
1203 * YFS.StoreData64 operation type.
1204 */
1205 static const struct afs_call_type yfs_RXYFSStoreData64 = {
1206 .name = "YFS.StoreData64",
1207 .op = yfs_FS_StoreData64,
1208 .deliver = yfs_deliver_status_and_volsync,
1209 .destructor = afs_flat_call_destructor,
1210 };
1211
1212 /*
1213 * Store a set of pages to a large file.
1214 */
1215 int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1216 pgoff_t first, pgoff_t last,
1217 unsigned offset, unsigned to,
1218 struct afs_status_cb *scb)
1219 {
1220 struct afs_vnode *vnode = fc->vnode;
1221 struct afs_call *call;
1222 struct afs_net *net = afs_v2net(vnode);
1223 loff_t size, pos, i_size;
1224 __be32 *bp;
1225
1226 _enter(",%x,{%llx:%llu},,",
1227 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1228
1229 size = (loff_t)to - (loff_t)offset;
1230 if (first != last)
1231 size += (loff_t)(last - first) << PAGE_SHIFT;
1232 pos = (loff_t)first << PAGE_SHIFT;
1233 pos += offset;
1234
1235 i_size = i_size_read(&vnode->vfs_inode);
1236 if (pos + size > i_size)
1237 i_size = size + pos;
1238
1239 _debug("size %llx, at %llx, i_size %llx",
1240 (unsigned long long)size, (unsigned long long)pos,
1241 (unsigned long long)i_size);
1242
1243 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1244 sizeof(__be32) +
1245 sizeof(__be32) +
1246 sizeof(struct yfs_xdr_YFSFid) +
1247 sizeof(struct yfs_xdr_YFSStoreStatus) +
1248 sizeof(struct yfs_xdr_u64) * 3,
1249 sizeof(struct yfs_xdr_YFSFetchStatus) +
1250 sizeof(struct yfs_xdr_YFSVolSync));
1251 if (!call)
1252 return -ENOMEM;
1253
1254 call->key = fc->key;
1255 call->mapping = mapping;
1256 call->first = first;
1257 call->last = last;
1258 call->first_offset = offset;
1259 call->last_to = to;
1260 call->send_pages = true;
1261 call->out_scb = scb;
1262
1263 /* marshall the parameters */
1264 bp = call->request;
1265 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1266 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1267 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1268 bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1269 bp = xdr_encode_u64(bp, pos);
1270 bp = xdr_encode_u64(bp, size);
1271 bp = xdr_encode_u64(bp, i_size);
1272 yfs_check_req(call, bp);
1273
1274 afs_use_fs_server(call, fc->cbi);
1275 trace_afs_make_fs_call(call, &vnode->fid);
1276 afs_set_fc_call(call, fc);
1277 afs_make_call(&fc->ac, call, GFP_NOFS);
1278 return afs_wait_for_call_to_complete(call, &fc->ac);
1279 }
1280
1281 /*
1282 * YFS.StoreStatus operation type
1283 */
1284 static const struct afs_call_type yfs_RXYFSStoreStatus = {
1285 .name = "YFS.StoreStatus",
1286 .op = yfs_FS_StoreStatus,
1287 .deliver = yfs_deliver_status_and_volsync,
1288 .destructor = afs_flat_call_destructor,
1289 };
1290
1291 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1292 .name = "YFS.StoreData64",
1293 .op = yfs_FS_StoreData64,
1294 .deliver = yfs_deliver_status_and_volsync,
1295 .destructor = afs_flat_call_destructor,
1296 };
1297
1298 /*
1299 * Set the attributes on a file, using YFS.StoreData64 rather than
1300 * YFS.StoreStatus so as to alter the file size also.
1301 */
1302 static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr,
1303 struct afs_status_cb *scb)
1304 {
1305 struct afs_vnode *vnode = fc->vnode;
1306 struct afs_call *call;
1307 struct afs_net *net = afs_v2net(vnode);
1308 __be32 *bp;
1309
1310 _enter(",%x,{%llx:%llu},,",
1311 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1312
1313 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1314 sizeof(__be32) * 2 +
1315 sizeof(struct yfs_xdr_YFSFid) +
1316 sizeof(struct yfs_xdr_YFSStoreStatus) +
1317 sizeof(struct yfs_xdr_u64) * 3,
1318 sizeof(struct yfs_xdr_YFSFetchStatus) +
1319 sizeof(struct yfs_xdr_YFSVolSync));
1320 if (!call)
1321 return -ENOMEM;
1322
1323 call->key = fc->key;
1324 call->out_scb = scb;
1325
1326 /* marshall the parameters */
1327 bp = call->request;
1328 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1329 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1330 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1331 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1332 bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1333 bp = xdr_encode_u64(bp, 0); /* size of write */
1334 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1335 yfs_check_req(call, bp);
1336
1337 afs_use_fs_server(call, fc->cbi);
1338 trace_afs_make_fs_call(call, &vnode->fid);
1339 afs_set_fc_call(call, fc);
1340 afs_make_call(&fc->ac, call, GFP_NOFS);
1341 return afs_wait_for_call_to_complete(call, &fc->ac);
1342 }
1343
1344 /*
1345 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1346 * file size, and YFS.StoreStatus otherwise.
1347 */
1348 int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr,
1349 struct afs_status_cb *scb)
1350 {
1351 struct afs_vnode *vnode = fc->vnode;
1352 struct afs_call *call;
1353 struct afs_net *net = afs_v2net(vnode);
1354 __be32 *bp;
1355
1356 if (attr->ia_valid & ATTR_SIZE)
1357 return yfs_fs_setattr_size(fc, attr, scb);
1358
1359 _enter(",%x,{%llx:%llu},,",
1360 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1361
1362 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1363 sizeof(__be32) * 2 +
1364 sizeof(struct yfs_xdr_YFSFid) +
1365 sizeof(struct yfs_xdr_YFSStoreStatus),
1366 sizeof(struct yfs_xdr_YFSFetchStatus) +
1367 sizeof(struct yfs_xdr_YFSVolSync));
1368 if (!call)
1369 return -ENOMEM;
1370
1371 call->key = fc->key;
1372 call->out_scb = scb;
1373
1374 /* marshall the parameters */
1375 bp = call->request;
1376 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1377 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1378 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1379 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1380 yfs_check_req(call, bp);
1381
1382 afs_use_fs_server(call, fc->cbi);
1383 trace_afs_make_fs_call(call, &vnode->fid);
1384 afs_set_fc_call(call, fc);
1385 afs_make_call(&fc->ac, call, GFP_NOFS);
1386 return afs_wait_for_call_to_complete(call, &fc->ac);
1387 }
1388
1389 /*
1390 * Deliver reply data to a YFS.GetVolumeStatus operation.
1391 */
1392 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1393 {
1394 const __be32 *bp;
1395 char *p;
1396 u32 size;
1397 int ret;
1398
1399 _enter("{%u}", call->unmarshall);
1400
1401 switch (call->unmarshall) {
1402 case 0:
1403 call->unmarshall++;
1404 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1405 /* Fall through */
1406
1407 /* extract the returned status record */
1408 case 1:
1409 _debug("extract status");
1410 ret = afs_extract_data(call, true);
1411 if (ret < 0)
1412 return ret;
1413
1414 bp = call->buffer;
1415 xdr_decode_YFSFetchVolumeStatus(&bp, call->out_volstatus);
1416 call->unmarshall++;
1417 afs_extract_to_tmp(call);
1418 /* Fall through */
1419
1420 /* extract the volume name length */
1421 case 2:
1422 ret = afs_extract_data(call, true);
1423 if (ret < 0)
1424 return ret;
1425
1426 call->count = ntohl(call->tmp);
1427 _debug("volname length: %u", call->count);
1428 if (call->count >= AFSNAMEMAX)
1429 return afs_protocol_error(call, afs_eproto_volname_len);
1430 size = (call->count + 3) & ~3; /* It's padded */
1431 afs_extract_to_buf(call, size);
1432 call->unmarshall++;
1433 /* Fall through */
1434
1435 /* extract the volume name */
1436 case 3:
1437 _debug("extract volname");
1438 ret = afs_extract_data(call, true);
1439 if (ret < 0)
1440 return ret;
1441
1442 p = call->buffer;
1443 p[call->count] = 0;
1444 _debug("volname '%s'", p);
1445 afs_extract_to_tmp(call);
1446 call->unmarshall++;
1447 /* Fall through */
1448
1449 /* extract the offline message length */
1450 case 4:
1451 ret = afs_extract_data(call, true);
1452 if (ret < 0)
1453 return ret;
1454
1455 call->count = ntohl(call->tmp);
1456 _debug("offline msg length: %u", call->count);
1457 if (call->count >= AFSNAMEMAX)
1458 return afs_protocol_error(call, afs_eproto_offline_msg_len);
1459 size = (call->count + 3) & ~3; /* It's padded */
1460 afs_extract_to_buf(call, size);
1461 call->unmarshall++;
1462 /* Fall through */
1463
1464 /* extract the offline message */
1465 case 5:
1466 _debug("extract offline");
1467 ret = afs_extract_data(call, true);
1468 if (ret < 0)
1469 return ret;
1470
1471 p = call->buffer;
1472 p[call->count] = 0;
1473 _debug("offline '%s'", p);
1474
1475 afs_extract_to_tmp(call);
1476 call->unmarshall++;
1477 /* Fall through */
1478
1479 /* extract the message of the day length */
1480 case 6:
1481 ret = afs_extract_data(call, true);
1482 if (ret < 0)
1483 return ret;
1484
1485 call->count = ntohl(call->tmp);
1486 _debug("motd length: %u", call->count);
1487 if (call->count >= AFSNAMEMAX)
1488 return afs_protocol_error(call, afs_eproto_motd_len);
1489 size = (call->count + 3) & ~3; /* It's padded */
1490 afs_extract_to_buf(call, size);
1491 call->unmarshall++;
1492 /* Fall through */
1493
1494 /* extract the message of the day */
1495 case 7:
1496 _debug("extract motd");
1497 ret = afs_extract_data(call, false);
1498 if (ret < 0)
1499 return ret;
1500
1501 p = call->buffer;
1502 p[call->count] = 0;
1503 _debug("motd '%s'", p);
1504
1505 call->unmarshall++;
1506 /* Fall through */
1507
1508 case 8:
1509 break;
1510 }
1511
1512 _leave(" = 0 [done]");
1513 return 0;
1514 }
1515
1516 /*
1517 * YFS.GetVolumeStatus operation type
1518 */
1519 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1520 .name = "YFS.GetVolumeStatus",
1521 .op = yfs_FS_GetVolumeStatus,
1522 .deliver = yfs_deliver_fs_get_volume_status,
1523 .destructor = afs_flat_call_destructor,
1524 };
1525
1526 /*
1527 * fetch the status of a volume
1528 */
1529 int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1530 struct afs_volume_status *vs)
1531 {
1532 struct afs_vnode *vnode = fc->vnode;
1533 struct afs_call *call;
1534 struct afs_net *net = afs_v2net(vnode);
1535 __be32 *bp;
1536
1537 _enter("");
1538
1539 call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1540 sizeof(__be32) * 2 +
1541 sizeof(struct yfs_xdr_u64),
1542 max_t(size_t,
1543 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1544 sizeof(__be32),
1545 AFSOPAQUEMAX + 1));
1546 if (!call)
1547 return -ENOMEM;
1548
1549 call->key = fc->key;
1550 call->out_volstatus = vs;
1551
1552 /* marshall the parameters */
1553 bp = call->request;
1554 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1555 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1556 bp = xdr_encode_u64(bp, vnode->fid.vid);
1557 yfs_check_req(call, bp);
1558
1559 afs_use_fs_server(call, fc->cbi);
1560 trace_afs_make_fs_call(call, &vnode->fid);
1561 afs_set_fc_call(call, fc);
1562 afs_make_call(&fc->ac, call, GFP_NOFS);
1563 return afs_wait_for_call_to_complete(call, &fc->ac);
1564 }
1565
1566 /*
1567 * YFS.SetLock operation type
1568 */
1569 static const struct afs_call_type yfs_RXYFSSetLock = {
1570 .name = "YFS.SetLock",
1571 .op = yfs_FS_SetLock,
1572 .deliver = yfs_deliver_status_and_volsync,
1573 .done = afs_lock_op_done,
1574 .destructor = afs_flat_call_destructor,
1575 };
1576
1577 /*
1578 * YFS.ExtendLock operation type
1579 */
1580 static const struct afs_call_type yfs_RXYFSExtendLock = {
1581 .name = "YFS.ExtendLock",
1582 .op = yfs_FS_ExtendLock,
1583 .deliver = yfs_deliver_status_and_volsync,
1584 .done = afs_lock_op_done,
1585 .destructor = afs_flat_call_destructor,
1586 };
1587
1588 /*
1589 * YFS.ReleaseLock operation type
1590 */
1591 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1592 .name = "YFS.ReleaseLock",
1593 .op = yfs_FS_ReleaseLock,
1594 .deliver = yfs_deliver_status_and_volsync,
1595 .destructor = afs_flat_call_destructor,
1596 };
1597
1598 /*
1599 * Set a lock on a file
1600 */
1601 int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type,
1602 struct afs_status_cb *scb)
1603 {
1604 struct afs_vnode *vnode = fc->vnode;
1605 struct afs_call *call;
1606 struct afs_net *net = afs_v2net(vnode);
1607 __be32 *bp;
1608
1609 _enter("");
1610
1611 call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1612 sizeof(__be32) * 2 +
1613 sizeof(struct yfs_xdr_YFSFid) +
1614 sizeof(__be32),
1615 sizeof(struct yfs_xdr_YFSFetchStatus) +
1616 sizeof(struct yfs_xdr_YFSVolSync));
1617 if (!call)
1618 return -ENOMEM;
1619
1620 call->key = fc->key;
1621 call->lvnode = vnode;
1622 call->out_scb = scb;
1623
1624 /* marshall the parameters */
1625 bp = call->request;
1626 bp = xdr_encode_u32(bp, YFSSETLOCK);
1627 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1628 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1629 bp = xdr_encode_u32(bp, type);
1630 yfs_check_req(call, bp);
1631
1632 afs_use_fs_server(call, fc->cbi);
1633 trace_afs_make_fs_calli(call, &vnode->fid, type);
1634 afs_set_fc_call(call, fc);
1635 afs_make_call(&fc->ac, call, GFP_NOFS);
1636 return afs_wait_for_call_to_complete(call, &fc->ac);
1637 }
1638
1639 /*
1640 * extend a lock on a file
1641 */
1642 int yfs_fs_extend_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1643 {
1644 struct afs_vnode *vnode = fc->vnode;
1645 struct afs_call *call;
1646 struct afs_net *net = afs_v2net(vnode);
1647 __be32 *bp;
1648
1649 _enter("");
1650
1651 call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1652 sizeof(__be32) * 2 +
1653 sizeof(struct yfs_xdr_YFSFid),
1654 sizeof(struct yfs_xdr_YFSFetchStatus) +
1655 sizeof(struct yfs_xdr_YFSVolSync));
1656 if (!call)
1657 return -ENOMEM;
1658
1659 call->key = fc->key;
1660 call->lvnode = vnode;
1661 call->out_scb = scb;
1662
1663 /* marshall the parameters */
1664 bp = call->request;
1665 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1666 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1667 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1668 yfs_check_req(call, bp);
1669
1670 afs_use_fs_server(call, fc->cbi);
1671 trace_afs_make_fs_call(call, &vnode->fid);
1672 afs_set_fc_call(call, fc);
1673 afs_make_call(&fc->ac, call, GFP_NOFS);
1674 return afs_wait_for_call_to_complete(call, &fc->ac);
1675 }
1676
1677 /*
1678 * release a lock on a file
1679 */
1680 int yfs_fs_release_lock(struct afs_fs_cursor *fc, struct afs_status_cb *scb)
1681 {
1682 struct afs_vnode *vnode = fc->vnode;
1683 struct afs_call *call;
1684 struct afs_net *net = afs_v2net(vnode);
1685 __be32 *bp;
1686
1687 _enter("");
1688
1689 call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1690 sizeof(__be32) * 2 +
1691 sizeof(struct yfs_xdr_YFSFid),
1692 sizeof(struct yfs_xdr_YFSFetchStatus) +
1693 sizeof(struct yfs_xdr_YFSVolSync));
1694 if (!call)
1695 return -ENOMEM;
1696
1697 call->key = fc->key;
1698 call->lvnode = vnode;
1699 call->out_scb = scb;
1700
1701 /* marshall the parameters */
1702 bp = call->request;
1703 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1704 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1705 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1706 yfs_check_req(call, bp);
1707
1708 afs_use_fs_server(call, fc->cbi);
1709 trace_afs_make_fs_call(call, &vnode->fid);
1710 afs_set_fc_call(call, fc);
1711 afs_make_call(&fc->ac, call, GFP_NOFS);
1712 return afs_wait_for_call_to_complete(call, &fc->ac);
1713 }
1714
1715 /*
1716 * YFS.FetchStatus operation type
1717 */
1718 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1719 .name = "YFS.FetchStatus",
1720 .op = yfs_FS_FetchStatus,
1721 .deliver = yfs_deliver_fs_status_cb_and_volsync,
1722 .destructor = afs_flat_call_destructor,
1723 };
1724
1725 /*
1726 * Fetch the status information for a fid without needing a vnode handle.
1727 */
1728 int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1729 struct afs_net *net,
1730 struct afs_fid *fid,
1731 struct afs_status_cb *scb,
1732 struct afs_volsync *volsync)
1733 {
1734 struct afs_call *call;
1735 __be32 *bp;
1736
1737 _enter(",%x,{%llx:%llu},,",
1738 key_serial(fc->key), fid->vid, fid->vnode);
1739
1740 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1741 sizeof(__be32) * 2 +
1742 sizeof(struct yfs_xdr_YFSFid),
1743 sizeof(struct yfs_xdr_YFSFetchStatus) +
1744 sizeof(struct yfs_xdr_YFSCallBack) +
1745 sizeof(struct yfs_xdr_YFSVolSync));
1746 if (!call) {
1747 fc->ac.error = -ENOMEM;
1748 return -ENOMEM;
1749 }
1750
1751 call->key = fc->key;
1752 call->out_scb = scb;
1753 call->out_volsync = volsync;
1754
1755 /* marshall the parameters */
1756 bp = call->request;
1757 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1758 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1759 bp = xdr_encode_YFSFid(bp, fid);
1760 yfs_check_req(call, bp);
1761
1762 afs_use_fs_server(call, fc->cbi);
1763 trace_afs_make_fs_call(call, fid);
1764 afs_set_fc_call(call, fc);
1765 afs_make_call(&fc->ac, call, GFP_NOFS);
1766 return afs_wait_for_call_to_complete(call, &fc->ac);
1767 }
1768
1769 /*
1770 * Deliver reply data to an YFS.InlineBulkStatus call
1771 */
1772 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1773 {
1774 struct afs_status_cb *scb;
1775 const __be32 *bp;
1776 u32 tmp;
1777 int ret;
1778
1779 _enter("{%u}", call->unmarshall);
1780
1781 switch (call->unmarshall) {
1782 case 0:
1783 afs_extract_to_tmp(call);
1784 call->unmarshall++;
1785 /* Fall through */
1786
1787 /* Extract the file status count and array in two steps */
1788 case 1:
1789 _debug("extract status count");
1790 ret = afs_extract_data(call, true);
1791 if (ret < 0)
1792 return ret;
1793
1794 tmp = ntohl(call->tmp);
1795 _debug("status count: %u/%u", tmp, call->count2);
1796 if (tmp != call->count2)
1797 return afs_protocol_error(call, afs_eproto_ibulkst_count);
1798
1799 call->count = 0;
1800 call->unmarshall++;
1801 more_counts:
1802 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1803 /* Fall through */
1804
1805 case 2:
1806 _debug("extract status array %u", call->count);
1807 ret = afs_extract_data(call, true);
1808 if (ret < 0)
1809 return ret;
1810
1811 bp = call->buffer;
1812 scb = &call->out_scb[call->count];
1813 xdr_decode_YFSFetchStatus(&bp, call, scb);
1814
1815 call->count++;
1816 if (call->count < call->count2)
1817 goto more_counts;
1818
1819 call->count = 0;
1820 call->unmarshall++;
1821 afs_extract_to_tmp(call);
1822 /* Fall through */
1823
1824 /* Extract the callback count and array in two steps */
1825 case 3:
1826 _debug("extract CB count");
1827 ret = afs_extract_data(call, true);
1828 if (ret < 0)
1829 return ret;
1830
1831 tmp = ntohl(call->tmp);
1832 _debug("CB count: %u", tmp);
1833 if (tmp != call->count2)
1834 return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
1835 call->count = 0;
1836 call->unmarshall++;
1837 more_cbs:
1838 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1839 /* Fall through */
1840
1841 case 4:
1842 _debug("extract CB array");
1843 ret = afs_extract_data(call, true);
1844 if (ret < 0)
1845 return ret;
1846
1847 _debug("unmarshall CB array");
1848 bp = call->buffer;
1849 scb = &call->out_scb[call->count];
1850 xdr_decode_YFSCallBack(&bp, call, scb);
1851 call->count++;
1852 if (call->count < call->count2)
1853 goto more_cbs;
1854
1855 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1856 call->unmarshall++;
1857 /* Fall through */
1858
1859 case 5:
1860 ret = afs_extract_data(call, false);
1861 if (ret < 0)
1862 return ret;
1863
1864 bp = call->buffer;
1865 xdr_decode_YFSVolSync(&bp, call->out_volsync);
1866
1867 call->unmarshall++;
1868 /* Fall through */
1869
1870 case 6:
1871 break;
1872 }
1873
1874 _leave(" = 0 [done]");
1875 return 0;
1876 }
1877
1878 /*
1879 * FS.InlineBulkStatus operation type
1880 */
1881 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1882 .name = "YFS.InlineBulkStatus",
1883 .op = yfs_FS_InlineBulkStatus,
1884 .deliver = yfs_deliver_fs_inline_bulk_status,
1885 .destructor = afs_flat_call_destructor,
1886 };
1887
1888 /*
1889 * Fetch the status information for up to 1024 files
1890 */
1891 int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
1892 struct afs_net *net,
1893 struct afs_fid *fids,
1894 struct afs_status_cb *statuses,
1895 unsigned int nr_fids,
1896 struct afs_volsync *volsync)
1897 {
1898 struct afs_call *call;
1899 __be32 *bp;
1900 int i;
1901
1902 _enter(",%x,{%llx:%llu},%u",
1903 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
1904
1905 call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
1906 sizeof(__be32) +
1907 sizeof(__be32) +
1908 sizeof(__be32) +
1909 sizeof(struct yfs_xdr_YFSFid) * nr_fids,
1910 sizeof(struct yfs_xdr_YFSFetchStatus));
1911 if (!call) {
1912 fc->ac.error = -ENOMEM;
1913 return -ENOMEM;
1914 }
1915
1916 call->key = fc->key;
1917 call->out_scb = statuses;
1918 call->out_volsync = volsync;
1919 call->count2 = nr_fids;
1920
1921 /* marshall the parameters */
1922 bp = call->request;
1923 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
1924 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
1925 bp = xdr_encode_u32(bp, nr_fids);
1926 for (i = 0; i < nr_fids; i++)
1927 bp = xdr_encode_YFSFid(bp, &fids[i]);
1928 yfs_check_req(call, bp);
1929
1930 afs_use_fs_server(call, fc->cbi);
1931 trace_afs_make_fs_call(call, &fids[0]);
1932 afs_set_fc_call(call, fc);
1933 afs_make_call(&fc->ac, call, GFP_NOFS);
1934 return afs_wait_for_call_to_complete(call, &fc->ac);
1935 }
1936
1937 /*
1938 * Deliver reply data to an YFS.FetchOpaqueACL.
1939 */
1940 static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
1941 {
1942 struct yfs_acl *yacl = call->out_yacl;
1943 struct afs_acl *acl;
1944 const __be32 *bp;
1945 unsigned int size;
1946 int ret;
1947
1948 _enter("{%u}", call->unmarshall);
1949
1950 switch (call->unmarshall) {
1951 case 0:
1952 afs_extract_to_tmp(call);
1953 call->unmarshall++;
1954 /* Fall through */
1955
1956 /* Extract the file ACL length */
1957 case 1:
1958 ret = afs_extract_data(call, true);
1959 if (ret < 0)
1960 return ret;
1961
1962 size = call->count2 = ntohl(call->tmp);
1963 size = round_up(size, 4);
1964
1965 if (yacl->flags & YFS_ACL_WANT_ACL) {
1966 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1967 if (!acl)
1968 return -ENOMEM;
1969 yacl->acl = acl;
1970 acl->size = call->count2;
1971 afs_extract_begin(call, acl->data, size);
1972 } else {
1973 afs_extract_discard(call, size);
1974 }
1975 call->unmarshall++;
1976 /* Fall through */
1977
1978 /* Extract the file ACL */
1979 case 2:
1980 ret = afs_extract_data(call, true);
1981 if (ret < 0)
1982 return ret;
1983
1984 afs_extract_to_tmp(call);
1985 call->unmarshall++;
1986 /* Fall through */
1987
1988 /* Extract the volume ACL length */
1989 case 3:
1990 ret = afs_extract_data(call, true);
1991 if (ret < 0)
1992 return ret;
1993
1994 size = call->count2 = ntohl(call->tmp);
1995 size = round_up(size, 4);
1996
1997 if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
1998 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
1999 if (!acl)
2000 return -ENOMEM;
2001 yacl->vol_acl = acl;
2002 acl->size = call->count2;
2003 afs_extract_begin(call, acl->data, size);
2004 } else {
2005 afs_extract_discard(call, size);
2006 }
2007 call->unmarshall++;
2008 /* Fall through */
2009
2010 /* Extract the volume ACL */
2011 case 4:
2012 ret = afs_extract_data(call, true);
2013 if (ret < 0)
2014 return ret;
2015
2016 afs_extract_to_buf(call,
2017 sizeof(__be32) * 2 +
2018 sizeof(struct yfs_xdr_YFSFetchStatus) +
2019 sizeof(struct yfs_xdr_YFSVolSync));
2020 call->unmarshall++;
2021 /* Fall through */
2022
2023 /* extract the metadata */
2024 case 5:
2025 ret = afs_extract_data(call, false);
2026 if (ret < 0)
2027 return ret;
2028
2029 bp = call->buffer;
2030 yacl->inherit_flag = ntohl(*bp++);
2031 yacl->num_cleaned = ntohl(*bp++);
2032 xdr_decode_YFSFetchStatus(&bp, call, call->out_scb);
2033 xdr_decode_YFSVolSync(&bp, call->out_volsync);
2034
2035 call->unmarshall++;
2036 /* Fall through */
2037
2038 case 6:
2039 break;
2040 }
2041
2042 _leave(" = 0 [done]");
2043 return 0;
2044 }
2045
2046 void yfs_free_opaque_acl(struct yfs_acl *yacl)
2047 {
2048 if (yacl) {
2049 kfree(yacl->acl);
2050 kfree(yacl->vol_acl);
2051 kfree(yacl);
2052 }
2053 }
2054
2055 /*
2056 * YFS.FetchOpaqueACL operation type
2057 */
2058 static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2059 .name = "YFS.FetchOpaqueACL",
2060 .op = yfs_FS_FetchOpaqueACL,
2061 .deliver = yfs_deliver_fs_fetch_opaque_acl,
2062 .destructor = afs_flat_call_destructor,
2063 };
2064
2065 /*
2066 * Fetch the YFS advanced ACLs for a file.
2067 */
2068 struct yfs_acl *yfs_fs_fetch_opaque_acl(struct afs_fs_cursor *fc,
2069 struct yfs_acl *yacl,
2070 struct afs_status_cb *scb)
2071 {
2072 struct afs_vnode *vnode = fc->vnode;
2073 struct afs_call *call;
2074 struct afs_net *net = afs_v2net(vnode);
2075 __be32 *bp;
2076
2077 _enter(",%x,{%llx:%llu},,",
2078 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2079
2080 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchOpaqueACL,
2081 sizeof(__be32) * 2 +
2082 sizeof(struct yfs_xdr_YFSFid),
2083 sizeof(__be32) * 2 +
2084 sizeof(struct yfs_xdr_YFSFetchStatus) +
2085 sizeof(struct yfs_xdr_YFSVolSync));
2086 if (!call) {
2087 fc->ac.error = -ENOMEM;
2088 return ERR_PTR(-ENOMEM);
2089 }
2090
2091 call->key = fc->key;
2092 call->out_yacl = yacl;
2093 call->out_scb = scb;
2094 call->out_volsync = NULL;
2095
2096 /* marshall the parameters */
2097 bp = call->request;
2098 bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2099 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2100 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2101 yfs_check_req(call, bp);
2102
2103 afs_use_fs_server(call, fc->cbi);
2104 trace_afs_make_fs_call(call, &vnode->fid);
2105 afs_make_call(&fc->ac, call, GFP_KERNEL);
2106 return (struct yfs_acl *)afs_wait_for_call_to_complete(call, &fc->ac);
2107 }
2108
2109 /*
2110 * YFS.StoreOpaqueACL2 operation type
2111 */
2112 static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2113 .name = "YFS.StoreOpaqueACL2",
2114 .op = yfs_FS_StoreOpaqueACL2,
2115 .deliver = yfs_deliver_status_and_volsync,
2116 .destructor = afs_flat_call_destructor,
2117 };
2118
2119 /*
2120 * Fetch the YFS ACL for a file.
2121 */
2122 int yfs_fs_store_opaque_acl2(struct afs_fs_cursor *fc, const struct afs_acl *acl,
2123 struct afs_status_cb *scb)
2124 {
2125 struct afs_vnode *vnode = fc->vnode;
2126 struct afs_call *call;
2127 struct afs_net *net = afs_v2net(vnode);
2128 size_t size;
2129 __be32 *bp;
2130
2131 _enter(",%x,{%llx:%llu},,",
2132 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
2133
2134 size = round_up(acl->size, 4);
2135 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreOpaqueACL2,
2136 sizeof(__be32) * 2 +
2137 sizeof(struct yfs_xdr_YFSFid) +
2138 sizeof(__be32) + size,
2139 sizeof(struct yfs_xdr_YFSFetchStatus) +
2140 sizeof(struct yfs_xdr_YFSVolSync));
2141 if (!call) {
2142 fc->ac.error = -ENOMEM;
2143 return -ENOMEM;
2144 }
2145
2146 call->key = fc->key;
2147 call->out_scb = scb;
2148 call->out_volsync = NULL;
2149
2150 /* marshall the parameters */
2151 bp = call->request;
2152 bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2153 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2154 bp = xdr_encode_YFSFid(bp, &vnode->fid);
2155 bp = xdr_encode_u32(bp, acl->size);
2156 memcpy(bp, acl->data, acl->size);
2157 if (acl->size != size)
2158 memset((void *)bp + acl->size, 0, size - acl->size);
2159 yfs_check_req(call, bp);
2160
2161 trace_afs_make_fs_call(call, &vnode->fid);
2162 afs_make_call(&fc->ac, call, GFP_KERNEL);
2163 return afs_wait_for_call_to_complete(call, &fc->ac);
2164 }