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