Merge tag 'xarray-4.20-rc7' of git://git.infradead.org/users/willy/linux-dax
[linux/fpc-iii.git] / fs / afs / yfsclient.c
blob12658c1363ae41951783049d56b3933f3f3fd43e
1 /* YFS File Server client stubs
3 * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
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"
22 static const struct afs_fid afs_zero_fid;
24 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
26 call->cbi = afs_get_cb_interest(cbi);
29 #define xdr_size(x) (sizeof(*x) / sizeof(__be32))
31 static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
33 const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
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);
42 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
44 *bp++ = htonl(n);
45 return bp;
48 static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
50 struct yfs_xdr_u64 *x = (void *)bp;
52 *x = u64_to_xdr(n);
53 return bp + xdr_size(x);
56 static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
58 struct yfs_xdr_YFSFid *x = (void *)bp;
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);
67 static size_t xdr_strlen(unsigned int len)
69 return sizeof(__be32) + round_up(len, sizeof(__be32));
72 static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
74 bp = xdr_encode_u32(bp, len);
75 bp = memcpy(bp, p, len);
76 if (len & 3) {
77 unsigned int pad = 4 - (len & 3);
79 memset((u8 *)bp + len, 0, pad);
80 len += pad;
83 return bp + len / sizeof(__be32);
86 static s64 linux_to_yfs_time(const struct timespec64 *t)
88 /* Convert to 100ns intervals. */
89 return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
92 static __be32 *xdr_encode_YFSStoreStatus_mode(__be32 *bp, mode_t mode)
94 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
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);
104 static __be32 *xdr_encode_YFSStoreStatus_mtime(__be32 *bp, const struct timespec64 *t)
106 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
107 s64 mtime = linux_to_yfs_time(t);
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);
118 * Convert a signed 100ns-resolution 64-bit time into a timespec.
120 static struct timespec64 yfs_time_to_linux(s64 t)
122 struct timespec64 ts;
123 u64 abs_t;
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
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;
141 return ts;
144 static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
146 s64 t = xdr_to_u64(xdr);
148 return yfs_time_to_linux(t);
151 static void yfs_check_req(struct afs_call *call, __be32 *bp)
153 size_t len = (void *)bp - call->request;
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);
164 * Dump a bad file status record.
166 static void xdr_dump_bad(const __be32 *bp)
168 __be32 x[4];
169 int i;
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]));
179 memcpy(x, bp, 4);
180 pr_notice("0x50: %08x\n", ntohl(x[0]));
184 * Decode a YFSFetchStatus block
186 static 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)
193 const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
194 u32 type;
195 u8 flags = 0;
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);
204 return 0;
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;
222 status->type = type;
223 break;
224 default:
225 goto bad;
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; \
235 } while (0)
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; \
244 } while (0)
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; \
253 } while (0)
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);
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);
269 if (read_req) {
270 read_req->data_version = status->data_version;
271 read_req->file_size = status->size;
274 *_bp += xdr_size(xdr);
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);
283 return 0;
285 bad:
286 xdr_dump_bad(*_bp);
287 return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
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.
294 static 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)
301 int ret;
303 if (!vnode)
304 return xdr_decode_YFSFetchStatus(call, _bp, status, vnode,
305 expected_version, read_req);
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;
315 * Decode a YFSCallBack block
317 static void xdr_decode_YFSCallBack(struct afs_call *call,
318 struct afs_vnode *vnode,
319 const __be32 **_bp)
321 struct yfs_xdr_YFSCallBack *xdr = (void *)*_bp;
322 struct afs_cb_interest *old, *cbi = call->cbi;
323 u64 cb_expiry;
325 write_seqlock(&vnode->cb_lock);
327 if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) {
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;
338 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
341 write_sequnlock(&vnode->cb_lock);
342 call->cbi = cbi;
343 *_bp += xdr_size(xdr);
346 static void xdr_decode_YFSCallBack_raw(const __be32 **_bp,
347 struct afs_callback *cb)
349 struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
350 u64 cb_expiry;
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();
358 *_bp += xdr_size(x);
362 * Decode a YFSVolSync block
364 static void xdr_decode_YFSVolSync(const __be32 **_bp,
365 struct afs_volsync *volsync)
367 struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
368 u64 creation;
370 if (volsync) {
371 creation = xdr_to_u64(x->vol_creation_date);
372 do_div(creation, 10 * 1000 * 1000);
373 volsync->creation = creation;
376 *_bp += xdr_size(x);
380 * Encode the requested attributes into a YFSStoreStatus block
382 static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
384 struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
385 s64 mtime = 0, owner = 0, group = 0;
386 u32 mask = 0, mode = 0;
388 mask = 0;
389 if (attr->ia_valid & ATTR_MTIME) {
390 mask |= AFS_SET_MTIME;
391 mtime = linux_to_yfs_time(&attr->ia_mtime);
394 if (attr->ia_valid & ATTR_UID) {
395 mask |= AFS_SET_OWNER;
396 owner = from_kuid(&init_user_ns, attr->ia_uid);
399 if (attr->ia_valid & ATTR_GID) {
400 mask |= AFS_SET_GROUP;
401 group = from_kgid(&init_user_ns, attr->ia_gid);
404 if (attr->ia_valid & ATTR_MODE) {
405 mask |= AFS_SET_MODE;
406 mode = attr->ia_mode & S_IALLUGO;
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);
418 * Decode a YFSFetchVolumeStatus block.
420 static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
421 struct afs_volume_status *vs)
423 const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
424 u32 flags;
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);
445 * deliver reply data to an FS.FetchStatus
447 static int yfs_deliver_fs_fetch_status_vnode(struct afs_call *call)
449 struct afs_vnode *vnode = call->reply[0];
450 const __be32 *bp;
451 int ret;
453 ret = afs_transfer_reply(call);
454 if (ret < 0)
455 return ret;
457 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
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]);
468 _leave(" = 0 [done]");
469 return 0;
473 * YFS.FetchStatus operation type
475 static 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,
483 * Fetch the status information for a file.
485 int yfs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
486 bool new_inode)
488 struct afs_vnode *vnode = fc->vnode;
489 struct afs_call *call;
490 struct afs_net *net = afs_v2net(vnode);
491 __be32 *bp;
493 _enter(",%x,{%llx:%llu},,",
494 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
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;
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;
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);
519 call->cb_break = fc->cb_break;
520 afs_use_fs_server(call, fc->cbi);
521 trace_afs_make_fs_call(call, &vnode->fid);
522 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
526 * Deliver reply data to an YFS.FetchData64.
528 static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
530 struct afs_vnode *vnode = call->reply[0];
531 struct afs_read *req = call->reply[2];
532 const __be32 *bp;
533 unsigned int size;
534 int ret;
536 _enter("{%u,%zu/%llu}",
537 call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
539 switch (call->unmarshall) {
540 case 0:
541 req->actual_len = 0;
542 req->index = 0;
543 req->offset = req->pos & (PAGE_SIZE - 1);
544 afs_extract_to_tmp64(call);
545 call->unmarshall++;
547 /* extract the returned data length */
548 case 1:
549 _debug("extract data length");
550 ret = afs_extract_data(call, true);
551 if (ret < 0)
552 return ret;
554 req->actual_len = be64_to_cpu(call->tmp64);
555 _debug("DATA length: %llu", req->actual_len);
556 req->remain = min(req->len, req->actual_len);
557 if (req->remain == 0)
558 goto no_more_data;
560 call->unmarshall++;
562 begin_page:
563 ASSERTCMP(req->index, <, req->nr_pages);
564 if (req->remain > PAGE_SIZE - req->offset)
565 size = PAGE_SIZE - req->offset;
566 else
567 size = req->remain;
568 call->bvec[0].bv_len = size;
569 call->bvec[0].bv_offset = req->offset;
570 call->bvec[0].bv_page = req->pages[req->index];
571 iov_iter_bvec(&call->iter, READ, call->bvec, 1, size);
572 ASSERTCMP(size, <=, PAGE_SIZE);
574 /* extract the returned data */
575 case 2:
576 _debug("extract data %zu/%llu",
577 iov_iter_count(&call->iter), req->remain);
579 ret = afs_extract_data(call, true);
580 if (ret < 0)
581 return ret;
582 req->remain -= call->bvec[0].bv_len;
583 req->offset += call->bvec[0].bv_len;
584 ASSERTCMP(req->offset, <=, PAGE_SIZE);
585 if (req->offset == PAGE_SIZE) {
586 req->offset = 0;
587 if (req->page_done)
588 req->page_done(call, req);
589 req->index++;
590 if (req->remain > 0)
591 goto begin_page;
594 ASSERTCMP(req->remain, ==, 0);
595 if (req->actual_len <= req->len)
596 goto no_more_data;
598 /* Discard any excess data the server gave us */
599 iov_iter_discard(&call->iter, READ, req->actual_len - req->len);
600 call->unmarshall = 3;
601 case 3:
602 _debug("extract discard %zu/%llu",
603 iov_iter_count(&call->iter), req->actual_len - req->len);
605 ret = afs_extract_data(call, true);
606 if (ret < 0)
607 return ret;
609 no_more_data:
610 call->unmarshall = 4;
611 afs_extract_to_buf(call,
612 sizeof(struct yfs_xdr_YFSFetchStatus) +
613 sizeof(struct yfs_xdr_YFSCallBack) +
614 sizeof(struct yfs_xdr_YFSVolSync));
616 /* extract the metadata */
617 case 4:
618 ret = afs_extract_data(call, false);
619 if (ret < 0)
620 return ret;
622 bp = call->buffer;
623 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
624 &vnode->status.data_version, req);
625 if (ret < 0)
626 return ret;
627 xdr_decode_YFSCallBack(call, vnode, &bp);
628 xdr_decode_YFSVolSync(&bp, call->reply[1]);
630 call->unmarshall++;
632 case 5:
633 break;
636 for (; req->index < req->nr_pages; req->index++) {
637 if (req->offset < PAGE_SIZE)
638 zero_user_segment(req->pages[req->index],
639 req->offset, PAGE_SIZE);
640 if (req->page_done)
641 req->page_done(call, req);
642 req->offset = 0;
645 _leave(" = 0 [done]");
646 return 0;
649 static void yfs_fetch_data_destructor(struct afs_call *call)
651 struct afs_read *req = call->reply[2];
653 afs_put_read(req);
654 afs_flat_call_destructor(call);
658 * YFS.FetchData64 operation type
660 static const struct afs_call_type yfs_RXYFSFetchData64 = {
661 .name = "YFS.FetchData64",
662 .op = yfs_FS_FetchData64,
663 .deliver = yfs_deliver_fs_fetch_data64,
664 .destructor = yfs_fetch_data_destructor,
668 * Fetch data from a file.
670 int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
672 struct afs_vnode *vnode = fc->vnode;
673 struct afs_call *call;
674 struct afs_net *net = afs_v2net(vnode);
675 __be32 *bp;
677 _enter(",%x,{%llx:%llu},%llx,%llx",
678 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
679 req->pos, req->len);
681 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
682 sizeof(__be32) * 2 +
683 sizeof(struct yfs_xdr_YFSFid) +
684 sizeof(struct yfs_xdr_u64) * 2,
685 sizeof(struct yfs_xdr_YFSFetchStatus) +
686 sizeof(struct yfs_xdr_YFSCallBack) +
687 sizeof(struct yfs_xdr_YFSVolSync));
688 if (!call)
689 return -ENOMEM;
691 call->key = fc->key;
692 call->reply[0] = vnode;
693 call->reply[1] = NULL; /* volsync */
694 call->reply[2] = req;
695 call->expected_version = vnode->status.data_version;
696 call->want_reply_time = true;
698 /* marshall the parameters */
699 bp = call->request;
700 bp = xdr_encode_u32(bp, YFSFETCHDATA64);
701 bp = xdr_encode_u32(bp, 0); /* RPC flags */
702 bp = xdr_encode_YFSFid(bp, &vnode->fid);
703 bp = xdr_encode_u64(bp, req->pos);
704 bp = xdr_encode_u64(bp, req->len);
705 yfs_check_req(call, bp);
707 refcount_inc(&req->usage);
708 call->cb_break = fc->cb_break;
709 afs_use_fs_server(call, fc->cbi);
710 trace_afs_make_fs_call(call, &vnode->fid);
711 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
715 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
717 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
719 struct afs_vnode *vnode = call->reply[0];
720 const __be32 *bp;
721 int ret;
723 _enter("{%u}", call->unmarshall);
725 ret = afs_transfer_reply(call);
726 if (ret < 0)
727 return ret;
729 /* unmarshall the reply once we've received all of it */
730 bp = call->buffer;
731 xdr_decode_YFSFid(&bp, call->reply[1]);
732 ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
733 if (ret < 0)
734 return ret;
735 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
736 &call->expected_version, NULL);
737 if (ret < 0)
738 return ret;
739 xdr_decode_YFSCallBack_raw(&bp, call->reply[3]);
740 xdr_decode_YFSVolSync(&bp, NULL);
742 _leave(" = 0 [done]");
743 return 0;
747 * FS.CreateFile and FS.MakeDir operation type
749 static const struct afs_call_type afs_RXFSCreateFile = {
750 .name = "YFS.CreateFile",
751 .op = yfs_FS_CreateFile,
752 .deliver = yfs_deliver_fs_create_vnode,
753 .destructor = afs_flat_call_destructor,
757 * Create a file.
759 int yfs_fs_create_file(struct afs_fs_cursor *fc,
760 const char *name,
761 umode_t mode,
762 u64 current_data_version,
763 struct afs_fid *newfid,
764 struct afs_file_status *newstatus,
765 struct afs_callback *newcb)
767 struct afs_vnode *vnode = fc->vnode;
768 struct afs_call *call;
769 struct afs_net *net = afs_v2net(vnode);
770 size_t namesz, reqsz, rplsz;
771 __be32 *bp;
773 _enter("");
775 namesz = strlen(name);
776 reqsz = (sizeof(__be32) +
777 sizeof(__be32) +
778 sizeof(struct yfs_xdr_YFSFid) +
779 xdr_strlen(namesz) +
780 sizeof(struct yfs_xdr_YFSStoreStatus) +
781 sizeof(__be32));
782 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
783 sizeof(struct yfs_xdr_YFSFetchStatus) +
784 sizeof(struct yfs_xdr_YFSFetchStatus) +
785 sizeof(struct yfs_xdr_YFSCallBack) +
786 sizeof(struct yfs_xdr_YFSVolSync));
788 call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
789 if (!call)
790 return -ENOMEM;
792 call->key = fc->key;
793 call->reply[0] = vnode;
794 call->reply[1] = newfid;
795 call->reply[2] = newstatus;
796 call->reply[3] = newcb;
797 call->expected_version = current_data_version + 1;
799 /* marshall the parameters */
800 bp = call->request;
801 bp = xdr_encode_u32(bp, YFSCREATEFILE);
802 bp = xdr_encode_u32(bp, 0); /* RPC flags */
803 bp = xdr_encode_YFSFid(bp, &vnode->fid);
804 bp = xdr_encode_string(bp, name, namesz);
805 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
806 bp = xdr_encode_u32(bp, 0); /* ViceLockType */
807 yfs_check_req(call, bp);
809 afs_use_fs_server(call, fc->cbi);
810 trace_afs_make_fs_call(call, &vnode->fid);
811 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
814 static const struct afs_call_type yfs_RXFSMakeDir = {
815 .name = "YFS.MakeDir",
816 .op = yfs_FS_MakeDir,
817 .deliver = yfs_deliver_fs_create_vnode,
818 .destructor = afs_flat_call_destructor,
822 * Make a directory.
824 int yfs_fs_make_dir(struct afs_fs_cursor *fc,
825 const char *name,
826 umode_t mode,
827 u64 current_data_version,
828 struct afs_fid *newfid,
829 struct afs_file_status *newstatus,
830 struct afs_callback *newcb)
832 struct afs_vnode *vnode = fc->vnode;
833 struct afs_call *call;
834 struct afs_net *net = afs_v2net(vnode);
835 size_t namesz, reqsz, rplsz;
836 __be32 *bp;
838 _enter("");
840 namesz = strlen(name);
841 reqsz = (sizeof(__be32) +
842 sizeof(struct yfs_xdr_RPCFlags) +
843 sizeof(struct yfs_xdr_YFSFid) +
844 xdr_strlen(namesz) +
845 sizeof(struct yfs_xdr_YFSStoreStatus));
846 rplsz = (sizeof(struct yfs_xdr_YFSFid) +
847 sizeof(struct yfs_xdr_YFSFetchStatus) +
848 sizeof(struct yfs_xdr_YFSFetchStatus) +
849 sizeof(struct yfs_xdr_YFSCallBack) +
850 sizeof(struct yfs_xdr_YFSVolSync));
852 call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
853 if (!call)
854 return -ENOMEM;
856 call->key = fc->key;
857 call->reply[0] = vnode;
858 call->reply[1] = newfid;
859 call->reply[2] = newstatus;
860 call->reply[3] = newcb;
861 call->expected_version = current_data_version + 1;
863 /* marshall the parameters */
864 bp = call->request;
865 bp = xdr_encode_u32(bp, YFSMAKEDIR);
866 bp = xdr_encode_u32(bp, 0); /* RPC flags */
867 bp = xdr_encode_YFSFid(bp, &vnode->fid);
868 bp = xdr_encode_string(bp, name, namesz);
869 bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
870 yfs_check_req(call, bp);
872 afs_use_fs_server(call, fc->cbi);
873 trace_afs_make_fs_call(call, &vnode->fid);
874 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
878 * Deliver reply data to a YFS.RemoveFile2 operation.
880 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
882 struct afs_vnode *dvnode = call->reply[0];
883 struct afs_vnode *vnode = call->reply[1];
884 struct afs_fid fid;
885 const __be32 *bp;
886 int ret;
888 _enter("{%u}", call->unmarshall);
890 ret = afs_transfer_reply(call);
891 if (ret < 0)
892 return ret;
894 /* unmarshall the reply once we've received all of it */
895 bp = call->buffer;
896 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
897 &call->expected_version, NULL);
898 if (ret < 0)
899 return ret;
901 xdr_decode_YFSFid(&bp, &fid);
902 ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
903 if (ret < 0)
904 return ret;
905 /* Was deleted if vnode->status.abort_code == VNOVNODE. */
907 xdr_decode_YFSVolSync(&bp, NULL);
908 return 0;
912 * YFS.RemoveFile2 operation type.
914 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
915 .name = "YFS.RemoveFile2",
916 .op = yfs_FS_RemoveFile2,
917 .deliver = yfs_deliver_fs_remove_file2,
918 .destructor = afs_flat_call_destructor,
922 * Remove a file and retrieve new file status.
924 int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
925 const char *name, u64 current_data_version)
927 struct afs_vnode *dvnode = fc->vnode;
928 struct afs_call *call;
929 struct afs_net *net = afs_v2net(dvnode);
930 size_t namesz;
931 __be32 *bp;
933 _enter("");
935 namesz = strlen(name);
937 call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
938 sizeof(__be32) +
939 sizeof(struct yfs_xdr_RPCFlags) +
940 sizeof(struct yfs_xdr_YFSFid) +
941 xdr_strlen(namesz),
942 sizeof(struct yfs_xdr_YFSFetchStatus) +
943 sizeof(struct yfs_xdr_YFSFid) +
944 sizeof(struct yfs_xdr_YFSFetchStatus) +
945 sizeof(struct yfs_xdr_YFSVolSync));
946 if (!call)
947 return -ENOMEM;
949 call->key = fc->key;
950 call->reply[0] = dvnode;
951 call->reply[1] = vnode;
952 call->expected_version = current_data_version + 1;
954 /* marshall the parameters */
955 bp = call->request;
956 bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
957 bp = xdr_encode_u32(bp, 0); /* RPC flags */
958 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
959 bp = xdr_encode_string(bp, name, namesz);
960 yfs_check_req(call, bp);
962 afs_use_fs_server(call, fc->cbi);
963 trace_afs_make_fs_call(call, &dvnode->fid);
964 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
968 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
970 static int yfs_deliver_fs_remove(struct afs_call *call)
972 struct afs_vnode *dvnode = call->reply[0];
973 const __be32 *bp;
974 int ret;
976 _enter("{%u}", call->unmarshall);
978 ret = afs_transfer_reply(call);
979 if (ret < 0)
980 return ret;
982 /* unmarshall the reply once we've received all of it */
983 bp = call->buffer;
984 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
985 &call->expected_version, NULL);
986 if (ret < 0)
987 return ret;
989 xdr_decode_YFSVolSync(&bp, NULL);
990 return 0;
994 * FS.RemoveDir and FS.RemoveFile operation types.
996 static const struct afs_call_type yfs_RXYFSRemoveFile = {
997 .name = "YFS.RemoveFile",
998 .op = yfs_FS_RemoveFile,
999 .deliver = yfs_deliver_fs_remove,
1000 .destructor = afs_flat_call_destructor,
1003 static const struct afs_call_type yfs_RXYFSRemoveDir = {
1004 .name = "YFS.RemoveDir",
1005 .op = yfs_FS_RemoveDir,
1006 .deliver = yfs_deliver_fs_remove,
1007 .destructor = afs_flat_call_destructor,
1011 * remove a file or directory
1013 int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1014 const char *name, bool isdir, u64 current_data_version)
1016 struct afs_vnode *dvnode = fc->vnode;
1017 struct afs_call *call;
1018 struct afs_net *net = afs_v2net(dvnode);
1019 size_t namesz;
1020 __be32 *bp;
1022 _enter("");
1024 namesz = strlen(name);
1025 call = afs_alloc_flat_call(
1026 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
1027 sizeof(__be32) +
1028 sizeof(struct yfs_xdr_RPCFlags) +
1029 sizeof(struct yfs_xdr_YFSFid) +
1030 xdr_strlen(namesz),
1031 sizeof(struct yfs_xdr_YFSFetchStatus) +
1032 sizeof(struct yfs_xdr_YFSVolSync));
1033 if (!call)
1034 return -ENOMEM;
1036 call->key = fc->key;
1037 call->reply[0] = dvnode;
1038 call->reply[1] = vnode;
1039 call->expected_version = current_data_version + 1;
1041 /* marshall the parameters */
1042 bp = call->request;
1043 bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
1044 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1045 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1046 bp = xdr_encode_string(bp, name, namesz);
1047 yfs_check_req(call, bp);
1049 afs_use_fs_server(call, fc->cbi);
1050 trace_afs_make_fs_call(call, &dvnode->fid);
1051 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1055 * Deliver reply data to a YFS.Link operation.
1057 static int yfs_deliver_fs_link(struct afs_call *call)
1059 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
1060 const __be32 *bp;
1061 int ret;
1063 _enter("{%u}", call->unmarshall);
1065 ret = afs_transfer_reply(call);
1066 if (ret < 0)
1067 return ret;
1069 /* unmarshall the reply once we've received all of it */
1070 bp = call->buffer;
1071 ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
1072 if (ret < 0)
1073 return ret;
1074 ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
1075 &call->expected_version, NULL);
1076 if (ret < 0)
1077 return ret;
1078 xdr_decode_YFSVolSync(&bp, NULL);
1079 _leave(" = 0 [done]");
1080 return 0;
1084 * YFS.Link operation type.
1086 static const struct afs_call_type yfs_RXYFSLink = {
1087 .name = "YFS.Link",
1088 .op = yfs_FS_Link,
1089 .deliver = yfs_deliver_fs_link,
1090 .destructor = afs_flat_call_destructor,
1094 * Make a hard link.
1096 int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1097 const char *name, u64 current_data_version)
1099 struct afs_vnode *dvnode = fc->vnode;
1100 struct afs_call *call;
1101 struct afs_net *net = afs_v2net(vnode);
1102 size_t namesz;
1103 __be32 *bp;
1105 _enter("");
1107 namesz = strlen(name);
1108 call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1109 sizeof(__be32) +
1110 sizeof(struct yfs_xdr_RPCFlags) +
1111 sizeof(struct yfs_xdr_YFSFid) +
1112 xdr_strlen(namesz) +
1113 sizeof(struct yfs_xdr_YFSFid),
1114 sizeof(struct yfs_xdr_YFSFetchStatus) +
1115 sizeof(struct yfs_xdr_YFSFetchStatus) +
1116 sizeof(struct yfs_xdr_YFSVolSync));
1117 if (!call)
1118 return -ENOMEM;
1120 call->key = fc->key;
1121 call->reply[0] = dvnode;
1122 call->reply[1] = vnode;
1123 call->expected_version = current_data_version + 1;
1125 /* marshall the parameters */
1126 bp = call->request;
1127 bp = xdr_encode_u32(bp, YFSLINK);
1128 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1129 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1130 bp = xdr_encode_string(bp, name, namesz);
1131 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1132 yfs_check_req(call, bp);
1134 afs_use_fs_server(call, fc->cbi);
1135 trace_afs_make_fs_call(call, &vnode->fid);
1136 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1140 * Deliver reply data to a YFS.Symlink operation.
1142 static int yfs_deliver_fs_symlink(struct afs_call *call)
1144 struct afs_vnode *vnode = call->reply[0];
1145 const __be32 *bp;
1146 int ret;
1148 _enter("{%u}", call->unmarshall);
1150 ret = afs_transfer_reply(call);
1151 if (ret < 0)
1152 return ret;
1154 /* unmarshall the reply once we've received all of it */
1155 bp = call->buffer;
1156 xdr_decode_YFSFid(&bp, call->reply[1]);
1157 ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
1158 if (ret < 0)
1159 return ret;
1160 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1161 &call->expected_version, NULL);
1162 if (ret < 0)
1163 return ret;
1164 xdr_decode_YFSVolSync(&bp, NULL);
1166 _leave(" = 0 [done]");
1167 return 0;
1171 * YFS.Symlink operation type
1173 static const struct afs_call_type yfs_RXYFSSymlink = {
1174 .name = "YFS.Symlink",
1175 .op = yfs_FS_Symlink,
1176 .deliver = yfs_deliver_fs_symlink,
1177 .destructor = afs_flat_call_destructor,
1181 * Create a symbolic link.
1183 int yfs_fs_symlink(struct afs_fs_cursor *fc,
1184 const char *name,
1185 const char *contents,
1186 u64 current_data_version,
1187 struct afs_fid *newfid,
1188 struct afs_file_status *newstatus)
1190 struct afs_vnode *dvnode = fc->vnode;
1191 struct afs_call *call;
1192 struct afs_net *net = afs_v2net(dvnode);
1193 size_t namesz, contents_sz;
1194 __be32 *bp;
1196 _enter("");
1198 namesz = strlen(name);
1199 contents_sz = strlen(contents);
1200 call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1201 sizeof(__be32) +
1202 sizeof(struct yfs_xdr_RPCFlags) +
1203 sizeof(struct yfs_xdr_YFSFid) +
1204 xdr_strlen(namesz) +
1205 xdr_strlen(contents_sz) +
1206 sizeof(struct yfs_xdr_YFSStoreStatus),
1207 sizeof(struct yfs_xdr_YFSFid) +
1208 sizeof(struct yfs_xdr_YFSFetchStatus) +
1209 sizeof(struct yfs_xdr_YFSFetchStatus) +
1210 sizeof(struct yfs_xdr_YFSVolSync));
1211 if (!call)
1212 return -ENOMEM;
1214 call->key = fc->key;
1215 call->reply[0] = dvnode;
1216 call->reply[1] = newfid;
1217 call->reply[2] = newstatus;
1218 call->expected_version = current_data_version + 1;
1220 /* marshall the parameters */
1221 bp = call->request;
1222 bp = xdr_encode_u32(bp, YFSSYMLINK);
1223 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1224 bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1225 bp = xdr_encode_string(bp, name, namesz);
1226 bp = xdr_encode_string(bp, contents, contents_sz);
1227 bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1228 yfs_check_req(call, bp);
1230 afs_use_fs_server(call, fc->cbi);
1231 trace_afs_make_fs_call(call, &dvnode->fid);
1232 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1236 * Deliver reply data to a YFS.Rename operation.
1238 static int yfs_deliver_fs_rename(struct afs_call *call)
1240 struct afs_vnode *orig_dvnode = call->reply[0];
1241 struct afs_vnode *new_dvnode = call->reply[1];
1242 const __be32 *bp;
1243 int ret;
1245 _enter("{%u}", call->unmarshall);
1247 ret = afs_transfer_reply(call);
1248 if (ret < 0)
1249 return ret;
1251 /* unmarshall the reply once we've received all of it */
1252 bp = call->buffer;
1253 ret = yfs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
1254 &call->expected_version, NULL);
1255 if (ret < 0)
1256 return ret;
1257 if (new_dvnode != orig_dvnode) {
1258 ret = yfs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
1259 &call->expected_version_2, NULL);
1260 if (ret < 0)
1261 return ret;
1264 xdr_decode_YFSVolSync(&bp, NULL);
1265 _leave(" = 0 [done]");
1266 return 0;
1270 * YFS.Rename operation type
1272 static const struct afs_call_type yfs_RXYFSRename = {
1273 .name = "FS.Rename",
1274 .op = yfs_FS_Rename,
1275 .deliver = yfs_deliver_fs_rename,
1276 .destructor = afs_flat_call_destructor,
1280 * Rename a file or directory.
1282 int yfs_fs_rename(struct afs_fs_cursor *fc,
1283 const char *orig_name,
1284 struct afs_vnode *new_dvnode,
1285 const char *new_name,
1286 u64 current_orig_data_version,
1287 u64 current_new_data_version)
1289 struct afs_vnode *orig_dvnode = fc->vnode;
1290 struct afs_call *call;
1291 struct afs_net *net = afs_v2net(orig_dvnode);
1292 size_t o_namesz, n_namesz;
1293 __be32 *bp;
1295 _enter("");
1297 o_namesz = strlen(orig_name);
1298 n_namesz = strlen(new_name);
1299 call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1300 sizeof(__be32) +
1301 sizeof(struct yfs_xdr_RPCFlags) +
1302 sizeof(struct yfs_xdr_YFSFid) +
1303 xdr_strlen(o_namesz) +
1304 sizeof(struct yfs_xdr_YFSFid) +
1305 xdr_strlen(n_namesz),
1306 sizeof(struct yfs_xdr_YFSFetchStatus) +
1307 sizeof(struct yfs_xdr_YFSFetchStatus) +
1308 sizeof(struct yfs_xdr_YFSVolSync));
1309 if (!call)
1310 return -ENOMEM;
1312 call->key = fc->key;
1313 call->reply[0] = orig_dvnode;
1314 call->reply[1] = new_dvnode;
1315 call->expected_version = current_orig_data_version + 1;
1316 call->expected_version_2 = current_new_data_version + 1;
1318 /* marshall the parameters */
1319 bp = call->request;
1320 bp = xdr_encode_u32(bp, YFSRENAME);
1321 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1322 bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1323 bp = xdr_encode_string(bp, orig_name, o_namesz);
1324 bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1325 bp = xdr_encode_string(bp, new_name, n_namesz);
1326 yfs_check_req(call, bp);
1328 afs_use_fs_server(call, fc->cbi);
1329 trace_afs_make_fs_call(call, &orig_dvnode->fid);
1330 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1334 * Deliver reply data to a YFS.StoreData64 operation.
1336 static int yfs_deliver_fs_store_data(struct afs_call *call)
1338 struct afs_vnode *vnode = call->reply[0];
1339 const __be32 *bp;
1340 int ret;
1342 _enter("");
1344 ret = afs_transfer_reply(call);
1345 if (ret < 0)
1346 return ret;
1348 /* unmarshall the reply once we've received all of it */
1349 bp = call->buffer;
1350 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1351 &call->expected_version, NULL);
1352 if (ret < 0)
1353 return ret;
1354 xdr_decode_YFSVolSync(&bp, NULL);
1356 afs_pages_written_back(vnode, call);
1358 _leave(" = 0 [done]");
1359 return 0;
1363 * YFS.StoreData64 operation type.
1365 static const struct afs_call_type yfs_RXYFSStoreData64 = {
1366 .name = "YFS.StoreData64",
1367 .op = yfs_FS_StoreData64,
1368 .deliver = yfs_deliver_fs_store_data,
1369 .destructor = afs_flat_call_destructor,
1373 * Store a set of pages to a large file.
1375 int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1376 pgoff_t first, pgoff_t last,
1377 unsigned offset, unsigned to)
1379 struct afs_vnode *vnode = fc->vnode;
1380 struct afs_call *call;
1381 struct afs_net *net = afs_v2net(vnode);
1382 loff_t size, pos, i_size;
1383 __be32 *bp;
1385 _enter(",%x,{%llx:%llu},,",
1386 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1388 size = (loff_t)to - (loff_t)offset;
1389 if (first != last)
1390 size += (loff_t)(last - first) << PAGE_SHIFT;
1391 pos = (loff_t)first << PAGE_SHIFT;
1392 pos += offset;
1394 i_size = i_size_read(&vnode->vfs_inode);
1395 if (pos + size > i_size)
1396 i_size = size + pos;
1398 _debug("size %llx, at %llx, i_size %llx",
1399 (unsigned long long)size, (unsigned long long)pos,
1400 (unsigned long long)i_size);
1402 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1403 sizeof(__be32) +
1404 sizeof(__be32) +
1405 sizeof(struct yfs_xdr_YFSFid) +
1406 sizeof(struct yfs_xdr_YFSStoreStatus) +
1407 sizeof(struct yfs_xdr_u64) * 3,
1408 sizeof(struct yfs_xdr_YFSFetchStatus) +
1409 sizeof(struct yfs_xdr_YFSVolSync));
1410 if (!call)
1411 return -ENOMEM;
1413 call->key = fc->key;
1414 call->mapping = mapping;
1415 call->reply[0] = vnode;
1416 call->first = first;
1417 call->last = last;
1418 call->first_offset = offset;
1419 call->last_to = to;
1420 call->send_pages = true;
1421 call->expected_version = vnode->status.data_version + 1;
1423 /* marshall the parameters */
1424 bp = call->request;
1425 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1426 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1427 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1428 bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1429 bp = xdr_encode_u64(bp, pos);
1430 bp = xdr_encode_u64(bp, size);
1431 bp = xdr_encode_u64(bp, i_size);
1432 yfs_check_req(call, bp);
1434 afs_use_fs_server(call, fc->cbi);
1435 trace_afs_make_fs_call(call, &vnode->fid);
1436 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1440 * deliver reply data to an FS.StoreStatus
1442 static int yfs_deliver_fs_store_status(struct afs_call *call)
1444 struct afs_vnode *vnode = call->reply[0];
1445 const __be32 *bp;
1446 int ret;
1448 _enter("");
1450 ret = afs_transfer_reply(call);
1451 if (ret < 0)
1452 return ret;
1454 /* unmarshall the reply once we've received all of it */
1455 bp = call->buffer;
1456 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1457 &call->expected_version, NULL);
1458 if (ret < 0)
1459 return ret;
1460 xdr_decode_YFSVolSync(&bp, NULL);
1462 _leave(" = 0 [done]");
1463 return 0;
1467 * YFS.StoreStatus operation type
1469 static const struct afs_call_type yfs_RXYFSStoreStatus = {
1470 .name = "YFS.StoreStatus",
1471 .op = yfs_FS_StoreStatus,
1472 .deliver = yfs_deliver_fs_store_status,
1473 .destructor = afs_flat_call_destructor,
1476 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1477 .name = "YFS.StoreData64",
1478 .op = yfs_FS_StoreData64,
1479 .deliver = yfs_deliver_fs_store_status,
1480 .destructor = afs_flat_call_destructor,
1484 * Set the attributes on a file, using YFS.StoreData64 rather than
1485 * YFS.StoreStatus so as to alter the file size also.
1487 static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1489 struct afs_vnode *vnode = fc->vnode;
1490 struct afs_call *call;
1491 struct afs_net *net = afs_v2net(vnode);
1492 __be32 *bp;
1494 _enter(",%x,{%llx:%llu},,",
1495 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1497 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1498 sizeof(__be32) * 2 +
1499 sizeof(struct yfs_xdr_YFSFid) +
1500 sizeof(struct yfs_xdr_YFSStoreStatus) +
1501 sizeof(struct yfs_xdr_u64) * 3,
1502 sizeof(struct yfs_xdr_YFSFetchStatus) +
1503 sizeof(struct yfs_xdr_YFSVolSync));
1504 if (!call)
1505 return -ENOMEM;
1507 call->key = fc->key;
1508 call->reply[0] = vnode;
1509 call->expected_version = vnode->status.data_version + 1;
1511 /* marshall the parameters */
1512 bp = call->request;
1513 bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1514 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1515 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1516 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1517 bp = xdr_encode_u64(bp, 0); /* position of start of write */
1518 bp = xdr_encode_u64(bp, 0); /* size of write */
1519 bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1520 yfs_check_req(call, bp);
1522 afs_use_fs_server(call, fc->cbi);
1523 trace_afs_make_fs_call(call, &vnode->fid);
1524 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1528 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1529 * file size, and YFS.StoreStatus otherwise.
1531 int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1533 struct afs_vnode *vnode = fc->vnode;
1534 struct afs_call *call;
1535 struct afs_net *net = afs_v2net(vnode);
1536 __be32 *bp;
1538 if (attr->ia_valid & ATTR_SIZE)
1539 return yfs_fs_setattr_size(fc, attr);
1541 _enter(",%x,{%llx:%llu},,",
1542 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1544 call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1545 sizeof(__be32) * 2 +
1546 sizeof(struct yfs_xdr_YFSFid) +
1547 sizeof(struct yfs_xdr_YFSStoreStatus),
1548 sizeof(struct yfs_xdr_YFSFetchStatus) +
1549 sizeof(struct yfs_xdr_YFSVolSync));
1550 if (!call)
1551 return -ENOMEM;
1553 call->key = fc->key;
1554 call->reply[0] = vnode;
1555 call->expected_version = vnode->status.data_version;
1557 /* marshall the parameters */
1558 bp = call->request;
1559 bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1560 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1561 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1562 bp = xdr_encode_YFS_StoreStatus(bp, attr);
1563 yfs_check_req(call, bp);
1565 afs_use_fs_server(call, fc->cbi);
1566 trace_afs_make_fs_call(call, &vnode->fid);
1567 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1571 * Deliver reply data to a YFS.GetVolumeStatus operation.
1573 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1575 const __be32 *bp;
1576 char *p;
1577 u32 size;
1578 int ret;
1580 _enter("{%u}", call->unmarshall);
1582 switch (call->unmarshall) {
1583 case 0:
1584 call->unmarshall++;
1585 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1587 /* extract the returned status record */
1588 case 1:
1589 _debug("extract status");
1590 ret = afs_extract_data(call, true);
1591 if (ret < 0)
1592 return ret;
1594 bp = call->buffer;
1595 xdr_decode_YFSFetchVolumeStatus(&bp, call->reply[1]);
1596 call->unmarshall++;
1597 afs_extract_to_tmp(call);
1599 /* extract the volume name length */
1600 case 2:
1601 ret = afs_extract_data(call, true);
1602 if (ret < 0)
1603 return ret;
1605 call->count = ntohl(call->tmp);
1606 _debug("volname length: %u", call->count);
1607 if (call->count >= AFSNAMEMAX)
1608 return afs_protocol_error(call, -EBADMSG,
1609 afs_eproto_volname_len);
1610 size = (call->count + 3) & ~3; /* It's padded */
1611 afs_extract_begin(call, call->reply[2], size);
1612 call->unmarshall++;
1614 /* extract the volume name */
1615 case 3:
1616 _debug("extract volname");
1617 ret = afs_extract_data(call, true);
1618 if (ret < 0)
1619 return ret;
1621 p = call->reply[2];
1622 p[call->count] = 0;
1623 _debug("volname '%s'", p);
1624 afs_extract_to_tmp(call);
1625 call->unmarshall++;
1627 /* extract the offline message length */
1628 case 4:
1629 ret = afs_extract_data(call, true);
1630 if (ret < 0)
1631 return ret;
1633 call->count = ntohl(call->tmp);
1634 _debug("offline msg length: %u", call->count);
1635 if (call->count >= AFSNAMEMAX)
1636 return afs_protocol_error(call, -EBADMSG,
1637 afs_eproto_offline_msg_len);
1638 size = (call->count + 3) & ~3; /* It's padded */
1639 afs_extract_begin(call, call->reply[2], size);
1640 call->unmarshall++;
1642 /* extract the offline message */
1643 case 5:
1644 _debug("extract offline");
1645 ret = afs_extract_data(call, true);
1646 if (ret < 0)
1647 return ret;
1649 p = call->reply[2];
1650 p[call->count] = 0;
1651 _debug("offline '%s'", p);
1653 afs_extract_to_tmp(call);
1654 call->unmarshall++;
1656 /* extract the message of the day length */
1657 case 6:
1658 ret = afs_extract_data(call, true);
1659 if (ret < 0)
1660 return ret;
1662 call->count = ntohl(call->tmp);
1663 _debug("motd length: %u", call->count);
1664 if (call->count >= AFSNAMEMAX)
1665 return afs_protocol_error(call, -EBADMSG,
1666 afs_eproto_motd_len);
1667 size = (call->count + 3) & ~3; /* It's padded */
1668 afs_extract_begin(call, call->reply[2], size);
1669 call->unmarshall++;
1671 /* extract the message of the day */
1672 case 7:
1673 _debug("extract motd");
1674 ret = afs_extract_data(call, false);
1675 if (ret < 0)
1676 return ret;
1678 p = call->reply[2];
1679 p[call->count] = 0;
1680 _debug("motd '%s'", p);
1682 call->unmarshall++;
1684 case 8:
1685 break;
1688 _leave(" = 0 [done]");
1689 return 0;
1693 * Destroy a YFS.GetVolumeStatus call.
1695 static void yfs_get_volume_status_call_destructor(struct afs_call *call)
1697 kfree(call->reply[2]);
1698 call->reply[2] = NULL;
1699 afs_flat_call_destructor(call);
1703 * YFS.GetVolumeStatus operation type
1705 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1706 .name = "YFS.GetVolumeStatus",
1707 .op = yfs_FS_GetVolumeStatus,
1708 .deliver = yfs_deliver_fs_get_volume_status,
1709 .destructor = yfs_get_volume_status_call_destructor,
1713 * fetch the status of a volume
1715 int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1716 struct afs_volume_status *vs)
1718 struct afs_vnode *vnode = fc->vnode;
1719 struct afs_call *call;
1720 struct afs_net *net = afs_v2net(vnode);
1721 __be32 *bp;
1722 void *tmpbuf;
1724 _enter("");
1726 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1727 if (!tmpbuf)
1728 return -ENOMEM;
1730 call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1731 sizeof(__be32) * 2 +
1732 sizeof(struct yfs_xdr_u64),
1733 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1734 sizeof(__be32));
1735 if (!call) {
1736 kfree(tmpbuf);
1737 return -ENOMEM;
1740 call->key = fc->key;
1741 call->reply[0] = vnode;
1742 call->reply[1] = vs;
1743 call->reply[2] = tmpbuf;
1745 /* marshall the parameters */
1746 bp = call->request;
1747 bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1748 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1749 bp = xdr_encode_u64(bp, vnode->fid.vid);
1750 yfs_check_req(call, bp);
1752 afs_use_fs_server(call, fc->cbi);
1753 trace_afs_make_fs_call(call, &vnode->fid);
1754 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1758 * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock
1760 static int yfs_deliver_fs_xxxx_lock(struct afs_call *call)
1762 struct afs_vnode *vnode = call->reply[0];
1763 const __be32 *bp;
1764 int ret;
1766 _enter("{%u}", call->unmarshall);
1768 ret = afs_transfer_reply(call);
1769 if (ret < 0)
1770 return ret;
1772 /* unmarshall the reply once we've received all of it */
1773 bp = call->buffer;
1774 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1775 &call->expected_version, NULL);
1776 if (ret < 0)
1777 return ret;
1778 xdr_decode_YFSVolSync(&bp, NULL);
1780 _leave(" = 0 [done]");
1781 return 0;
1785 * YFS.SetLock operation type
1787 static const struct afs_call_type yfs_RXYFSSetLock = {
1788 .name = "YFS.SetLock",
1789 .op = yfs_FS_SetLock,
1790 .deliver = yfs_deliver_fs_xxxx_lock,
1791 .destructor = afs_flat_call_destructor,
1795 * YFS.ExtendLock operation type
1797 static const struct afs_call_type yfs_RXYFSExtendLock = {
1798 .name = "YFS.ExtendLock",
1799 .op = yfs_FS_ExtendLock,
1800 .deliver = yfs_deliver_fs_xxxx_lock,
1801 .destructor = afs_flat_call_destructor,
1805 * YFS.ReleaseLock operation type
1807 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1808 .name = "YFS.ReleaseLock",
1809 .op = yfs_FS_ReleaseLock,
1810 .deliver = yfs_deliver_fs_xxxx_lock,
1811 .destructor = afs_flat_call_destructor,
1815 * Set a lock on a file
1817 int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1819 struct afs_vnode *vnode = fc->vnode;
1820 struct afs_call *call;
1821 struct afs_net *net = afs_v2net(vnode);
1822 __be32 *bp;
1824 _enter("");
1826 call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1827 sizeof(__be32) * 2 +
1828 sizeof(struct yfs_xdr_YFSFid) +
1829 sizeof(__be32),
1830 sizeof(struct yfs_xdr_YFSFetchStatus) +
1831 sizeof(struct yfs_xdr_YFSVolSync));
1832 if (!call)
1833 return -ENOMEM;
1835 call->key = fc->key;
1836 call->reply[0] = vnode;
1838 /* marshall the parameters */
1839 bp = call->request;
1840 bp = xdr_encode_u32(bp, YFSSETLOCK);
1841 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1842 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1843 bp = xdr_encode_u32(bp, type);
1844 yfs_check_req(call, bp);
1846 afs_use_fs_server(call, fc->cbi);
1847 trace_afs_make_fs_call(call, &vnode->fid);
1848 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1852 * extend a lock on a file
1854 int yfs_fs_extend_lock(struct afs_fs_cursor *fc)
1856 struct afs_vnode *vnode = fc->vnode;
1857 struct afs_call *call;
1858 struct afs_net *net = afs_v2net(vnode);
1859 __be32 *bp;
1861 _enter("");
1863 call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1864 sizeof(__be32) * 2 +
1865 sizeof(struct yfs_xdr_YFSFid),
1866 sizeof(struct yfs_xdr_YFSFetchStatus) +
1867 sizeof(struct yfs_xdr_YFSVolSync));
1868 if (!call)
1869 return -ENOMEM;
1871 call->key = fc->key;
1872 call->reply[0] = vnode;
1874 /* marshall the parameters */
1875 bp = call->request;
1876 bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1877 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1878 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1879 yfs_check_req(call, bp);
1881 afs_use_fs_server(call, fc->cbi);
1882 trace_afs_make_fs_call(call, &vnode->fid);
1883 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1887 * release a lock on a file
1889 int yfs_fs_release_lock(struct afs_fs_cursor *fc)
1891 struct afs_vnode *vnode = fc->vnode;
1892 struct afs_call *call;
1893 struct afs_net *net = afs_v2net(vnode);
1894 __be32 *bp;
1896 _enter("");
1898 call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1899 sizeof(__be32) * 2 +
1900 sizeof(struct yfs_xdr_YFSFid),
1901 sizeof(struct yfs_xdr_YFSFetchStatus) +
1902 sizeof(struct yfs_xdr_YFSVolSync));
1903 if (!call)
1904 return -ENOMEM;
1906 call->key = fc->key;
1907 call->reply[0] = vnode;
1909 /* marshall the parameters */
1910 bp = call->request;
1911 bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1912 bp = xdr_encode_u32(bp, 0); /* RPC flags */
1913 bp = xdr_encode_YFSFid(bp, &vnode->fid);
1914 yfs_check_req(call, bp);
1916 afs_use_fs_server(call, fc->cbi);
1917 trace_afs_make_fs_call(call, &vnode->fid);
1918 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1922 * Deliver reply data to an FS.FetchStatus with no vnode.
1924 static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1926 struct afs_file_status *status = call->reply[1];
1927 struct afs_callback *callback = call->reply[2];
1928 struct afs_volsync *volsync = call->reply[3];
1929 struct afs_vnode *vnode = call->reply[0];
1930 const __be32 *bp;
1931 int ret;
1933 ret = afs_transfer_reply(call);
1934 if (ret < 0)
1935 return ret;
1937 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
1939 /* unmarshall the reply once we've received all of it */
1940 bp = call->buffer;
1941 ret = yfs_decode_status(call, &bp, status, vnode,
1942 &call->expected_version, NULL);
1943 if (ret < 0)
1944 return ret;
1945 xdr_decode_YFSCallBack_raw(&bp, callback);
1946 xdr_decode_YFSVolSync(&bp, volsync);
1948 _leave(" = 0 [done]");
1949 return 0;
1953 * YFS.FetchStatus operation type
1955 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1956 .name = "YFS.FetchStatus",
1957 .op = yfs_FS_FetchStatus,
1958 .deliver = yfs_deliver_fs_fetch_status,
1959 .destructor = afs_flat_call_destructor,
1963 * Fetch the status information for a fid without needing a vnode handle.
1965 int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1966 struct afs_net *net,
1967 struct afs_fid *fid,
1968 struct afs_file_status *status,
1969 struct afs_callback *callback,
1970 struct afs_volsync *volsync)
1972 struct afs_call *call;
1973 __be32 *bp;
1975 _enter(",%x,{%llx:%llu},,",
1976 key_serial(fc->key), fid->vid, fid->vnode);
1978 call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1979 sizeof(__be32) * 2 +
1980 sizeof(struct yfs_xdr_YFSFid),
1981 sizeof(struct yfs_xdr_YFSFetchStatus) +
1982 sizeof(struct yfs_xdr_YFSCallBack) +
1983 sizeof(struct yfs_xdr_YFSVolSync));
1984 if (!call) {
1985 fc->ac.error = -ENOMEM;
1986 return -ENOMEM;
1989 call->key = fc->key;
1990 call->reply[0] = NULL; /* vnode for fid[0] */
1991 call->reply[1] = status;
1992 call->reply[2] = callback;
1993 call->reply[3] = volsync;
1994 call->expected_version = 1; /* vnode->status.data_version */
1996 /* marshall the parameters */
1997 bp = call->request;
1998 bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1999 bp = xdr_encode_u32(bp, 0); /* RPC flags */
2000 bp = xdr_encode_YFSFid(bp, fid);
2001 yfs_check_req(call, bp);
2003 call->cb_break = fc->cb_break;
2004 afs_use_fs_server(call, fc->cbi);
2005 trace_afs_make_fs_call(call, fid);
2006 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2010 * Deliver reply data to an YFS.InlineBulkStatus call
2012 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
2014 struct afs_file_status *statuses;
2015 struct afs_callback *callbacks;
2016 struct afs_vnode *vnode = call->reply[0];
2017 const __be32 *bp;
2018 u32 tmp;
2019 int ret;
2021 _enter("{%u}", call->unmarshall);
2023 switch (call->unmarshall) {
2024 case 0:
2025 afs_extract_to_tmp(call);
2026 call->unmarshall++;
2028 /* Extract the file status count and array in two steps */
2029 case 1:
2030 _debug("extract status count");
2031 ret = afs_extract_data(call, true);
2032 if (ret < 0)
2033 return ret;
2035 tmp = ntohl(call->tmp);
2036 _debug("status count: %u/%u", tmp, call->count2);
2037 if (tmp != call->count2)
2038 return afs_protocol_error(call, -EBADMSG,
2039 afs_eproto_ibulkst_count);
2041 call->count = 0;
2042 call->unmarshall++;
2043 more_counts:
2044 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
2046 case 2:
2047 _debug("extract status array %u", call->count);
2048 ret = afs_extract_data(call, true);
2049 if (ret < 0)
2050 return ret;
2052 bp = call->buffer;
2053 statuses = call->reply[1];
2054 ret = yfs_decode_status(call, &bp, &statuses[call->count],
2055 call->count == 0 ? vnode : NULL,
2056 NULL, NULL);
2057 if (ret < 0)
2058 return ret;
2060 call->count++;
2061 if (call->count < call->count2)
2062 goto more_counts;
2064 call->count = 0;
2065 call->unmarshall++;
2066 afs_extract_to_tmp(call);
2068 /* Extract the callback count and array in two steps */
2069 case 3:
2070 _debug("extract CB count");
2071 ret = afs_extract_data(call, true);
2072 if (ret < 0)
2073 return ret;
2075 tmp = ntohl(call->tmp);
2076 _debug("CB count: %u", tmp);
2077 if (tmp != call->count2)
2078 return afs_protocol_error(call, -EBADMSG,
2079 afs_eproto_ibulkst_cb_count);
2080 call->count = 0;
2081 call->unmarshall++;
2082 more_cbs:
2083 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
2085 case 4:
2086 _debug("extract CB array");
2087 ret = afs_extract_data(call, true);
2088 if (ret < 0)
2089 return ret;
2091 _debug("unmarshall CB array");
2092 bp = call->buffer;
2093 callbacks = call->reply[2];
2094 xdr_decode_YFSCallBack_raw(&bp, &callbacks[call->count]);
2095 statuses = call->reply[1];
2096 if (call->count == 0 && vnode && statuses[0].abort_code == 0) {
2097 bp = call->buffer;
2098 xdr_decode_YFSCallBack(call, vnode, &bp);
2100 call->count++;
2101 if (call->count < call->count2)
2102 goto more_cbs;
2104 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
2105 call->unmarshall++;
2107 case 5:
2108 ret = afs_extract_data(call, false);
2109 if (ret < 0)
2110 return ret;
2112 bp = call->buffer;
2113 xdr_decode_YFSVolSync(&bp, call->reply[3]);
2115 call->unmarshall++;
2117 case 6:
2118 break;
2121 _leave(" = 0 [done]");
2122 return 0;
2126 * FS.InlineBulkStatus operation type
2128 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
2129 .name = "YFS.InlineBulkStatus",
2130 .op = yfs_FS_InlineBulkStatus,
2131 .deliver = yfs_deliver_fs_inline_bulk_status,
2132 .destructor = afs_flat_call_destructor,
2136 * Fetch the status information for up to 1024 files
2138 int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2139 struct afs_net *net,
2140 struct afs_fid *fids,
2141 struct afs_file_status *statuses,
2142 struct afs_callback *callbacks,
2143 unsigned int nr_fids,
2144 struct afs_volsync *volsync)
2146 struct afs_call *call;
2147 __be32 *bp;
2148 int i;
2150 _enter(",%x,{%llx:%llu},%u",
2151 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2153 call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
2154 sizeof(__be32) +
2155 sizeof(__be32) +
2156 sizeof(__be32) +
2157 sizeof(struct yfs_xdr_YFSFid) * nr_fids,
2158 sizeof(struct yfs_xdr_YFSFetchStatus));
2159 if (!call) {
2160 fc->ac.error = -ENOMEM;
2161 return -ENOMEM;
2164 call->key = fc->key;
2165 call->reply[0] = NULL; /* vnode for fid[0] */
2166 call->reply[1] = statuses;
2167 call->reply[2] = callbacks;
2168 call->reply[3] = volsync;
2169 call->count2 = nr_fids;
2171 /* marshall the parameters */
2172 bp = call->request;
2173 bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
2174 bp = xdr_encode_u32(bp, 0); /* RPCFlags */
2175 bp = xdr_encode_u32(bp, nr_fids);
2176 for (i = 0; i < nr_fids; i++)
2177 bp = xdr_encode_YFSFid(bp, &fids[i]);
2178 yfs_check_req(call, bp);
2180 call->cb_break = fc->cb_break;
2181 afs_use_fs_server(call, fc->cbi);
2182 trace_afs_make_fs_call(call, &fids[0]);
2183 return afs_make_call(&fc->ac, call, GFP_NOFS, false);