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