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