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