Merge tag 'driver-core-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.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                 /* Fall through - and 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                 /* Fall through - and 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
602                 /* Fall through */
603         case 3:
604                 _debug("extract discard %zu/%llu",
605                        iov_iter_count(&call->iter), req->actual_len - req->len);
606
607                 ret = afs_extract_data(call, true);
608                 if (ret < 0)
609                         return ret;
610
611         no_more_data:
612                 call->unmarshall = 4;
613                 afs_extract_to_buf(call,
614                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
615                                    sizeof(struct yfs_xdr_YFSCallBack) +
616                                    sizeof(struct yfs_xdr_YFSVolSync));
617
618                 /* Fall through - and extract the metadata */
619         case 4:
620                 ret = afs_extract_data(call, false);
621                 if (ret < 0)
622                         return ret;
623
624                 bp = call->buffer;
625                 ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
626                                         &vnode->status.data_version, req);
627                 if (ret < 0)
628                         return ret;
629                 xdr_decode_YFSCallBack(call, vnode, &bp);
630                 xdr_decode_YFSVolSync(&bp, call->reply[1]);
631
632                 call->unmarshall++;
633
634                 /* Fall through */
635         case 5:
636                 break;
637         }
638
639         for (; req->index < req->nr_pages; req->index++) {
640                 if (req->offset < PAGE_SIZE)
641                         zero_user_segment(req->pages[req->index],
642                                           req->offset, PAGE_SIZE);
643                 if (req->page_done)
644                         req->page_done(call, req);
645                 req->offset = 0;
646         }
647
648         _leave(" = 0 [done]");
649         return 0;
650 }
651
652 static void yfs_fetch_data_destructor(struct afs_call *call)
653 {
654         struct afs_read *req = call->reply[2];
655
656         afs_put_read(req);
657         afs_flat_call_destructor(call);
658 }
659
660 /*
661  * YFS.FetchData64 operation type
662  */
663 static const struct afs_call_type yfs_RXYFSFetchData64 = {
664         .name           = "YFS.FetchData64",
665         .op             = yfs_FS_FetchData64,
666         .deliver        = yfs_deliver_fs_fetch_data64,
667         .destructor     = yfs_fetch_data_destructor,
668 };
669
670 /*
671  * Fetch data from a file.
672  */
673 int yfs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
674 {
675         struct afs_vnode *vnode = fc->vnode;
676         struct afs_call *call;
677         struct afs_net *net = afs_v2net(vnode);
678         __be32 *bp;
679
680         _enter(",%x,{%llx:%llu},%llx,%llx",
681                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode,
682                req->pos, req->len);
683
684         call = afs_alloc_flat_call(net, &yfs_RXYFSFetchData64,
685                                    sizeof(__be32) * 2 +
686                                    sizeof(struct yfs_xdr_YFSFid) +
687                                    sizeof(struct yfs_xdr_u64) * 2,
688                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
689                                    sizeof(struct yfs_xdr_YFSCallBack) +
690                                    sizeof(struct yfs_xdr_YFSVolSync));
691         if (!call)
692                 return -ENOMEM;
693
694         call->key = fc->key;
695         call->reply[0] = vnode;
696         call->reply[1] = NULL; /* volsync */
697         call->reply[2] = req;
698         call->expected_version = vnode->status.data_version;
699         call->want_reply_time = true;
700
701         /* marshall the parameters */
702         bp = call->request;
703         bp = xdr_encode_u32(bp, YFSFETCHDATA64);
704         bp = xdr_encode_u32(bp, 0); /* RPC flags */
705         bp = xdr_encode_YFSFid(bp, &vnode->fid);
706         bp = xdr_encode_u64(bp, req->pos);
707         bp = xdr_encode_u64(bp, req->len);
708         yfs_check_req(call, bp);
709
710         refcount_inc(&req->usage);
711         call->cb_break = fc->cb_break;
712         afs_use_fs_server(call, fc->cbi);
713         trace_afs_make_fs_call(call, &vnode->fid);
714         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
715 }
716
717 /*
718  * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
719  */
720 static int yfs_deliver_fs_create_vnode(struct afs_call *call)
721 {
722         struct afs_vnode *vnode = call->reply[0];
723         const __be32 *bp;
724         int ret;
725
726         _enter("{%u}", call->unmarshall);
727
728         ret = afs_transfer_reply(call);
729         if (ret < 0)
730                 return ret;
731
732         /* unmarshall the reply once we've received all of it */
733         bp = call->buffer;
734         xdr_decode_YFSFid(&bp, call->reply[1]);
735         ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
736         if (ret < 0)
737                 return ret;
738         ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
739                                 &call->expected_version, NULL);
740         if (ret < 0)
741                 return ret;
742         xdr_decode_YFSCallBack_raw(&bp, call->reply[3]);
743         xdr_decode_YFSVolSync(&bp, NULL);
744
745         _leave(" = 0 [done]");
746         return 0;
747 }
748
749 /*
750  * FS.CreateFile and FS.MakeDir operation type
751  */
752 static const struct afs_call_type afs_RXFSCreateFile = {
753         .name           = "YFS.CreateFile",
754         .op             = yfs_FS_CreateFile,
755         .deliver        = yfs_deliver_fs_create_vnode,
756         .destructor     = afs_flat_call_destructor,
757 };
758
759 /*
760  * Create a file.
761  */
762 int yfs_fs_create_file(struct afs_fs_cursor *fc,
763                        const char *name,
764                        umode_t mode,
765                        u64 current_data_version,
766                        struct afs_fid *newfid,
767                        struct afs_file_status *newstatus,
768                        struct afs_callback *newcb)
769 {
770         struct afs_vnode *vnode = fc->vnode;
771         struct afs_call *call;
772         struct afs_net *net = afs_v2net(vnode);
773         size_t namesz, reqsz, rplsz;
774         __be32 *bp;
775
776         _enter("");
777
778         namesz = strlen(name);
779         reqsz = (sizeof(__be32) +
780                  sizeof(__be32) +
781                  sizeof(struct yfs_xdr_YFSFid) +
782                  xdr_strlen(namesz) +
783                  sizeof(struct yfs_xdr_YFSStoreStatus) +
784                  sizeof(__be32));
785         rplsz = (sizeof(struct yfs_xdr_YFSFid) +
786                  sizeof(struct yfs_xdr_YFSFetchStatus) +
787                  sizeof(struct yfs_xdr_YFSFetchStatus) +
788                  sizeof(struct yfs_xdr_YFSCallBack) +
789                  sizeof(struct yfs_xdr_YFSVolSync));
790
791         call = afs_alloc_flat_call(net, &afs_RXFSCreateFile, reqsz, rplsz);
792         if (!call)
793                 return -ENOMEM;
794
795         call->key = fc->key;
796         call->reply[0] = vnode;
797         call->reply[1] = newfid;
798         call->reply[2] = newstatus;
799         call->reply[3] = newcb;
800         call->expected_version = current_data_version + 1;
801
802         /* marshall the parameters */
803         bp = call->request;
804         bp = xdr_encode_u32(bp, YFSCREATEFILE);
805         bp = xdr_encode_u32(bp, 0); /* RPC flags */
806         bp = xdr_encode_YFSFid(bp, &vnode->fid);
807         bp = xdr_encode_string(bp, name, namesz);
808         bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
809         bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
810         yfs_check_req(call, bp);
811
812         afs_use_fs_server(call, fc->cbi);
813         trace_afs_make_fs_call(call, &vnode->fid);
814         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
815 }
816
817 static const struct afs_call_type yfs_RXFSMakeDir = {
818         .name           = "YFS.MakeDir",
819         .op             = yfs_FS_MakeDir,
820         .deliver        = yfs_deliver_fs_create_vnode,
821         .destructor     = afs_flat_call_destructor,
822 };
823
824 /*
825  * Make a directory.
826  */
827 int yfs_fs_make_dir(struct afs_fs_cursor *fc,
828                     const char *name,
829                     umode_t mode,
830                     u64 current_data_version,
831                     struct afs_fid *newfid,
832                     struct afs_file_status *newstatus,
833                     struct afs_callback *newcb)
834 {
835         struct afs_vnode *vnode = fc->vnode;
836         struct afs_call *call;
837         struct afs_net *net = afs_v2net(vnode);
838         size_t namesz, reqsz, rplsz;
839         __be32 *bp;
840
841         _enter("");
842
843         namesz = strlen(name);
844         reqsz = (sizeof(__be32) +
845                  sizeof(struct yfs_xdr_RPCFlags) +
846                  sizeof(struct yfs_xdr_YFSFid) +
847                  xdr_strlen(namesz) +
848                  sizeof(struct yfs_xdr_YFSStoreStatus));
849         rplsz = (sizeof(struct yfs_xdr_YFSFid) +
850                  sizeof(struct yfs_xdr_YFSFetchStatus) +
851                  sizeof(struct yfs_xdr_YFSFetchStatus) +
852                  sizeof(struct yfs_xdr_YFSCallBack) +
853                  sizeof(struct yfs_xdr_YFSVolSync));
854
855         call = afs_alloc_flat_call(net, &yfs_RXFSMakeDir, reqsz, rplsz);
856         if (!call)
857                 return -ENOMEM;
858
859         call->key = fc->key;
860         call->reply[0] = vnode;
861         call->reply[1] = newfid;
862         call->reply[2] = newstatus;
863         call->reply[3] = newcb;
864         call->expected_version = current_data_version + 1;
865
866         /* marshall the parameters */
867         bp = call->request;
868         bp = xdr_encode_u32(bp, YFSMAKEDIR);
869         bp = xdr_encode_u32(bp, 0); /* RPC flags */
870         bp = xdr_encode_YFSFid(bp, &vnode->fid);
871         bp = xdr_encode_string(bp, name, namesz);
872         bp = xdr_encode_YFSStoreStatus_mode(bp, mode);
873         yfs_check_req(call, bp);
874
875         afs_use_fs_server(call, fc->cbi);
876         trace_afs_make_fs_call(call, &vnode->fid);
877         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
878 }
879
880 /*
881  * Deliver reply data to a YFS.RemoveFile2 operation.
882  */
883 static int yfs_deliver_fs_remove_file2(struct afs_call *call)
884 {
885         struct afs_vnode *dvnode = call->reply[0];
886         struct afs_vnode *vnode = call->reply[1];
887         struct afs_fid fid;
888         const __be32 *bp;
889         int ret;
890
891         _enter("{%u}", call->unmarshall);
892
893         ret = afs_transfer_reply(call);
894         if (ret < 0)
895                 return ret;
896
897         /* unmarshall the reply once we've received all of it */
898         bp = call->buffer;
899         ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
900                                 &call->expected_version, NULL);
901         if (ret < 0)
902                 return ret;
903
904         xdr_decode_YFSFid(&bp, &fid);
905         ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
906         if (ret < 0)
907                 return ret;
908         /* Was deleted if vnode->status.abort_code == VNOVNODE. */
909
910         xdr_decode_YFSVolSync(&bp, NULL);
911         return 0;
912 }
913
914 /*
915  * YFS.RemoveFile2 operation type.
916  */
917 static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
918         .name           = "YFS.RemoveFile2",
919         .op             = yfs_FS_RemoveFile2,
920         .deliver        = yfs_deliver_fs_remove_file2,
921         .destructor     = afs_flat_call_destructor,
922 };
923
924 /*
925  * Remove a file and retrieve new file status.
926  */
927 int yfs_fs_remove_file2(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
928                         const char *name, u64 current_data_version)
929 {
930         struct afs_vnode *dvnode = fc->vnode;
931         struct afs_call *call;
932         struct afs_net *net = afs_v2net(dvnode);
933         size_t namesz;
934         __be32 *bp;
935
936         _enter("");
937
938         namesz = strlen(name);
939
940         call = afs_alloc_flat_call(net, &yfs_RXYFSRemoveFile2,
941                                    sizeof(__be32) +
942                                    sizeof(struct yfs_xdr_RPCFlags) +
943                                    sizeof(struct yfs_xdr_YFSFid) +
944                                    xdr_strlen(namesz),
945                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
946                                    sizeof(struct yfs_xdr_YFSFid) +
947                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
948                                    sizeof(struct yfs_xdr_YFSVolSync));
949         if (!call)
950                 return -ENOMEM;
951
952         call->key = fc->key;
953         call->reply[0] = dvnode;
954         call->reply[1] = vnode;
955         call->expected_version = current_data_version + 1;
956
957         /* marshall the parameters */
958         bp = call->request;
959         bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
960         bp = xdr_encode_u32(bp, 0); /* RPC flags */
961         bp = xdr_encode_YFSFid(bp, &dvnode->fid);
962         bp = xdr_encode_string(bp, name, namesz);
963         yfs_check_req(call, bp);
964
965         afs_use_fs_server(call, fc->cbi);
966         trace_afs_make_fs_call(call, &dvnode->fid);
967         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
968 }
969
970 /*
971  * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
972  */
973 static int yfs_deliver_fs_remove(struct afs_call *call)
974 {
975         struct afs_vnode *dvnode = call->reply[0];
976         const __be32 *bp;
977         int ret;
978
979         _enter("{%u}", call->unmarshall);
980
981         ret = afs_transfer_reply(call);
982         if (ret < 0)
983                 return ret;
984
985         /* unmarshall the reply once we've received all of it */
986         bp = call->buffer;
987         ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
988                                 &call->expected_version, NULL);
989         if (ret < 0)
990                 return ret;
991
992         xdr_decode_YFSVolSync(&bp, NULL);
993         return 0;
994 }
995
996 /*
997  * FS.RemoveDir and FS.RemoveFile operation types.
998  */
999 static const struct afs_call_type yfs_RXYFSRemoveFile = {
1000         .name           = "YFS.RemoveFile",
1001         .op             = yfs_FS_RemoveFile,
1002         .deliver        = yfs_deliver_fs_remove,
1003         .destructor     = afs_flat_call_destructor,
1004 };
1005
1006 static const struct afs_call_type yfs_RXYFSRemoveDir = {
1007         .name           = "YFS.RemoveDir",
1008         .op             = yfs_FS_RemoveDir,
1009         .deliver        = yfs_deliver_fs_remove,
1010         .destructor     = afs_flat_call_destructor,
1011 };
1012
1013 /*
1014  * remove a file or directory
1015  */
1016 int yfs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1017                   const char *name, bool isdir, u64 current_data_version)
1018 {
1019         struct afs_vnode *dvnode = fc->vnode;
1020         struct afs_call *call;
1021         struct afs_net *net = afs_v2net(dvnode);
1022         size_t namesz;
1023         __be32 *bp;
1024
1025         _enter("");
1026
1027         namesz = strlen(name);
1028         call = afs_alloc_flat_call(
1029                 net, isdir ? &yfs_RXYFSRemoveDir : &yfs_RXYFSRemoveFile,
1030                 sizeof(__be32) +
1031                 sizeof(struct yfs_xdr_RPCFlags) +
1032                 sizeof(struct yfs_xdr_YFSFid) +
1033                 xdr_strlen(namesz),
1034                 sizeof(struct yfs_xdr_YFSFetchStatus) +
1035                 sizeof(struct yfs_xdr_YFSVolSync));
1036         if (!call)
1037                 return -ENOMEM;
1038
1039         call->key = fc->key;
1040         call->reply[0] = dvnode;
1041         call->reply[1] = vnode;
1042         call->expected_version = current_data_version + 1;
1043
1044         /* marshall the parameters */
1045         bp = call->request;
1046         bp = xdr_encode_u32(bp, isdir ? YFSREMOVEDIR : YFSREMOVEFILE);
1047         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1048         bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1049         bp = xdr_encode_string(bp, name, namesz);
1050         yfs_check_req(call, bp);
1051
1052         afs_use_fs_server(call, fc->cbi);
1053         trace_afs_make_fs_call(call, &dvnode->fid);
1054         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1055 }
1056
1057 /*
1058  * Deliver reply data to a YFS.Link operation.
1059  */
1060 static int yfs_deliver_fs_link(struct afs_call *call)
1061 {
1062         struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
1063         const __be32 *bp;
1064         int ret;
1065
1066         _enter("{%u}", call->unmarshall);
1067
1068         ret = afs_transfer_reply(call);
1069         if (ret < 0)
1070                 return ret;
1071
1072         /* unmarshall the reply once we've received all of it */
1073         bp = call->buffer;
1074         ret = yfs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
1075         if (ret < 0)
1076                 return ret;
1077         ret = yfs_decode_status(call, &bp, &dvnode->status, dvnode,
1078                                 &call->expected_version, NULL);
1079         if (ret < 0)
1080                 return ret;
1081         xdr_decode_YFSVolSync(&bp, NULL);
1082         _leave(" = 0 [done]");
1083         return 0;
1084 }
1085
1086 /*
1087  * YFS.Link operation type.
1088  */
1089 static const struct afs_call_type yfs_RXYFSLink = {
1090         .name           = "YFS.Link",
1091         .op             = yfs_FS_Link,
1092         .deliver        = yfs_deliver_fs_link,
1093         .destructor     = afs_flat_call_destructor,
1094 };
1095
1096 /*
1097  * Make a hard link.
1098  */
1099 int yfs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
1100                 const char *name, u64 current_data_version)
1101 {
1102         struct afs_vnode *dvnode = fc->vnode;
1103         struct afs_call *call;
1104         struct afs_net *net = afs_v2net(vnode);
1105         size_t namesz;
1106         __be32 *bp;
1107
1108         _enter("");
1109
1110         namesz = strlen(name);
1111         call = afs_alloc_flat_call(net, &yfs_RXYFSLink,
1112                                    sizeof(__be32) +
1113                                    sizeof(struct yfs_xdr_RPCFlags) +
1114                                    sizeof(struct yfs_xdr_YFSFid) +
1115                                    xdr_strlen(namesz) +
1116                                    sizeof(struct yfs_xdr_YFSFid),
1117                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1118                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1119                                    sizeof(struct yfs_xdr_YFSVolSync));
1120         if (!call)
1121                 return -ENOMEM;
1122
1123         call->key = fc->key;
1124         call->reply[0] = dvnode;
1125         call->reply[1] = vnode;
1126         call->expected_version = current_data_version + 1;
1127
1128         /* marshall the parameters */
1129         bp = call->request;
1130         bp = xdr_encode_u32(bp, YFSLINK);
1131         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1132         bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1133         bp = xdr_encode_string(bp, name, namesz);
1134         bp = xdr_encode_YFSFid(bp, &vnode->fid);
1135         yfs_check_req(call, bp);
1136
1137         afs_use_fs_server(call, fc->cbi);
1138         trace_afs_make_fs_call(call, &vnode->fid);
1139         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1140 }
1141
1142 /*
1143  * Deliver reply data to a YFS.Symlink operation.
1144  */
1145 static int yfs_deliver_fs_symlink(struct afs_call *call)
1146 {
1147         struct afs_vnode *vnode = call->reply[0];
1148         const __be32 *bp;
1149         int ret;
1150
1151         _enter("{%u}", call->unmarshall);
1152
1153         ret = afs_transfer_reply(call);
1154         if (ret < 0)
1155                 return ret;
1156
1157         /* unmarshall the reply once we've received all of it */
1158         bp = call->buffer;
1159         xdr_decode_YFSFid(&bp, call->reply[1]);
1160         ret = yfs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
1161         if (ret < 0)
1162                 return ret;
1163         ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1164                                 &call->expected_version, NULL);
1165         if (ret < 0)
1166                 return ret;
1167         xdr_decode_YFSVolSync(&bp, NULL);
1168
1169         _leave(" = 0 [done]");
1170         return 0;
1171 }
1172
1173 /*
1174  * YFS.Symlink operation type
1175  */
1176 static const struct afs_call_type yfs_RXYFSSymlink = {
1177         .name           = "YFS.Symlink",
1178         .op             = yfs_FS_Symlink,
1179         .deliver        = yfs_deliver_fs_symlink,
1180         .destructor     = afs_flat_call_destructor,
1181 };
1182
1183 /*
1184  * Create a symbolic link.
1185  */
1186 int yfs_fs_symlink(struct afs_fs_cursor *fc,
1187                    const char *name,
1188                    const char *contents,
1189                    u64 current_data_version,
1190                    struct afs_fid *newfid,
1191                    struct afs_file_status *newstatus)
1192 {
1193         struct afs_vnode *dvnode = fc->vnode;
1194         struct afs_call *call;
1195         struct afs_net *net = afs_v2net(dvnode);
1196         size_t namesz, contents_sz;
1197         __be32 *bp;
1198
1199         _enter("");
1200
1201         namesz = strlen(name);
1202         contents_sz = strlen(contents);
1203         call = afs_alloc_flat_call(net, &yfs_RXYFSSymlink,
1204                                    sizeof(__be32) +
1205                                    sizeof(struct yfs_xdr_RPCFlags) +
1206                                    sizeof(struct yfs_xdr_YFSFid) +
1207                                    xdr_strlen(namesz) +
1208                                    xdr_strlen(contents_sz) +
1209                                    sizeof(struct yfs_xdr_YFSStoreStatus),
1210                                    sizeof(struct yfs_xdr_YFSFid) +
1211                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1212                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1213                                    sizeof(struct yfs_xdr_YFSVolSync));
1214         if (!call)
1215                 return -ENOMEM;
1216
1217         call->key = fc->key;
1218         call->reply[0] = dvnode;
1219         call->reply[1] = newfid;
1220         call->reply[2] = newstatus;
1221         call->expected_version = current_data_version + 1;
1222
1223         /* marshall the parameters */
1224         bp = call->request;
1225         bp = xdr_encode_u32(bp, YFSSYMLINK);
1226         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1227         bp = xdr_encode_YFSFid(bp, &dvnode->fid);
1228         bp = xdr_encode_string(bp, name, namesz);
1229         bp = xdr_encode_string(bp, contents, contents_sz);
1230         bp = xdr_encode_YFSStoreStatus_mode(bp, S_IRWXUGO);
1231         yfs_check_req(call, bp);
1232
1233         afs_use_fs_server(call, fc->cbi);
1234         trace_afs_make_fs_call(call, &dvnode->fid);
1235         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1236 }
1237
1238 /*
1239  * Deliver reply data to a YFS.Rename operation.
1240  */
1241 static int yfs_deliver_fs_rename(struct afs_call *call)
1242 {
1243         struct afs_vnode *orig_dvnode = call->reply[0];
1244         struct afs_vnode *new_dvnode = call->reply[1];
1245         const __be32 *bp;
1246         int ret;
1247
1248         _enter("{%u}", call->unmarshall);
1249
1250         ret = afs_transfer_reply(call);
1251         if (ret < 0)
1252                 return ret;
1253
1254         /* unmarshall the reply once we've received all of it */
1255         bp = call->buffer;
1256         ret = yfs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
1257                                 &call->expected_version, NULL);
1258         if (ret < 0)
1259                 return ret;
1260         if (new_dvnode != orig_dvnode) {
1261                 ret = yfs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
1262                                         &call->expected_version_2, NULL);
1263                 if (ret < 0)
1264                         return ret;
1265         }
1266
1267         xdr_decode_YFSVolSync(&bp, NULL);
1268         _leave(" = 0 [done]");
1269         return 0;
1270 }
1271
1272 /*
1273  * YFS.Rename operation type
1274  */
1275 static const struct afs_call_type yfs_RXYFSRename = {
1276         .name           = "FS.Rename",
1277         .op             = yfs_FS_Rename,
1278         .deliver        = yfs_deliver_fs_rename,
1279         .destructor     = afs_flat_call_destructor,
1280 };
1281
1282 /*
1283  * Rename a file or directory.
1284  */
1285 int yfs_fs_rename(struct afs_fs_cursor *fc,
1286                   const char *orig_name,
1287                   struct afs_vnode *new_dvnode,
1288                   const char *new_name,
1289                   u64 current_orig_data_version,
1290                   u64 current_new_data_version)
1291 {
1292         struct afs_vnode *orig_dvnode = fc->vnode;
1293         struct afs_call *call;
1294         struct afs_net *net = afs_v2net(orig_dvnode);
1295         size_t o_namesz, n_namesz;
1296         __be32 *bp;
1297
1298         _enter("");
1299
1300         o_namesz = strlen(orig_name);
1301         n_namesz = strlen(new_name);
1302         call = afs_alloc_flat_call(net, &yfs_RXYFSRename,
1303                                    sizeof(__be32) +
1304                                    sizeof(struct yfs_xdr_RPCFlags) +
1305                                    sizeof(struct yfs_xdr_YFSFid) +
1306                                    xdr_strlen(o_namesz) +
1307                                    sizeof(struct yfs_xdr_YFSFid) +
1308                                    xdr_strlen(n_namesz),
1309                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1310                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1311                                    sizeof(struct yfs_xdr_YFSVolSync));
1312         if (!call)
1313                 return -ENOMEM;
1314
1315         call->key = fc->key;
1316         call->reply[0] = orig_dvnode;
1317         call->reply[1] = new_dvnode;
1318         call->expected_version = current_orig_data_version + 1;
1319         call->expected_version_2 = current_new_data_version + 1;
1320
1321         /* marshall the parameters */
1322         bp = call->request;
1323         bp = xdr_encode_u32(bp, YFSRENAME);
1324         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1325         bp = xdr_encode_YFSFid(bp, &orig_dvnode->fid);
1326         bp = xdr_encode_string(bp, orig_name, o_namesz);
1327         bp = xdr_encode_YFSFid(bp, &new_dvnode->fid);
1328         bp = xdr_encode_string(bp, new_name, n_namesz);
1329         yfs_check_req(call, bp);
1330
1331         afs_use_fs_server(call, fc->cbi);
1332         trace_afs_make_fs_call(call, &orig_dvnode->fid);
1333         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1334 }
1335
1336 /*
1337  * Deliver reply data to a YFS.StoreData64 operation.
1338  */
1339 static int yfs_deliver_fs_store_data(struct afs_call *call)
1340 {
1341         struct afs_vnode *vnode = call->reply[0];
1342         const __be32 *bp;
1343         int ret;
1344
1345         _enter("");
1346
1347         ret = afs_transfer_reply(call);
1348         if (ret < 0)
1349                 return ret;
1350
1351         /* unmarshall the reply once we've received all of it */
1352         bp = call->buffer;
1353         ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1354                                 &call->expected_version, NULL);
1355         if (ret < 0)
1356                 return ret;
1357         xdr_decode_YFSVolSync(&bp, NULL);
1358
1359         afs_pages_written_back(vnode, call);
1360
1361         _leave(" = 0 [done]");
1362         return 0;
1363 }
1364
1365 /*
1366  * YFS.StoreData64 operation type.
1367  */
1368 static const struct afs_call_type yfs_RXYFSStoreData64 = {
1369         .name           = "YFS.StoreData64",
1370         .op             = yfs_FS_StoreData64,
1371         .deliver        = yfs_deliver_fs_store_data,
1372         .destructor     = afs_flat_call_destructor,
1373 };
1374
1375 /*
1376  * Store a set of pages to a large file.
1377  */
1378 int yfs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1379                       pgoff_t first, pgoff_t last,
1380                       unsigned offset, unsigned to)
1381 {
1382         struct afs_vnode *vnode = fc->vnode;
1383         struct afs_call *call;
1384         struct afs_net *net = afs_v2net(vnode);
1385         loff_t size, pos, i_size;
1386         __be32 *bp;
1387
1388         _enter(",%x,{%llx:%llu},,",
1389                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1390
1391         size = (loff_t)to - (loff_t)offset;
1392         if (first != last)
1393                 size += (loff_t)(last - first) << PAGE_SHIFT;
1394         pos = (loff_t)first << PAGE_SHIFT;
1395         pos += offset;
1396
1397         i_size = i_size_read(&vnode->vfs_inode);
1398         if (pos + size > i_size)
1399                 i_size = size + pos;
1400
1401         _debug("size %llx, at %llx, i_size %llx",
1402                (unsigned long long)size, (unsigned long long)pos,
1403                (unsigned long long)i_size);
1404
1405         call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64,
1406                                    sizeof(__be32) +
1407                                    sizeof(__be32) +
1408                                    sizeof(struct yfs_xdr_YFSFid) +
1409                                    sizeof(struct yfs_xdr_YFSStoreStatus) +
1410                                    sizeof(struct yfs_xdr_u64) * 3,
1411                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1412                                    sizeof(struct yfs_xdr_YFSVolSync));
1413         if (!call)
1414                 return -ENOMEM;
1415
1416         call->key = fc->key;
1417         call->mapping = mapping;
1418         call->reply[0] = vnode;
1419         call->first = first;
1420         call->last = last;
1421         call->first_offset = offset;
1422         call->last_to = to;
1423         call->send_pages = true;
1424         call->expected_version = vnode->status.data_version + 1;
1425
1426         /* marshall the parameters */
1427         bp = call->request;
1428         bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1429         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1430         bp = xdr_encode_YFSFid(bp, &vnode->fid);
1431         bp = xdr_encode_YFSStoreStatus_mtime(bp, &vnode->vfs_inode.i_mtime);
1432         bp = xdr_encode_u64(bp, pos);
1433         bp = xdr_encode_u64(bp, size);
1434         bp = xdr_encode_u64(bp, i_size);
1435         yfs_check_req(call, bp);
1436
1437         afs_use_fs_server(call, fc->cbi);
1438         trace_afs_make_fs_call(call, &vnode->fid);
1439         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1440 }
1441
1442 /*
1443  * deliver reply data to an FS.StoreStatus
1444  */
1445 static int yfs_deliver_fs_store_status(struct afs_call *call)
1446 {
1447         struct afs_vnode *vnode = call->reply[0];
1448         const __be32 *bp;
1449         int ret;
1450
1451         _enter("");
1452
1453         ret = afs_transfer_reply(call);
1454         if (ret < 0)
1455                 return ret;
1456
1457         /* unmarshall the reply once we've received all of it */
1458         bp = call->buffer;
1459         ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1460                                 &call->expected_version, NULL);
1461         if (ret < 0)
1462                 return ret;
1463         xdr_decode_YFSVolSync(&bp, NULL);
1464
1465         _leave(" = 0 [done]");
1466         return 0;
1467 }
1468
1469 /*
1470  * YFS.StoreStatus operation type
1471  */
1472 static const struct afs_call_type yfs_RXYFSStoreStatus = {
1473         .name           = "YFS.StoreStatus",
1474         .op             = yfs_FS_StoreStatus,
1475         .deliver        = yfs_deliver_fs_store_status,
1476         .destructor     = afs_flat_call_destructor,
1477 };
1478
1479 static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1480         .name           = "YFS.StoreData64",
1481         .op             = yfs_FS_StoreData64,
1482         .deliver        = yfs_deliver_fs_store_status,
1483         .destructor     = afs_flat_call_destructor,
1484 };
1485
1486 /*
1487  * Set the attributes on a file, using YFS.StoreData64 rather than
1488  * YFS.StoreStatus so as to alter the file size also.
1489  */
1490 static int yfs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1491 {
1492         struct afs_vnode *vnode = fc->vnode;
1493         struct afs_call *call;
1494         struct afs_net *net = afs_v2net(vnode);
1495         __be32 *bp;
1496
1497         _enter(",%x,{%llx:%llu},,",
1498                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1499
1500         call = afs_alloc_flat_call(net, &yfs_RXYFSStoreData64_as_Status,
1501                                    sizeof(__be32) * 2 +
1502                                    sizeof(struct yfs_xdr_YFSFid) +
1503                                    sizeof(struct yfs_xdr_YFSStoreStatus) +
1504                                    sizeof(struct yfs_xdr_u64) * 3,
1505                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1506                                    sizeof(struct yfs_xdr_YFSVolSync));
1507         if (!call)
1508                 return -ENOMEM;
1509
1510         call->key = fc->key;
1511         call->reply[0] = vnode;
1512         call->expected_version = vnode->status.data_version + 1;
1513
1514         /* marshall the parameters */
1515         bp = call->request;
1516         bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1517         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1518         bp = xdr_encode_YFSFid(bp, &vnode->fid);
1519         bp = xdr_encode_YFS_StoreStatus(bp, attr);
1520         bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1521         bp = xdr_encode_u64(bp, 0);             /* size of write */
1522         bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1523         yfs_check_req(call, bp);
1524
1525         afs_use_fs_server(call, fc->cbi);
1526         trace_afs_make_fs_call(call, &vnode->fid);
1527         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1528 }
1529
1530 /*
1531  * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1532  * file size, and YFS.StoreStatus otherwise.
1533  */
1534 int yfs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1535 {
1536         struct afs_vnode *vnode = fc->vnode;
1537         struct afs_call *call;
1538         struct afs_net *net = afs_v2net(vnode);
1539         __be32 *bp;
1540
1541         if (attr->ia_valid & ATTR_SIZE)
1542                 return yfs_fs_setattr_size(fc, attr);
1543
1544         _enter(",%x,{%llx:%llu},,",
1545                key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1546
1547         call = afs_alloc_flat_call(net, &yfs_RXYFSStoreStatus,
1548                                    sizeof(__be32) * 2 +
1549                                    sizeof(struct yfs_xdr_YFSFid) +
1550                                    sizeof(struct yfs_xdr_YFSStoreStatus),
1551                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1552                                    sizeof(struct yfs_xdr_YFSVolSync));
1553         if (!call)
1554                 return -ENOMEM;
1555
1556         call->key = fc->key;
1557         call->reply[0] = vnode;
1558         call->expected_version = vnode->status.data_version;
1559
1560         /* marshall the parameters */
1561         bp = call->request;
1562         bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1563         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1564         bp = xdr_encode_YFSFid(bp, &vnode->fid);
1565         bp = xdr_encode_YFS_StoreStatus(bp, attr);
1566         yfs_check_req(call, bp);
1567
1568         afs_use_fs_server(call, fc->cbi);
1569         trace_afs_make_fs_call(call, &vnode->fid);
1570         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1571 }
1572
1573 /*
1574  * Deliver reply data to a YFS.GetVolumeStatus operation.
1575  */
1576 static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1577 {
1578         const __be32 *bp;
1579         char *p;
1580         u32 size;
1581         int ret;
1582
1583         _enter("{%u}", call->unmarshall);
1584
1585         switch (call->unmarshall) {
1586         case 0:
1587                 call->unmarshall++;
1588                 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1589
1590                 /* Fall through - and extract the returned status record */
1591         case 1:
1592                 _debug("extract status");
1593                 ret = afs_extract_data(call, true);
1594                 if (ret < 0)
1595                         return ret;
1596
1597                 bp = call->buffer;
1598                 xdr_decode_YFSFetchVolumeStatus(&bp, call->reply[1]);
1599                 call->unmarshall++;
1600                 afs_extract_to_tmp(call);
1601
1602                 /* Fall through - and extract the volume name length */
1603         case 2:
1604                 ret = afs_extract_data(call, true);
1605                 if (ret < 0)
1606                         return ret;
1607
1608                 call->count = ntohl(call->tmp);
1609                 _debug("volname length: %u", call->count);
1610                 if (call->count >= AFSNAMEMAX)
1611                         return afs_protocol_error(call, -EBADMSG,
1612                                                   afs_eproto_volname_len);
1613                 size = (call->count + 3) & ~3; /* It's padded */
1614                 afs_extract_begin(call, call->reply[2], size);
1615                 call->unmarshall++;
1616
1617                 /* Fall through - and extract the volume name */
1618         case 3:
1619                 _debug("extract volname");
1620                 ret = afs_extract_data(call, true);
1621                 if (ret < 0)
1622                         return ret;
1623
1624                 p = call->reply[2];
1625                 p[call->count] = 0;
1626                 _debug("volname '%s'", p);
1627                 afs_extract_to_tmp(call);
1628                 call->unmarshall++;
1629
1630                 /* Fall through - and extract the offline message length */
1631         case 4:
1632                 ret = afs_extract_data(call, true);
1633                 if (ret < 0)
1634                         return ret;
1635
1636                 call->count = ntohl(call->tmp);
1637                 _debug("offline msg length: %u", call->count);
1638                 if (call->count >= AFSNAMEMAX)
1639                         return afs_protocol_error(call, -EBADMSG,
1640                                                   afs_eproto_offline_msg_len);
1641                 size = (call->count + 3) & ~3; /* It's padded */
1642                 afs_extract_begin(call, call->reply[2], size);
1643                 call->unmarshall++;
1644
1645                 /* Fall through - and extract the offline message */
1646         case 5:
1647                 _debug("extract offline");
1648                 ret = afs_extract_data(call, true);
1649                 if (ret < 0)
1650                         return ret;
1651
1652                 p = call->reply[2];
1653                 p[call->count] = 0;
1654                 _debug("offline '%s'", p);
1655
1656                 afs_extract_to_tmp(call);
1657                 call->unmarshall++;
1658
1659                 /* Fall through - and extract the message of the day length */
1660         case 6:
1661                 ret = afs_extract_data(call, true);
1662                 if (ret < 0)
1663                         return ret;
1664
1665                 call->count = ntohl(call->tmp);
1666                 _debug("motd length: %u", call->count);
1667                 if (call->count >= AFSNAMEMAX)
1668                         return afs_protocol_error(call, -EBADMSG,
1669                                                   afs_eproto_motd_len);
1670                 size = (call->count + 3) & ~3; /* It's padded */
1671                 afs_extract_begin(call, call->reply[2], size);
1672                 call->unmarshall++;
1673
1674                 /* Fall through - and extract the message of the day */
1675         case 7:
1676                 _debug("extract motd");
1677                 ret = afs_extract_data(call, false);
1678                 if (ret < 0)
1679                         return ret;
1680
1681                 p = call->reply[2];
1682                 p[call->count] = 0;
1683                 _debug("motd '%s'", p);
1684
1685                 call->unmarshall++;
1686
1687                 /* Fall through */
1688         case 8:
1689                 break;
1690         }
1691
1692         _leave(" = 0 [done]");
1693         return 0;
1694 }
1695
1696 /*
1697  * Destroy a YFS.GetVolumeStatus call.
1698  */
1699 static void yfs_get_volume_status_call_destructor(struct afs_call *call)
1700 {
1701         kfree(call->reply[2]);
1702         call->reply[2] = NULL;
1703         afs_flat_call_destructor(call);
1704 }
1705
1706 /*
1707  * YFS.GetVolumeStatus operation type
1708  */
1709 static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1710         .name           = "YFS.GetVolumeStatus",
1711         .op             = yfs_FS_GetVolumeStatus,
1712         .deliver        = yfs_deliver_fs_get_volume_status,
1713         .destructor     = yfs_get_volume_status_call_destructor,
1714 };
1715
1716 /*
1717  * fetch the status of a volume
1718  */
1719 int yfs_fs_get_volume_status(struct afs_fs_cursor *fc,
1720                              struct afs_volume_status *vs)
1721 {
1722         struct afs_vnode *vnode = fc->vnode;
1723         struct afs_call *call;
1724         struct afs_net *net = afs_v2net(vnode);
1725         __be32 *bp;
1726         void *tmpbuf;
1727
1728         _enter("");
1729
1730         tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1731         if (!tmpbuf)
1732                 return -ENOMEM;
1733
1734         call = afs_alloc_flat_call(net, &yfs_RXYFSGetVolumeStatus,
1735                                    sizeof(__be32) * 2 +
1736                                    sizeof(struct yfs_xdr_u64),
1737                                    sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1738                                    sizeof(__be32));
1739         if (!call) {
1740                 kfree(tmpbuf);
1741                 return -ENOMEM;
1742         }
1743
1744         call->key = fc->key;
1745         call->reply[0] = vnode;
1746         call->reply[1] = vs;
1747         call->reply[2] = tmpbuf;
1748
1749         /* marshall the parameters */
1750         bp = call->request;
1751         bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1752         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1753         bp = xdr_encode_u64(bp, vnode->fid.vid);
1754         yfs_check_req(call, bp);
1755
1756         afs_use_fs_server(call, fc->cbi);
1757         trace_afs_make_fs_call(call, &vnode->fid);
1758         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1759 }
1760
1761 /*
1762  * Deliver reply data to an YFS.SetLock, YFS.ExtendLock or YFS.ReleaseLock
1763  */
1764 static int yfs_deliver_fs_xxxx_lock(struct afs_call *call)
1765 {
1766         struct afs_vnode *vnode = call->reply[0];
1767         const __be32 *bp;
1768         int ret;
1769
1770         _enter("{%u}", call->unmarshall);
1771
1772         ret = afs_transfer_reply(call);
1773         if (ret < 0)
1774                 return ret;
1775
1776         /* unmarshall the reply once we've received all of it */
1777         bp = call->buffer;
1778         ret = yfs_decode_status(call, &bp, &vnode->status, vnode,
1779                                 &call->expected_version, NULL);
1780         if (ret < 0)
1781                 return ret;
1782         xdr_decode_YFSVolSync(&bp, NULL);
1783
1784         _leave(" = 0 [done]");
1785         return 0;
1786 }
1787
1788 /*
1789  * YFS.SetLock operation type
1790  */
1791 static const struct afs_call_type yfs_RXYFSSetLock = {
1792         .name           = "YFS.SetLock",
1793         .op             = yfs_FS_SetLock,
1794         .deliver        = yfs_deliver_fs_xxxx_lock,
1795         .destructor     = afs_flat_call_destructor,
1796 };
1797
1798 /*
1799  * YFS.ExtendLock operation type
1800  */
1801 static const struct afs_call_type yfs_RXYFSExtendLock = {
1802         .name           = "YFS.ExtendLock",
1803         .op             = yfs_FS_ExtendLock,
1804         .deliver        = yfs_deliver_fs_xxxx_lock,
1805         .destructor     = afs_flat_call_destructor,
1806 };
1807
1808 /*
1809  * YFS.ReleaseLock operation type
1810  */
1811 static const struct afs_call_type yfs_RXYFSReleaseLock = {
1812         .name           = "YFS.ReleaseLock",
1813         .op             = yfs_FS_ReleaseLock,
1814         .deliver        = yfs_deliver_fs_xxxx_lock,
1815         .destructor     = afs_flat_call_destructor,
1816 };
1817
1818 /*
1819  * Set a lock on a file
1820  */
1821 int yfs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1822 {
1823         struct afs_vnode *vnode = fc->vnode;
1824         struct afs_call *call;
1825         struct afs_net *net = afs_v2net(vnode);
1826         __be32 *bp;
1827
1828         _enter("");
1829
1830         call = afs_alloc_flat_call(net, &yfs_RXYFSSetLock,
1831                                    sizeof(__be32) * 2 +
1832                                    sizeof(struct yfs_xdr_YFSFid) +
1833                                    sizeof(__be32),
1834                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1835                                    sizeof(struct yfs_xdr_YFSVolSync));
1836         if (!call)
1837                 return -ENOMEM;
1838
1839         call->key = fc->key;
1840         call->reply[0] = vnode;
1841
1842         /* marshall the parameters */
1843         bp = call->request;
1844         bp = xdr_encode_u32(bp, YFSSETLOCK);
1845         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1846         bp = xdr_encode_YFSFid(bp, &vnode->fid);
1847         bp = xdr_encode_u32(bp, type);
1848         yfs_check_req(call, bp);
1849
1850         afs_use_fs_server(call, fc->cbi);
1851         trace_afs_make_fs_call(call, &vnode->fid);
1852         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1853 }
1854
1855 /*
1856  * extend a lock on a file
1857  */
1858 int yfs_fs_extend_lock(struct afs_fs_cursor *fc)
1859 {
1860         struct afs_vnode *vnode = fc->vnode;
1861         struct afs_call *call;
1862         struct afs_net *net = afs_v2net(vnode);
1863         __be32 *bp;
1864
1865         _enter("");
1866
1867         call = afs_alloc_flat_call(net, &yfs_RXYFSExtendLock,
1868                                    sizeof(__be32) * 2 +
1869                                    sizeof(struct yfs_xdr_YFSFid),
1870                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1871                                    sizeof(struct yfs_xdr_YFSVolSync));
1872         if (!call)
1873                 return -ENOMEM;
1874
1875         call->key = fc->key;
1876         call->reply[0] = vnode;
1877
1878         /* marshall the parameters */
1879         bp = call->request;
1880         bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1881         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1882         bp = xdr_encode_YFSFid(bp, &vnode->fid);
1883         yfs_check_req(call, bp);
1884
1885         afs_use_fs_server(call, fc->cbi);
1886         trace_afs_make_fs_call(call, &vnode->fid);
1887         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1888 }
1889
1890 /*
1891  * release a lock on a file
1892  */
1893 int yfs_fs_release_lock(struct afs_fs_cursor *fc)
1894 {
1895         struct afs_vnode *vnode = fc->vnode;
1896         struct afs_call *call;
1897         struct afs_net *net = afs_v2net(vnode);
1898         __be32 *bp;
1899
1900         _enter("");
1901
1902         call = afs_alloc_flat_call(net, &yfs_RXYFSReleaseLock,
1903                                    sizeof(__be32) * 2 +
1904                                    sizeof(struct yfs_xdr_YFSFid),
1905                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1906                                    sizeof(struct yfs_xdr_YFSVolSync));
1907         if (!call)
1908                 return -ENOMEM;
1909
1910         call->key = fc->key;
1911         call->reply[0] = vnode;
1912
1913         /* marshall the parameters */
1914         bp = call->request;
1915         bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1916         bp = xdr_encode_u32(bp, 0); /* RPC flags */
1917         bp = xdr_encode_YFSFid(bp, &vnode->fid);
1918         yfs_check_req(call, bp);
1919
1920         afs_use_fs_server(call, fc->cbi);
1921         trace_afs_make_fs_call(call, &vnode->fid);
1922         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1923 }
1924
1925 /*
1926  * Deliver reply data to an FS.FetchStatus with no vnode.
1927  */
1928 static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1929 {
1930         struct afs_file_status *status = call->reply[1];
1931         struct afs_callback *callback = call->reply[2];
1932         struct afs_volsync *volsync = call->reply[3];
1933         struct afs_vnode *vnode = call->reply[0];
1934         const __be32 *bp;
1935         int ret;
1936
1937         ret = afs_transfer_reply(call);
1938         if (ret < 0)
1939                 return ret;
1940
1941         _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
1942
1943         /* unmarshall the reply once we've received all of it */
1944         bp = call->buffer;
1945         ret = yfs_decode_status(call, &bp, status, vnode,
1946                                 &call->expected_version, NULL);
1947         if (ret < 0)
1948                 return ret;
1949         xdr_decode_YFSCallBack_raw(&bp, callback);
1950         xdr_decode_YFSVolSync(&bp, volsync);
1951
1952         _leave(" = 0 [done]");
1953         return 0;
1954 }
1955
1956 /*
1957  * YFS.FetchStatus operation type
1958  */
1959 static const struct afs_call_type yfs_RXYFSFetchStatus = {
1960         .name           = "YFS.FetchStatus",
1961         .op             = yfs_FS_FetchStatus,
1962         .deliver        = yfs_deliver_fs_fetch_status,
1963         .destructor     = afs_flat_call_destructor,
1964 };
1965
1966 /*
1967  * Fetch the status information for a fid without needing a vnode handle.
1968  */
1969 int yfs_fs_fetch_status(struct afs_fs_cursor *fc,
1970                         struct afs_net *net,
1971                         struct afs_fid *fid,
1972                         struct afs_file_status *status,
1973                         struct afs_callback *callback,
1974                         struct afs_volsync *volsync)
1975 {
1976         struct afs_call *call;
1977         __be32 *bp;
1978
1979         _enter(",%x,{%llx:%llu},,",
1980                key_serial(fc->key), fid->vid, fid->vnode);
1981
1982         call = afs_alloc_flat_call(net, &yfs_RXYFSFetchStatus,
1983                                    sizeof(__be32) * 2 +
1984                                    sizeof(struct yfs_xdr_YFSFid),
1985                                    sizeof(struct yfs_xdr_YFSFetchStatus) +
1986                                    sizeof(struct yfs_xdr_YFSCallBack) +
1987                                    sizeof(struct yfs_xdr_YFSVolSync));
1988         if (!call) {
1989                 fc->ac.error = -ENOMEM;
1990                 return -ENOMEM;
1991         }
1992
1993         call->key = fc->key;
1994         call->reply[0] = NULL; /* vnode for fid[0] */
1995         call->reply[1] = status;
1996         call->reply[2] = callback;
1997         call->reply[3] = volsync;
1998         call->expected_version = 1; /* vnode->status.data_version */
1999
2000         /* marshall the parameters */
2001         bp = call->request;
2002         bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
2003         bp = xdr_encode_u32(bp, 0); /* RPC flags */
2004         bp = xdr_encode_YFSFid(bp, fid);
2005         yfs_check_req(call, bp);
2006
2007         call->cb_break = fc->cb_break;
2008         afs_use_fs_server(call, fc->cbi);
2009         trace_afs_make_fs_call(call, fid);
2010         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2011 }
2012
2013 /*
2014  * Deliver reply data to an YFS.InlineBulkStatus call
2015  */
2016 static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
2017 {
2018         struct afs_file_status *statuses;
2019         struct afs_callback *callbacks;
2020         struct afs_vnode *vnode = call->reply[0];
2021         const __be32 *bp;
2022         u32 tmp;
2023         int ret;
2024
2025         _enter("{%u}", call->unmarshall);
2026
2027         switch (call->unmarshall) {
2028         case 0:
2029                 afs_extract_to_tmp(call);
2030                 call->unmarshall++;
2031
2032                 /* Extract the file status count and array in two steps */
2033                 /* Fall through */
2034         case 1:
2035                 _debug("extract status count");
2036                 ret = afs_extract_data(call, true);
2037                 if (ret < 0)
2038                         return ret;
2039
2040                 tmp = ntohl(call->tmp);
2041                 _debug("status count: %u/%u", tmp, call->count2);
2042                 if (tmp != call->count2)
2043                         return afs_protocol_error(call, -EBADMSG,
2044                                                   afs_eproto_ibulkst_count);
2045
2046                 call->count = 0;
2047                 call->unmarshall++;
2048         more_counts:
2049                 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
2050
2051                 /* Fall through */
2052         case 2:
2053                 _debug("extract status array %u", call->count);
2054                 ret = afs_extract_data(call, true);
2055                 if (ret < 0)
2056                         return ret;
2057
2058                 bp = call->buffer;
2059                 statuses = call->reply[1];
2060                 ret = yfs_decode_status(call, &bp, &statuses[call->count],
2061                                         call->count == 0 ? vnode : NULL,
2062                                         NULL, NULL);
2063                 if (ret < 0)
2064                         return ret;
2065
2066                 call->count++;
2067                 if (call->count < call->count2)
2068                         goto more_counts;
2069
2070                 call->count = 0;
2071                 call->unmarshall++;
2072                 afs_extract_to_tmp(call);
2073
2074                 /* Extract the callback count and array in two steps */
2075                 /* Fall through */
2076         case 3:
2077                 _debug("extract CB count");
2078                 ret = afs_extract_data(call, true);
2079                 if (ret < 0)
2080                         return ret;
2081
2082                 tmp = ntohl(call->tmp);
2083                 _debug("CB count: %u", tmp);
2084                 if (tmp != call->count2)
2085                         return afs_protocol_error(call, -EBADMSG,
2086                                                   afs_eproto_ibulkst_cb_count);
2087                 call->count = 0;
2088                 call->unmarshall++;
2089         more_cbs:
2090                 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
2091
2092                 /* Fall through */
2093         case 4:
2094                 _debug("extract CB array");
2095                 ret = afs_extract_data(call, true);
2096                 if (ret < 0)
2097                         return ret;
2098
2099                 _debug("unmarshall CB array");
2100                 bp = call->buffer;
2101                 callbacks = call->reply[2];
2102                 xdr_decode_YFSCallBack_raw(&bp, &callbacks[call->count]);
2103                 statuses = call->reply[1];
2104                 if (call->count == 0 && vnode && statuses[0].abort_code == 0) {
2105                         bp = call->buffer;
2106                         xdr_decode_YFSCallBack(call, vnode, &bp);
2107                 }
2108                 call->count++;
2109                 if (call->count < call->count2)
2110                         goto more_cbs;
2111
2112                 afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
2113                 call->unmarshall++;
2114
2115                 /* Fall through */
2116         case 5:
2117                 ret = afs_extract_data(call, false);
2118                 if (ret < 0)
2119                         return ret;
2120
2121                 bp = call->buffer;
2122                 xdr_decode_YFSVolSync(&bp, call->reply[3]);
2123
2124                 call->unmarshall++;
2125
2126                 /* Fall through */
2127         case 6:
2128                 break;
2129         }
2130
2131         _leave(" = 0 [done]");
2132         return 0;
2133 }
2134
2135 /*
2136  * FS.InlineBulkStatus operation type
2137  */
2138 static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
2139         .name           = "YFS.InlineBulkStatus",
2140         .op             = yfs_FS_InlineBulkStatus,
2141         .deliver        = yfs_deliver_fs_inline_bulk_status,
2142         .destructor     = afs_flat_call_destructor,
2143 };
2144
2145 /*
2146  * Fetch the status information for up to 1024 files
2147  */
2148 int yfs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2149                               struct afs_net *net,
2150                               struct afs_fid *fids,
2151                               struct afs_file_status *statuses,
2152                               struct afs_callback *callbacks,
2153                               unsigned int nr_fids,
2154                               struct afs_volsync *volsync)
2155 {
2156         struct afs_call *call;
2157         __be32 *bp;
2158         int i;
2159
2160         _enter(",%x,{%llx:%llu},%u",
2161                key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2162
2163         call = afs_alloc_flat_call(net, &yfs_RXYFSInlineBulkStatus,
2164                                    sizeof(__be32) +
2165                                    sizeof(__be32) +
2166                                    sizeof(__be32) +
2167                                    sizeof(struct yfs_xdr_YFSFid) * nr_fids,
2168                                    sizeof(struct yfs_xdr_YFSFetchStatus));
2169         if (!call) {
2170                 fc->ac.error = -ENOMEM;
2171                 return -ENOMEM;
2172         }
2173
2174         call->key = fc->key;
2175         call->reply[0] = NULL; /* vnode for fid[0] */
2176         call->reply[1] = statuses;
2177         call->reply[2] = callbacks;
2178         call->reply[3] = volsync;
2179         call->count2 = nr_fids;
2180
2181         /* marshall the parameters */
2182         bp = call->request;
2183         bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
2184         bp = xdr_encode_u32(bp, 0); /* RPCFlags */
2185         bp = xdr_encode_u32(bp, nr_fids);
2186         for (i = 0; i < nr_fids; i++)
2187                 bp = xdr_encode_YFSFid(bp, &fids[i]);
2188         yfs_check_req(call, bp);
2189
2190         call->cb_break = fc->cb_break;
2191         afs_use_fs_server(call, fc->cbi);
2192         trace_afs_make_fs_call(call, &fids[0]);
2193         return afs_make_call(&fc->ac, call, GFP_NOFS, false);
2194 }