Merge tag 'sound-5.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[sfrench/cifs-2.6.git] / fs / afs / yfsclient.c
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
22 static const struct afs_fid afs_zero_fid;
23
24 static 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
31 static 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
42 static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
43 {
44         *bp++ = htonl(n);
45         return bp;
46 }
47
48 static __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
56 static __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
67 static size_t xdr_strlen(unsigned int len)
68 {
69         return sizeof(__be32) + round_up(len, sizeof(__be32));
70 }
71
72 static __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
86 static 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
92 static __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
104 static __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  */
120 static 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
144 static 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
151 static 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  */
166 static 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  */
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)
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
285 bad:
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  */
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)
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  */
317 static 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
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;
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
346 static 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  */
364 static 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  */
382 static __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  */
420 static 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  */
447 static 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  */
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,
480 };
481
482 /*
483  * Fetch the status information for a file.
484  */
485 int 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);
522         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
523 }
524
525 /*
526  * Deliver reply data to an YFS.FetchData64.
527  */
528 static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
529 {
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;
535
536         _enter("{%u,%zu/%llu}",
537                call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
538
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++;
546
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;
553
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;
559
560                 call->unmarshall++;
561
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);
573
574                 /* extract the returned data */
575         case 2:
576                 _debug("extract data %zu/%llu",
577                        iov_iter_count(&call->iter), req->remain);
578
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;
592                 }
593
594                 ASSERTCMP(req->remain, ==, 0);
595                 if (req->actual_len <= req->len)
596                         goto no_more_data;
597
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);
604
605                 ret = afs_extract_data(call, true);
606                 if (ret < 0)
607                         return ret;
608
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));
615
616                 /* extract the metadata */
617         case 4:
618                 ret = afs_extract_data(call, false);
619                 if (ret < 0)
620                         return ret;
621
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]);
629
630                 call->unmarshall++;
631
632         case 5:
633                 break;
634         }
635
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;
643         }
644
645         _leave(" = 0 [done]");
646         return 0;
647 }
648
649 static void yfs_fetch_data_destructor(struct afs_call *call)
650 {
651         struct afs_read *req = call->reply[2];
652
653         afs_put_read(req);
654         afs_flat_call_destructor(call);
655 }
656
657 /*
658  * YFS.FetchData64 operation type
659  */
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,
665 };
666
667 /*
668  * Fetch data from a file.
669  */
670 int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
671 {
672         struct afs_vnode *vnode = fc->vnode;
673         struct afs_call *call;
674         struct afs_net *net = afs_v2net(vnode);
675         __be32 *bp;
676
677         _enter(",%x,{%llx:%llu},%llx,%llx",
678                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
679                req->pos, req->len);
680
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;
690
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;
697
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);
706
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);
712 }
713
714 /*
715  * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
716  */
717 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
718 {
719         struct afs_vnode *vnode = call->reply[0];
720         const __be32 *bp;
721         int ret;
722
723         _enter("{%u}", call->unmarshall);
724
725         ret = afs_transfer_reply(call);
726         if (ret < 0)
727                 return ret;
728
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);
741
742         _leave(" = 0 [done]");
743         return 0;
744 }
745
746 /*
747  * FS.CreateFile and FS.MakeDir operation type
748  */
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,
754 };
755
756 /*
757  * Create a file.
758  */
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)
766 {
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;
772
773         _enter("");
774
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));
787
788         call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
789         if (!call)
790                 return -ENOMEM;
791
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;
798
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, yfs_LockNone); /* ViceLockType */
807         yfs_check_req(call, bp);
808
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);
812 }
813
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,
819 };
820
821 /*
822  * Make a directory.
823  */
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)
831 {
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;
837
838         _enter("");
839
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));
851
852         call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
853         if (!call)
854                 return -ENOMEM;
855
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;
862
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);
871
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);
875 }
876
877 /*
878  * Deliver reply data to a YFS.RemoveFile2 operation.
879  */
880 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
881 {
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;
887
888         _enter("{%u}", call->unmarshall);
889
890         ret = afs_transfer_reply(call);
891         if (ret < 0)
892                 return ret;
893
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;
900
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. */
906
907         xdr_decode_YFSVolSync(&bp, NULL);
908         return 0;
909 }
910
911 /*
912  * YFS.RemoveFile2 operation type.
913  */
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,
919 };
920
921 /*
922  * Remove a file and retrieve new file status.
923  */
924 int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
925                         const char *name, u64 current_data_version)
926 {
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;
932
933         _enter("");
934
935         namesz = strlen(name);
936
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;
948
949         call->key = fc->key;
950         call->reply[0] = dvnode;
951         call->reply[1] = vnode;
952         call->expected_version = current_data_version + 1;
953
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);
961
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);
965 }
966
967 /*
968  * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
969  */
970 static int yfs_deliver_fs_remove(struct afs_call *call)
971 {
972         struct afs_vnode *dvnode = call->reply[0];
973         const __be32 *bp;
974         int ret;
975
976         _enter("{%u}", call->unmarshall);
977
978         ret = afs_transfer_reply(call);
979         if (ret < 0)
980                 return ret;
981
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;
988
989         xdr_decode_YFSVolSync(&bp, NULL);
990         return 0;
991 }
992
993 /*
994  * FS.RemoveDir and FS.RemoveFile operation types.
995  */
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,
1001 };
1002
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,
1008 };
1009
1010 /*
1011  * remove a file or directory
1012  */
1013 int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1014                   const char *name, bool isdir, u64 current_data_version)
1015 {
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;
1021
1022         _enter("");
1023
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;
1035
1036         call->key = fc->key;
1037         call->reply[0] = dvnode;
1038         call->reply[1] = vnode;
1039         call->expected_version = current_data_version + 1;
1040
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);
1048
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);
1052 }
1053
1054 /*
1055  * Deliver reply data to a YFS.Link operation.
1056  */
1057 static int yfs_deliver_fs_link(struct afs_call *call)
1058 {
1059         struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
1060         const __be32 *bp;
1061         int ret;
1062
1063         _enter("{%u}", call->unmarshall);
1064
1065         ret = afs_transfer_reply(call);
1066         if (ret < 0)
1067                 return ret;
1068
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;
1081 }
1082
1083 /*
1084  * YFS.Link operation type.
1085  */
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,
1091 };
1092
1093 /*
1094  * Make a hard link.
1095  */
1096 int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1097                 const char *name, u64 current_data_version)
1098 {
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;
1104
1105         _enter("");
1106
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;
1119
1120         call->key = fc->key;
1121         call->reply[0] = dvnode;
1122         call->reply[1] = vnode;
1123         call->expected_version = current_data_version + 1;
1124
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);
1133
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);
1137 }
1138
1139 /*
1140  * Deliver reply data to a YFS.Symlink operation.
1141  */
1142 static int yfs_deliver_fs_symlink(struct afs_call *call)
1143 {
1144         struct afs_vnode *vnode = call->reply[0];
1145         const __be32 *bp;
1146         int ret;
1147
1148         _enter("{%u}", call->unmarshall);
1149
1150         ret = afs_transfer_reply(call);
1151         if (ret < 0)
1152                 return ret;
1153
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);
1165
1166         _leave(" = 0 [done]");
1167         return 0;
1168 }
1169
1170 /*
1171  * YFS.Symlink operation type
1172  */
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,
1178 };
1179
1180 /*
1181  * Create a symbolic link.
1182  */
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)
1189 {
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;
1195
1196         _enter("");
1197
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;
1213
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;
1219
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);
1229
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);
1233 }
1234
1235 /*
1236  * Deliver reply data to a YFS.Rename operation.
1237  */
1238 static int yfs_deliver_fs_rename(struct afs_call *call)
1239 {
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;
1244
1245         _enter("{%u}", call->unmarshall);
1246
1247         ret = afs_transfer_reply(call);
1248         if (ret < 0)
1249                 return ret;
1250
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;
1262         }
1263
1264         xdr_decode_YFSVolSync(&bp, NULL);
1265         _leave(" = 0 [done]");
1266         return 0;
1267 }
1268
1269 /*
1270  * YFS.Rename operation type
1271  */
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,
1277 };
1278
1279 /*
1280  * Rename a file or directory.
1281  */
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)
1288 {
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;
1294
1295         _enter("");
1296
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;
1311
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;
1317
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);
1327
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);
1331 }
1332
1333 /*
1334  * Deliver reply data to a YFS.StoreData64 operation.
1335  */
1336 static int yfs_deliver_fs_store_data(struct afs_call *call)
1337 {
1338         struct afs_vnode *vnode = call->reply[0];
1339         const __be32 *bp;
1340         int ret;
1341
1342         _enter("");
1343
1344         ret = afs_transfer_reply(call);
1345         if (ret < 0)
1346                 return ret;
1347
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);
1355
1356         afs_pages_written_back(vnode, call);
1357
1358         _leave(" = 0 [done]");
1359         return 0;
1360 }
1361
1362 /*
1363  * YFS.StoreData64 operation type.
1364  */
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,
1370 };
1371
1372 /*
1373  * Store a set of pages to a large file.
1374  */
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)
1378 {
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;
1384
1385         _enter(",%x,{%llx:%llu},,",
1386                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1387
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;
1393
1394         i_size = i_size_read(&vnode->vfs_inode);
1395         if (pos + size > i_size)
1396                 i_size = size + pos;
1397
1398         _debug("size %llx, at %llx, i_size %llx",
1399                (unsigned long long)size, (unsigned long long)pos,
1400                (unsigned long long)i_size);
1401
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;
1412
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;
1422
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);
1433
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);
1437 }
1438
1439 /*
1440  * deliver reply data to an FS.StoreStatus
1441  */
1442 static int yfs_deliver_fs_store_status(struct afs_call *call)
1443 {
1444         struct afs_vnode *vnode = call->reply[0];
1445         const __be32 *bp;
1446         int ret;
1447
1448         _enter("");
1449
1450         ret = afs_transfer_reply(call);
1451         if (ret < 0)
1452                 return ret;
1453
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);
1461
1462         _leave(" = 0 [done]");
1463         return 0;
1464 }
1465
1466 /*
1467  * YFS.StoreStatus operation type
1468  */
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,
1474 };
1475
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,
1481 };
1482
1483 /*
1484  * Set the attributes on a file, using YFS.StoreData64 rather than
1485  * YFS.StoreStatus so as to alter the file size also.
1486  */
1487 static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1488 {
1489         struct afs_vnode *vnode = fc->vnode;
1490         struct afs_call *call;
1491         struct afs_net *net = afs_v2net(vnode);
1492         __be32 *bp;
1493
1494         _enter(",%x,{%llx:%llu},,",
1495                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1496
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;
1506
1507         call->key = fc->key;
1508         call->reply[0] = vnode;
1509         call->expected_version = vnode->status.data_version + 1;
1510
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);
1521
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);
1525 }
1526
1527 /*
1528  * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1529  * file size, and YFS.StoreStatus otherwise.
1530  */
1531 int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1532 {
1533         struct afs_vnode *vnode = fc->vnode;
1534         struct afs_call *call;
1535         struct afs_net *net = afs_v2net(vnode);
1536         __be32 *bp;
1537
1538         if (attr->ia_valid & ATTR_SIZE)
1539                 return yfs_fs_setattr_size(fc, attr);
1540
1541         _enter(",%x,{%llx:%llu},,",
1542                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1543
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;
1552
1553         call->key = fc->key;
1554         call->reply[0] = vnode;
1555         call->expected_version = vnode->status.data_version;
1556
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);
1564
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);
1568 }
1569
1570 /*
1571  * Deliver reply data to a YFS.GetVolumeStatus operation.
1572  */
1573 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1574 {
1575         const __be32 *bp;
1576         char *p;
1577         u32 size;
1578         int ret;
1579
1580         _enter("{%u}", call->unmarshall);
1581
1582         switch (call->unmarshall) {
1583         case 0:
1584                 call->unmarshall++;
1585                 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1586
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;
1593
1594                 bp = call->buffer;
1595                 xdr_decode_YFSFetchVolumeStatus(&bp, call->reply[1]);
1596                 call->unmarshall++;
1597                 afs_extract_to_tmp(call);
1598
1599                 /* extract the volume name length */
1600         case 2:
1601                 ret = afs_extract_data(call, true);
1602                 if (ret < 0)
1603                         return ret;
1604
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++;
1613
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;
1620
1621                 p = call->reply[2];
1622                 p[call->count] = 0;
1623                 _debug("volname '%s'", p);
1624                 afs_extract_to_tmp(call);
1625                 call->unmarshall++;
1626
1627                 /* extract the offline message length */
1628         case 4:
1629                 ret = afs_extract_data(call, true);
1630                 if (ret < 0)
1631                         return ret;
1632
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++;
1641
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;
1648
1649                 p = call->reply[2];
1650                 p[call->count] = 0;
1651                 _debug("offline '%s'", p);
1652
1653                 afs_extract_to_tmp(call);
1654                 call->unmarshall++;
1655
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;
1661
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++;
1670
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;
1677
1678                 p = call->reply[2];
1679                 p[call->count] = 0;
1680                 _debug("motd '%s'", p);
1681
1682                 call->unmarshall++;
1683
1684         case 8:
1685                 break;
1686         }
1687
1688         _leave(" = 0 [done]");
1689         return 0;
1690 }
1691
1692 /*
1693  * Destroy a YFS.GetVolumeStatus call.
1694  */
1695 static void yfs_get_volume_status_call_destructor(struct afs_call *call)
1696 {
1697         kfree(call->reply[2]);
1698         call->reply[2] = NULL;
1699         afs_flat_call_destructor(call);
1700 }
1701
1702 /*
1703  * YFS.GetVolumeStatus operation type
1704  */
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,
1710 };
1711
1712 /*
1713  * fetch the status of a volume
1714  */
1715 int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1716                              struct afs_volume_status *vs)
1717 {
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;
1723
1724         _enter("");
1725
1726         tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1727         if (!tmpbuf)
1728                 return -ENOMEM;
1729
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;
1738         }
1739
1740         call->key = fc->key;
1741         call->reply[0] = vnode;
1742         call->reply[1] = vs;
1743         call->reply[2] = tmpbuf;
1744
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);
1751
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);
1755 }
1756
1757 /*
1758  * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock
1759  */
1760 static int yfs_deliver_fs_xxxx_lock(struct afs_call *call)
1761 {
1762         struct afs_vnode *vnode = call->reply[0];
1763         const __be32 *bp;
1764         int ret;
1765
1766         _enter("{%u}", call->unmarshall);
1767
1768         ret = afs_transfer_reply(call);
1769         if (ret < 0)
1770                 return ret;
1771
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);
1779
1780         _leave(" = 0 [done]");
1781         return 0;
1782 }
1783
1784 /*
1785  * YFS.SetLock operation type
1786  */
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,
1792 };
1793
1794 /*
1795  * YFS.ExtendLock operation type
1796  */
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,
1802 };
1803
1804 /*
1805  * YFS.ReleaseLock operation type
1806  */
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,
1812 };
1813
1814 /*
1815  * Set a lock on a file
1816  */
1817 int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1818 {
1819         struct afs_vnode *vnode = fc->vnode;
1820         struct afs_call *call;
1821         struct afs_net *net = afs_v2net(vnode);
1822         __be32 *bp;
1823
1824         _enter("");
1825
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;
1834
1835         call->key = fc->key;
1836         call->reply[0] = vnode;
1837
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);
1845
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);
1849 }
1850
1851 /*
1852  * extend a lock on a file
1853  */
1854 int yfs_fs_extend_lock(struct afs_fs_cursor *fc)
1855 {
1856         struct afs_vnode *vnode = fc->vnode;
1857         struct afs_call *call;
1858         struct afs_net *net = afs_v2net(vnode);
1859         __be32 *bp;
1860
1861         _enter("");
1862
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;
1870
1871         call->key = fc->key;
1872         call->reply[0] = vnode;
1873
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);
1880
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);
1884 }
1885
1886 /*
1887  * release a lock on a file
1888  */
1889 int yfs_fs_release_lock(struct afs_fs_cursor *fc)
1890 {
1891         struct afs_vnode *vnode = fc->vnode;
1892         struct afs_call *call;
1893         struct afs_net *net = afs_v2net(vnode);
1894         __be32 *bp;
1895
1896         _enter("");
1897
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;
1905
1906         call->key = fc->key;
1907         call->reply[0] = vnode;
1908
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);
1915
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);
1919 }
1920
1921 /*
1922  * Deliver reply data to an FS.FetchStatus with no vnode.
1923  */
1924 static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1925 {
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;
1932
1933         ret = afs_transfer_reply(call);
1934         if (ret < 0)
1935                 return ret;
1936
1937         _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
1938
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);
1947
1948         _leave(" = 0 [done]");
1949         return 0;
1950 }
1951
1952 /*
1953  * YFS.FetchStatus operation type
1954  */
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,
1960 };
1961
1962 /*
1963  * Fetch the status information for a fid without needing a vnode handle.
1964  */
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)
1971 {
1972         struct afs_call *call;
1973         __be32 *bp;
1974
1975         _enter(",%x,{%llx:%llu},,",
1976                key_serial(fc->key), fid->vid, fid->vnode);
1977
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;
1987         }
1988
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 */
1995
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);
2002
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);
2007 }
2008
2009 /*
2010  * Deliver reply data to an YFS.InlineBulkStatus call
2011  */
2012 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
2013 {
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;
2020
2021         _enter("{%u}", call->unmarshall);
2022
2023         switch (call->unmarshall) {
2024         case 0:
2025                 afs_extract_to_tmp(call);
2026                 call->unmarshall++;
2027
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;
2034
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);
2040
2041                 call->count = 0;
2042                 call->unmarshall++;
2043         more_counts:
2044                 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
2045
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;
2051
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;
2059
2060                 call->count++;
2061                 if (call->count < call->count2)
2062                         goto more_counts;
2063
2064                 call->count = 0;
2065                 call->unmarshall++;
2066                 afs_extract_to_tmp(call);
2067
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;
2074
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));
2084
2085         case 4:
2086                 _debug("extract CB array");
2087                 ret = afs_extract_data(call, true);
2088                 if (ret < 0)
2089                         return ret;
2090
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);
2099                 }
2100                 call->count++;
2101                 if (call->count < call->count2)
2102                         goto more_cbs;
2103
2104                 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
2105                 call->unmarshall++;
2106
2107         case 5:
2108                 ret = afs_extract_data(call, false);
2109                 if (ret < 0)
2110                         return ret;
2111
2112                 bp = call->buffer;
2113                 xdr_decode_YFSVolSync(&bp, call->reply[3]);
2114
2115                 call->unmarshall++;
2116
2117         case 6:
2118                 break;
2119         }
2120
2121         _leave(" = 0 [done]");
2122         return 0;
2123 }
2124
2125 /*
2126  * FS.InlineBulkStatus operation type
2127  */
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,
2133 };
2134
2135 /*
2136  * Fetch the status information for up to 1024 files
2137  */
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)
2145 {
2146         struct afs_call *call;
2147         __be32 *bp;
2148         int i;
2149
2150         _enter(",%x,{%llx:%llu},%u",
2151                key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2152
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;
2162         }
2163
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;
2170
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);
2179
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);
2184 }