]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/afs/fsclient.c
net: qcom/emac: display the phy driver info after we connect
[karo-tx-linux.git] / fs / afs / fsclient.c
1 /* AFS File Server client stubs
2  *
3  * Copyright (C) 2002, 2007 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 License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, 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 "internal.h"
17 #include "afs_fs.h"
18
19 /*
20  * decode an AFSFid block
21  */
22 static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
23 {
24         const __be32 *bp = *_bp;
25
26         fid->vid                = ntohl(*bp++);
27         fid->vnode              = ntohl(*bp++);
28         fid->unique             = ntohl(*bp++);
29         *_bp = bp;
30 }
31
32 /*
33  * decode an AFSFetchStatus block
34  */
35 static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
36                                       struct afs_file_status *status,
37                                       struct afs_vnode *vnode,
38                                       afs_dataversion_t *store_version)
39 {
40         afs_dataversion_t expected_version;
41         const __be32 *bp = *_bp;
42         umode_t mode;
43         u64 data_version, size;
44         u32 changed = 0; /* becomes non-zero if ctime-type changes seen */
45         kuid_t owner;
46         kgid_t group;
47
48 #define EXTRACT(DST)                            \
49         do {                                    \
50                 u32 x = ntohl(*bp++);           \
51                 changed |= DST - x;             \
52                 DST = x;                        \
53         } while (0)
54
55         status->if_version = ntohl(*bp++);
56         EXTRACT(status->type);
57         EXTRACT(status->nlink);
58         size = ntohl(*bp++);
59         data_version = ntohl(*bp++);
60         EXTRACT(status->author);
61         owner = make_kuid(&init_user_ns, ntohl(*bp++));
62         changed |= !uid_eq(owner, status->owner);
63         status->owner = owner;
64         EXTRACT(status->caller_access); /* call ticket dependent */
65         EXTRACT(status->anon_access);
66         EXTRACT(status->mode);
67         EXTRACT(status->parent.vnode);
68         EXTRACT(status->parent.unique);
69         bp++; /* seg size */
70         status->mtime_client = ntohl(*bp++);
71         status->mtime_server = ntohl(*bp++);
72         group = make_kgid(&init_user_ns, ntohl(*bp++));
73         changed |= !gid_eq(group, status->group);
74         status->group = group;
75         bp++; /* sync counter */
76         data_version |= (u64) ntohl(*bp++) << 32;
77         EXTRACT(status->lock_count);
78         size |= (u64) ntohl(*bp++) << 32;
79         bp++; /* spare 4 */
80         *_bp = bp;
81
82         if (size != status->size) {
83                 status->size = size;
84                 changed |= true;
85         }
86         status->mode &= S_IALLUGO;
87
88         _debug("vnode time %lx, %lx",
89                status->mtime_client, status->mtime_server);
90
91         if (vnode) {
92                 status->parent.vid = vnode->fid.vid;
93                 if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
94                         _debug("vnode changed");
95                         i_size_write(&vnode->vfs_inode, size);
96                         vnode->vfs_inode.i_uid = status->owner;
97                         vnode->vfs_inode.i_gid = status->group;
98                         vnode->vfs_inode.i_generation = vnode->fid.unique;
99                         set_nlink(&vnode->vfs_inode, status->nlink);
100
101                         mode = vnode->vfs_inode.i_mode;
102                         mode &= ~S_IALLUGO;
103                         mode |= status->mode;
104                         barrier();
105                         vnode->vfs_inode.i_mode = mode;
106                 }
107
108                 vnode->vfs_inode.i_ctime.tv_sec = status->mtime_server;
109                 vnode->vfs_inode.i_mtime        = vnode->vfs_inode.i_ctime;
110                 vnode->vfs_inode.i_atime        = vnode->vfs_inode.i_ctime;
111                 vnode->vfs_inode.i_version      = data_version;
112         }
113
114         expected_version = status->data_version;
115         if (store_version)
116                 expected_version = *store_version;
117
118         if (expected_version != data_version) {
119                 status->data_version = data_version;
120                 if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
121                         _debug("vnode modified %llx on {%x:%u}",
122                                (unsigned long long) data_version,
123                                vnode->fid.vid, vnode->fid.vnode);
124                         set_bit(AFS_VNODE_MODIFIED, &vnode->flags);
125                         set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
126                 }
127         } else if (store_version) {
128                 status->data_version = data_version;
129         }
130 }
131
132 /*
133  * decode an AFSCallBack block
134  */
135 static void xdr_decode_AFSCallBack(const __be32 **_bp, struct afs_vnode *vnode)
136 {
137         const __be32 *bp = *_bp;
138
139         vnode->cb_version       = ntohl(*bp++);
140         vnode->cb_expiry        = ntohl(*bp++);
141         vnode->cb_type          = ntohl(*bp++);
142         vnode->cb_expires       = vnode->cb_expiry + get_seconds();
143         *_bp = bp;
144 }
145
146 static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
147                                        struct afs_callback *cb)
148 {
149         const __be32 *bp = *_bp;
150
151         cb->version     = ntohl(*bp++);
152         cb->expiry      = ntohl(*bp++);
153         cb->type        = ntohl(*bp++);
154         *_bp = bp;
155 }
156
157 /*
158  * decode an AFSVolSync block
159  */
160 static void xdr_decode_AFSVolSync(const __be32 **_bp,
161                                   struct afs_volsync *volsync)
162 {
163         const __be32 *bp = *_bp;
164
165         volsync->creation = ntohl(*bp++);
166         bp++; /* spare2 */
167         bp++; /* spare3 */
168         bp++; /* spare4 */
169         bp++; /* spare5 */
170         bp++; /* spare6 */
171         *_bp = bp;
172 }
173
174 /*
175  * encode the requested attributes into an AFSStoreStatus block
176  */
177 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
178 {
179         __be32 *bp = *_bp;
180         u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
181
182         mask = 0;
183         if (attr->ia_valid & ATTR_MTIME) {
184                 mask |= AFS_SET_MTIME;
185                 mtime = attr->ia_mtime.tv_sec;
186         }
187
188         if (attr->ia_valid & ATTR_UID) {
189                 mask |= AFS_SET_OWNER;
190                 owner = from_kuid(&init_user_ns, attr->ia_uid);
191         }
192
193         if (attr->ia_valid & ATTR_GID) {
194                 mask |= AFS_SET_GROUP;
195                 group = from_kgid(&init_user_ns, attr->ia_gid);
196         }
197
198         if (attr->ia_valid & ATTR_MODE) {
199                 mask |= AFS_SET_MODE;
200                 mode = attr->ia_mode & S_IALLUGO;
201         }
202
203         *bp++ = htonl(mask);
204         *bp++ = htonl(mtime);
205         *bp++ = htonl(owner);
206         *bp++ = htonl(group);
207         *bp++ = htonl(mode);
208         *bp++ = 0;              /* segment size */
209         *_bp = bp;
210 }
211
212 /*
213  * decode an AFSFetchVolumeStatus block
214  */
215 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
216                                             struct afs_volume_status *vs)
217 {
218         const __be32 *bp = *_bp;
219
220         vs->vid                 = ntohl(*bp++);
221         vs->parent_id           = ntohl(*bp++);
222         vs->online              = ntohl(*bp++);
223         vs->in_service          = ntohl(*bp++);
224         vs->blessed             = ntohl(*bp++);
225         vs->needs_salvage       = ntohl(*bp++);
226         vs->type                = ntohl(*bp++);
227         vs->min_quota           = ntohl(*bp++);
228         vs->max_quota           = ntohl(*bp++);
229         vs->blocks_in_use       = ntohl(*bp++);
230         vs->part_blocks_avail   = ntohl(*bp++);
231         vs->part_max_blocks     = ntohl(*bp++);
232         *_bp = bp;
233 }
234
235 /*
236  * deliver reply data to an FS.FetchStatus
237  */
238 static int afs_deliver_fs_fetch_status(struct afs_call *call)
239 {
240         struct afs_vnode *vnode = call->reply;
241         const __be32 *bp;
242         int ret;
243
244         _enter("");
245
246         ret = afs_transfer_reply(call);
247         if (ret < 0)
248                 return ret;
249
250         /* unmarshall the reply once we've received all of it */
251         bp = call->buffer;
252         xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
253         xdr_decode_AFSCallBack(&bp, vnode);
254         if (call->reply2)
255                 xdr_decode_AFSVolSync(&bp, call->reply2);
256
257         _leave(" = 0 [done]");
258         return 0;
259 }
260
261 /*
262  * FS.FetchStatus operation type
263  */
264 static const struct afs_call_type afs_RXFSFetchStatus = {
265         .name           = "FS.FetchStatus",
266         .deliver        = afs_deliver_fs_fetch_status,
267         .abort_to_error = afs_abort_to_error,
268         .destructor     = afs_flat_call_destructor,
269 };
270
271 /*
272  * fetch the status information for a file
273  */
274 int afs_fs_fetch_file_status(struct afs_server *server,
275                              struct key *key,
276                              struct afs_vnode *vnode,
277                              struct afs_volsync *volsync,
278                              bool async)
279 {
280         struct afs_call *call;
281         __be32 *bp;
282
283         _enter(",%x,{%x:%u},,",
284                key_serial(key), vnode->fid.vid, vnode->fid.vnode);
285
286         call = afs_alloc_flat_call(&afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
287         if (!call)
288                 return -ENOMEM;
289
290         call->key = key;
291         call->reply = vnode;
292         call->reply2 = volsync;
293         call->service_id = FS_SERVICE;
294         call->port = htons(AFS_FS_PORT);
295
296         /* marshall the parameters */
297         bp = call->request;
298         bp[0] = htonl(FSFETCHSTATUS);
299         bp[1] = htonl(vnode->fid.vid);
300         bp[2] = htonl(vnode->fid.vnode);
301         bp[3] = htonl(vnode->fid.unique);
302
303         return afs_make_call(&server->addr, call, GFP_NOFS, async);
304 }
305
306 /*
307  * deliver reply data to an FS.FetchData
308  */
309 static int afs_deliver_fs_fetch_data(struct afs_call *call)
310 {
311         struct afs_vnode *vnode = call->reply;
312         struct afs_read *req = call->reply3;
313         const __be32 *bp;
314         unsigned int size;
315         void *buffer;
316         int ret;
317
318         _enter("{%u,%zu/%u;%u/%llu}",
319                call->unmarshall, call->offset, call->count,
320                req->remain, req->actual_len);
321
322         switch (call->unmarshall) {
323         case 0:
324                 req->actual_len = 0;
325                 call->offset = 0;
326                 call->unmarshall++;
327                 if (call->operation_ID != FSFETCHDATA64) {
328                         call->unmarshall++;
329                         goto no_msw;
330                 }
331
332                 /* extract the upper part of the returned data length of an
333                  * FSFETCHDATA64 op (which should always be 0 using this
334                  * client) */
335         case 1:
336                 _debug("extract data length (MSW)");
337                 ret = afs_extract_data(call, &call->tmp, 4, true);
338                 if (ret < 0)
339                         return ret;
340
341                 req->actual_len = ntohl(call->tmp);
342                 req->actual_len <<= 32;
343                 call->offset = 0;
344                 call->unmarshall++;
345
346         no_msw:
347                 /* extract the returned data length */
348         case 2:
349                 _debug("extract data length");
350                 ret = afs_extract_data(call, &call->tmp, 4, true);
351                 if (ret < 0)
352                         return ret;
353
354                 req->actual_len |= ntohl(call->tmp);
355                 _debug("DATA length: %llu", req->actual_len);
356                 /* Check that the server didn't want to send us extra.  We
357                  * might want to just discard instead, but that requires
358                  * cooperation from AF_RXRPC.
359                  */
360                 if (req->actual_len > req->len)
361                         return -EBADMSG;
362
363                 req->remain = req->actual_len;
364                 call->offset = req->pos & (PAGE_SIZE - 1);
365                 req->index = 0;
366                 if (req->actual_len == 0)
367                         goto no_more_data;
368                 call->unmarshall++;
369
370         begin_page:
371                 if (req->remain > PAGE_SIZE - call->offset)
372                         size = PAGE_SIZE - call->offset;
373                 else
374                         size = req->remain;
375                 call->count = call->offset + size;
376                 ASSERTCMP(call->count, <=, PAGE_SIZE);
377                 req->remain -= size;
378
379                 /* extract the returned data */
380         case 3:
381                 _debug("extract data %u/%llu %zu/%u",
382                        req->remain, req->actual_len, call->offset, call->count);
383
384                 buffer = kmap(req->pages[req->index]);
385                 ret = afs_extract_data(call, buffer, call->count, true);
386                 kunmap(req->pages[req->index]);
387                 if (ret < 0)
388                         return ret;
389                 if (call->offset == PAGE_SIZE) {
390                         if (req->page_done)
391                                 req->page_done(call, req);
392                         if (req->remain > 0) {
393                                 req->index++;
394                                 call->offset = 0;
395                                 goto begin_page;
396                         }
397                 }
398
399         no_more_data:
400                 call->offset = 0;
401                 call->unmarshall++;
402
403                 /* extract the metadata */
404         case 4:
405                 ret = afs_extract_data(call, call->buffer,
406                                        (21 + 3 + 6) * 4, false);
407                 if (ret < 0)
408                         return ret;
409
410                 bp = call->buffer;
411                 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
412                 xdr_decode_AFSCallBack(&bp, vnode);
413                 if (call->reply2)
414                         xdr_decode_AFSVolSync(&bp, call->reply2);
415
416                 call->offset = 0;
417                 call->unmarshall++;
418
419         case 5:
420                 break;
421         }
422
423         if (call->count < PAGE_SIZE) {
424                 buffer = kmap(req->pages[req->index]);
425                 memset(buffer + call->count, 0, PAGE_SIZE - call->count);
426                 kunmap(req->pages[req->index]);
427                 if (req->page_done)
428                         req->page_done(call, req);
429         }
430
431         _leave(" = 0 [done]");
432         return 0;
433 }
434
435 static void afs_fetch_data_destructor(struct afs_call *call)
436 {
437         struct afs_read *req = call->reply3;
438
439         afs_put_read(req);
440         afs_flat_call_destructor(call);
441 }
442
443 /*
444  * FS.FetchData operation type
445  */
446 static const struct afs_call_type afs_RXFSFetchData = {
447         .name           = "FS.FetchData",
448         .deliver        = afs_deliver_fs_fetch_data,
449         .abort_to_error = afs_abort_to_error,
450         .destructor     = afs_fetch_data_destructor,
451 };
452
453 static const struct afs_call_type afs_RXFSFetchData64 = {
454         .name           = "FS.FetchData64",
455         .deliver        = afs_deliver_fs_fetch_data,
456         .abort_to_error = afs_abort_to_error,
457         .destructor     = afs_fetch_data_destructor,
458 };
459
460 /*
461  * fetch data from a very large file
462  */
463 static int afs_fs_fetch_data64(struct afs_server *server,
464                                struct key *key,
465                                struct afs_vnode *vnode,
466                                struct afs_read *req,
467                                bool async)
468 {
469         struct afs_call *call;
470         __be32 *bp;
471
472         _enter("");
473
474         call = afs_alloc_flat_call(&afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
475         if (!call)
476                 return -ENOMEM;
477
478         call->key = key;
479         call->reply = vnode;
480         call->reply2 = NULL; /* volsync */
481         call->reply3 = req;
482         call->service_id = FS_SERVICE;
483         call->port = htons(AFS_FS_PORT);
484         call->operation_ID = FSFETCHDATA64;
485
486         /* marshall the parameters */
487         bp = call->request;
488         bp[0] = htonl(FSFETCHDATA64);
489         bp[1] = htonl(vnode->fid.vid);
490         bp[2] = htonl(vnode->fid.vnode);
491         bp[3] = htonl(vnode->fid.unique);
492         bp[4] = htonl(upper_32_bits(req->pos));
493         bp[5] = htonl(lower_32_bits(req->pos));
494         bp[6] = 0;
495         bp[7] = htonl(lower_32_bits(req->len));
496
497         atomic_inc(&req->usage);
498         return afs_make_call(&server->addr, call, GFP_NOFS, async);
499 }
500
501 /*
502  * fetch data from a file
503  */
504 int afs_fs_fetch_data(struct afs_server *server,
505                       struct key *key,
506                       struct afs_vnode *vnode,
507                       struct afs_read *req,
508                       bool async)
509 {
510         struct afs_call *call;
511         __be32 *bp;
512
513         if (upper_32_bits(req->pos) ||
514             upper_32_bits(req->len) ||
515             upper_32_bits(req->pos + req->len))
516                 return afs_fs_fetch_data64(server, key, vnode, req, async);
517
518         _enter("");
519
520         call = afs_alloc_flat_call(&afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
521         if (!call)
522                 return -ENOMEM;
523
524         call->key = key;
525         call->reply = vnode;
526         call->reply2 = NULL; /* volsync */
527         call->reply3 = req;
528         call->service_id = FS_SERVICE;
529         call->port = htons(AFS_FS_PORT);
530         call->operation_ID = FSFETCHDATA;
531
532         /* marshall the parameters */
533         bp = call->request;
534         bp[0] = htonl(FSFETCHDATA);
535         bp[1] = htonl(vnode->fid.vid);
536         bp[2] = htonl(vnode->fid.vnode);
537         bp[3] = htonl(vnode->fid.unique);
538         bp[4] = htonl(lower_32_bits(req->pos));
539         bp[5] = htonl(lower_32_bits(req->len));
540
541         atomic_inc(&req->usage);
542         return afs_make_call(&server->addr, call, GFP_NOFS, async);
543 }
544
545 /*
546  * deliver reply data to an FS.GiveUpCallBacks
547  */
548 static int afs_deliver_fs_give_up_callbacks(struct afs_call *call)
549 {
550         _enter("");
551
552         /* shouldn't be any reply data */
553         return afs_extract_data(call, NULL, 0, false);
554 }
555
556 /*
557  * FS.GiveUpCallBacks operation type
558  */
559 static const struct afs_call_type afs_RXFSGiveUpCallBacks = {
560         .name           = "FS.GiveUpCallBacks",
561         .deliver        = afs_deliver_fs_give_up_callbacks,
562         .abort_to_error = afs_abort_to_error,
563         .destructor     = afs_flat_call_destructor,
564 };
565
566 /*
567  * give up a set of callbacks
568  * - the callbacks are held in the server->cb_break ring
569  */
570 int afs_fs_give_up_callbacks(struct afs_server *server,
571                              bool async)
572 {
573         struct afs_call *call;
574         size_t ncallbacks;
575         __be32 *bp, *tp;
576         int loop;
577
578         ncallbacks = CIRC_CNT(server->cb_break_head, server->cb_break_tail,
579                               ARRAY_SIZE(server->cb_break));
580
581         _enter("{%zu},", ncallbacks);
582
583         if (ncallbacks == 0)
584                 return 0;
585         if (ncallbacks > AFSCBMAX)
586                 ncallbacks = AFSCBMAX;
587
588         _debug("break %zu callbacks", ncallbacks);
589
590         call = afs_alloc_flat_call(&afs_RXFSGiveUpCallBacks,
591                                    12 + ncallbacks * 6 * 4, 0);
592         if (!call)
593                 return -ENOMEM;
594
595         call->service_id = FS_SERVICE;
596         call->port = htons(AFS_FS_PORT);
597
598         /* marshall the parameters */
599         bp = call->request;
600         tp = bp + 2 + ncallbacks * 3;
601         *bp++ = htonl(FSGIVEUPCALLBACKS);
602         *bp++ = htonl(ncallbacks);
603         *tp++ = htonl(ncallbacks);
604
605         atomic_sub(ncallbacks, &server->cb_break_n);
606         for (loop = ncallbacks; loop > 0; loop--) {
607                 struct afs_callback *cb =
608                         &server->cb_break[server->cb_break_tail];
609
610                 *bp++ = htonl(cb->fid.vid);
611                 *bp++ = htonl(cb->fid.vnode);
612                 *bp++ = htonl(cb->fid.unique);
613                 *tp++ = htonl(cb->version);
614                 *tp++ = htonl(cb->expiry);
615                 *tp++ = htonl(cb->type);
616                 smp_mb();
617                 server->cb_break_tail =
618                         (server->cb_break_tail + 1) &
619                         (ARRAY_SIZE(server->cb_break) - 1);
620         }
621
622         ASSERT(ncallbacks > 0);
623         wake_up_nr(&server->cb_break_waitq, ncallbacks);
624
625         return afs_make_call(&server->addr, call, GFP_NOFS, async);
626 }
627
628 /*
629  * deliver reply data to an FS.CreateFile or an FS.MakeDir
630  */
631 static int afs_deliver_fs_create_vnode(struct afs_call *call)
632 {
633         struct afs_vnode *vnode = call->reply;
634         const __be32 *bp;
635         int ret;
636
637         _enter("{%u}", call->unmarshall);
638
639         ret = afs_transfer_reply(call);
640         if (ret < 0)
641                 return ret;
642
643         /* unmarshall the reply once we've received all of it */
644         bp = call->buffer;
645         xdr_decode_AFSFid(&bp, call->reply2);
646         xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
647         xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
648         xdr_decode_AFSCallBack_raw(&bp, call->reply4);
649         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
650
651         _leave(" = 0 [done]");
652         return 0;
653 }
654
655 /*
656  * FS.CreateFile and FS.MakeDir operation type
657  */
658 static const struct afs_call_type afs_RXFSCreateXXXX = {
659         .name           = "FS.CreateXXXX",
660         .deliver        = afs_deliver_fs_create_vnode,
661         .abort_to_error = afs_abort_to_error,
662         .destructor     = afs_flat_call_destructor,
663 };
664
665 /*
666  * create a file or make a directory
667  */
668 int afs_fs_create(struct afs_server *server,
669                   struct key *key,
670                   struct afs_vnode *vnode,
671                   const char *name,
672                   umode_t mode,
673                   struct afs_fid *newfid,
674                   struct afs_file_status *newstatus,
675                   struct afs_callback *newcb,
676                   bool async)
677 {
678         struct afs_call *call;
679         size_t namesz, reqsz, padsz;
680         __be32 *bp;
681
682         _enter("");
683
684         namesz = strlen(name);
685         padsz = (4 - (namesz & 3)) & 3;
686         reqsz = (5 * 4) + namesz + padsz + (6 * 4);
687
688         call = afs_alloc_flat_call(&afs_RXFSCreateXXXX, reqsz,
689                                    (3 + 21 + 21 + 3 + 6) * 4);
690         if (!call)
691                 return -ENOMEM;
692
693         call->key = key;
694         call->reply = vnode;
695         call->reply2 = newfid;
696         call->reply3 = newstatus;
697         call->reply4 = newcb;
698         call->service_id = FS_SERVICE;
699         call->port = htons(AFS_FS_PORT);
700
701         /* marshall the parameters */
702         bp = call->request;
703         *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
704         *bp++ = htonl(vnode->fid.vid);
705         *bp++ = htonl(vnode->fid.vnode);
706         *bp++ = htonl(vnode->fid.unique);
707         *bp++ = htonl(namesz);
708         memcpy(bp, name, namesz);
709         bp = (void *) bp + namesz;
710         if (padsz > 0) {
711                 memset(bp, 0, padsz);
712                 bp = (void *) bp + padsz;
713         }
714         *bp++ = htonl(AFS_SET_MODE);
715         *bp++ = 0; /* mtime */
716         *bp++ = 0; /* owner */
717         *bp++ = 0; /* group */
718         *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
719         *bp++ = 0; /* segment size */
720
721         return afs_make_call(&server->addr, call, GFP_NOFS, async);
722 }
723
724 /*
725  * deliver reply data to an FS.RemoveFile or FS.RemoveDir
726  */
727 static int afs_deliver_fs_remove(struct afs_call *call)
728 {
729         struct afs_vnode *vnode = call->reply;
730         const __be32 *bp;
731         int ret;
732
733         _enter("{%u}", call->unmarshall);
734
735         ret = afs_transfer_reply(call);
736         if (ret < 0)
737                 return ret;
738
739         /* unmarshall the reply once we've received all of it */
740         bp = call->buffer;
741         xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
742         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
743
744         _leave(" = 0 [done]");
745         return 0;
746 }
747
748 /*
749  * FS.RemoveDir/FS.RemoveFile operation type
750  */
751 static const struct afs_call_type afs_RXFSRemoveXXXX = {
752         .name           = "FS.RemoveXXXX",
753         .deliver        = afs_deliver_fs_remove,
754         .abort_to_error = afs_abort_to_error,
755         .destructor     = afs_flat_call_destructor,
756 };
757
758 /*
759  * remove a file or directory
760  */
761 int afs_fs_remove(struct afs_server *server,
762                   struct key *key,
763                   struct afs_vnode *vnode,
764                   const char *name,
765                   bool isdir,
766                   bool async)
767 {
768         struct afs_call *call;
769         size_t namesz, reqsz, padsz;
770         __be32 *bp;
771
772         _enter("");
773
774         namesz = strlen(name);
775         padsz = (4 - (namesz & 3)) & 3;
776         reqsz = (5 * 4) + namesz + padsz;
777
778         call = afs_alloc_flat_call(&afs_RXFSRemoveXXXX, reqsz, (21 + 6) * 4);
779         if (!call)
780                 return -ENOMEM;
781
782         call->key = key;
783         call->reply = vnode;
784         call->service_id = FS_SERVICE;
785         call->port = htons(AFS_FS_PORT);
786
787         /* marshall the parameters */
788         bp = call->request;
789         *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
790         *bp++ = htonl(vnode->fid.vid);
791         *bp++ = htonl(vnode->fid.vnode);
792         *bp++ = htonl(vnode->fid.unique);
793         *bp++ = htonl(namesz);
794         memcpy(bp, name, namesz);
795         bp = (void *) bp + namesz;
796         if (padsz > 0) {
797                 memset(bp, 0, padsz);
798                 bp = (void *) bp + padsz;
799         }
800
801         return afs_make_call(&server->addr, call, GFP_NOFS, async);
802 }
803
804 /*
805  * deliver reply data to an FS.Link
806  */
807 static int afs_deliver_fs_link(struct afs_call *call)
808 {
809         struct afs_vnode *dvnode = call->reply, *vnode = call->reply2;
810         const __be32 *bp;
811         int ret;
812
813         _enter("{%u}", call->unmarshall);
814
815         ret = afs_transfer_reply(call);
816         if (ret < 0)
817                 return ret;
818
819         /* unmarshall the reply once we've received all of it */
820         bp = call->buffer;
821         xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
822         xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
823         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
824
825         _leave(" = 0 [done]");
826         return 0;
827 }
828
829 /*
830  * FS.Link operation type
831  */
832 static const struct afs_call_type afs_RXFSLink = {
833         .name           = "FS.Link",
834         .deliver        = afs_deliver_fs_link,
835         .abort_to_error = afs_abort_to_error,
836         .destructor     = afs_flat_call_destructor,
837 };
838
839 /*
840  * make a hard link
841  */
842 int afs_fs_link(struct afs_server *server,
843                 struct key *key,
844                 struct afs_vnode *dvnode,
845                 struct afs_vnode *vnode,
846                 const char *name,
847                 bool async)
848 {
849         struct afs_call *call;
850         size_t namesz, reqsz, padsz;
851         __be32 *bp;
852
853         _enter("");
854
855         namesz = strlen(name);
856         padsz = (4 - (namesz & 3)) & 3;
857         reqsz = (5 * 4) + namesz + padsz + (3 * 4);
858
859         call = afs_alloc_flat_call(&afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
860         if (!call)
861                 return -ENOMEM;
862
863         call->key = key;
864         call->reply = dvnode;
865         call->reply2 = vnode;
866         call->service_id = FS_SERVICE;
867         call->port = htons(AFS_FS_PORT);
868
869         /* marshall the parameters */
870         bp = call->request;
871         *bp++ = htonl(FSLINK);
872         *bp++ = htonl(dvnode->fid.vid);
873         *bp++ = htonl(dvnode->fid.vnode);
874         *bp++ = htonl(dvnode->fid.unique);
875         *bp++ = htonl(namesz);
876         memcpy(bp, name, namesz);
877         bp = (void *) bp + namesz;
878         if (padsz > 0) {
879                 memset(bp, 0, padsz);
880                 bp = (void *) bp + padsz;
881         }
882         *bp++ = htonl(vnode->fid.vid);
883         *bp++ = htonl(vnode->fid.vnode);
884         *bp++ = htonl(vnode->fid.unique);
885
886         return afs_make_call(&server->addr, call, GFP_NOFS, async);
887 }
888
889 /*
890  * deliver reply data to an FS.Symlink
891  */
892 static int afs_deliver_fs_symlink(struct afs_call *call)
893 {
894         struct afs_vnode *vnode = call->reply;
895         const __be32 *bp;
896         int ret;
897
898         _enter("{%u}", call->unmarshall);
899
900         ret = afs_transfer_reply(call);
901         if (ret < 0)
902                 return ret;
903
904         /* unmarshall the reply once we've received all of it */
905         bp = call->buffer;
906         xdr_decode_AFSFid(&bp, call->reply2);
907         xdr_decode_AFSFetchStatus(&bp, call->reply3, NULL, NULL);
908         xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
909         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
910
911         _leave(" = 0 [done]");
912         return 0;
913 }
914
915 /*
916  * FS.Symlink operation type
917  */
918 static const struct afs_call_type afs_RXFSSymlink = {
919         .name           = "FS.Symlink",
920         .deliver        = afs_deliver_fs_symlink,
921         .abort_to_error = afs_abort_to_error,
922         .destructor     = afs_flat_call_destructor,
923 };
924
925 /*
926  * create a symbolic link
927  */
928 int afs_fs_symlink(struct afs_server *server,
929                    struct key *key,
930                    struct afs_vnode *vnode,
931                    const char *name,
932                    const char *contents,
933                    struct afs_fid *newfid,
934                    struct afs_file_status *newstatus,
935                    bool async)
936 {
937         struct afs_call *call;
938         size_t namesz, reqsz, padsz, c_namesz, c_padsz;
939         __be32 *bp;
940
941         _enter("");
942
943         namesz = strlen(name);
944         padsz = (4 - (namesz & 3)) & 3;
945
946         c_namesz = strlen(contents);
947         c_padsz = (4 - (c_namesz & 3)) & 3;
948
949         reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
950
951         call = afs_alloc_flat_call(&afs_RXFSSymlink, reqsz,
952                                    (3 + 21 + 21 + 6) * 4);
953         if (!call)
954                 return -ENOMEM;
955
956         call->key = key;
957         call->reply = vnode;
958         call->reply2 = newfid;
959         call->reply3 = newstatus;
960         call->service_id = FS_SERVICE;
961         call->port = htons(AFS_FS_PORT);
962
963         /* marshall the parameters */
964         bp = call->request;
965         *bp++ = htonl(FSSYMLINK);
966         *bp++ = htonl(vnode->fid.vid);
967         *bp++ = htonl(vnode->fid.vnode);
968         *bp++ = htonl(vnode->fid.unique);
969         *bp++ = htonl(namesz);
970         memcpy(bp, name, namesz);
971         bp = (void *) bp + namesz;
972         if (padsz > 0) {
973                 memset(bp, 0, padsz);
974                 bp = (void *) bp + padsz;
975         }
976         *bp++ = htonl(c_namesz);
977         memcpy(bp, contents, c_namesz);
978         bp = (void *) bp + c_namesz;
979         if (c_padsz > 0) {
980                 memset(bp, 0, c_padsz);
981                 bp = (void *) bp + c_padsz;
982         }
983         *bp++ = htonl(AFS_SET_MODE);
984         *bp++ = 0; /* mtime */
985         *bp++ = 0; /* owner */
986         *bp++ = 0; /* group */
987         *bp++ = htonl(S_IRWXUGO); /* unix mode */
988         *bp++ = 0; /* segment size */
989
990         return afs_make_call(&server->addr, call, GFP_NOFS, async);
991 }
992
993 /*
994  * deliver reply data to an FS.Rename
995  */
996 static int afs_deliver_fs_rename(struct afs_call *call)
997 {
998         struct afs_vnode *orig_dvnode = call->reply, *new_dvnode = call->reply2;
999         const __be32 *bp;
1000         int ret;
1001
1002         _enter("{%u}", call->unmarshall);
1003
1004         ret = afs_transfer_reply(call);
1005         if (ret < 0)
1006                 return ret;
1007
1008         /* unmarshall the reply once we've received all of it */
1009         bp = call->buffer;
1010         xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
1011         if (new_dvnode != orig_dvnode)
1012                 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
1013                                           NULL);
1014         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1015
1016         _leave(" = 0 [done]");
1017         return 0;
1018 }
1019
1020 /*
1021  * FS.Rename operation type
1022  */
1023 static const struct afs_call_type afs_RXFSRename = {
1024         .name           = "FS.Rename",
1025         .deliver        = afs_deliver_fs_rename,
1026         .abort_to_error = afs_abort_to_error,
1027         .destructor     = afs_flat_call_destructor,
1028 };
1029
1030 /*
1031  * create a symbolic link
1032  */
1033 int afs_fs_rename(struct afs_server *server,
1034                   struct key *key,
1035                   struct afs_vnode *orig_dvnode,
1036                   const char *orig_name,
1037                   struct afs_vnode *new_dvnode,
1038                   const char *new_name,
1039                   bool async)
1040 {
1041         struct afs_call *call;
1042         size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1043         __be32 *bp;
1044
1045         _enter("");
1046
1047         o_namesz = strlen(orig_name);
1048         o_padsz = (4 - (o_namesz & 3)) & 3;
1049
1050         n_namesz = strlen(new_name);
1051         n_padsz = (4 - (n_namesz & 3)) & 3;
1052
1053         reqsz = (4 * 4) +
1054                 4 + o_namesz + o_padsz +
1055                 (3 * 4) +
1056                 4 + n_namesz + n_padsz;
1057
1058         call = afs_alloc_flat_call(&afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1059         if (!call)
1060                 return -ENOMEM;
1061
1062         call->key = key;
1063         call->reply = orig_dvnode;
1064         call->reply2 = new_dvnode;
1065         call->service_id = FS_SERVICE;
1066         call->port = htons(AFS_FS_PORT);
1067
1068         /* marshall the parameters */
1069         bp = call->request;
1070         *bp++ = htonl(FSRENAME);
1071         *bp++ = htonl(orig_dvnode->fid.vid);
1072         *bp++ = htonl(orig_dvnode->fid.vnode);
1073         *bp++ = htonl(orig_dvnode->fid.unique);
1074         *bp++ = htonl(o_namesz);
1075         memcpy(bp, orig_name, o_namesz);
1076         bp = (void *) bp + o_namesz;
1077         if (o_padsz > 0) {
1078                 memset(bp, 0, o_padsz);
1079                 bp = (void *) bp + o_padsz;
1080         }
1081
1082         *bp++ = htonl(new_dvnode->fid.vid);
1083         *bp++ = htonl(new_dvnode->fid.vnode);
1084         *bp++ = htonl(new_dvnode->fid.unique);
1085         *bp++ = htonl(n_namesz);
1086         memcpy(bp, new_name, n_namesz);
1087         bp = (void *) bp + n_namesz;
1088         if (n_padsz > 0) {
1089                 memset(bp, 0, n_padsz);
1090                 bp = (void *) bp + n_padsz;
1091         }
1092
1093         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1094 }
1095
1096 /*
1097  * deliver reply data to an FS.StoreData
1098  */
1099 static int afs_deliver_fs_store_data(struct afs_call *call)
1100 {
1101         struct afs_vnode *vnode = call->reply;
1102         const __be32 *bp;
1103         int ret;
1104
1105         _enter("");
1106
1107         ret = afs_transfer_reply(call);
1108         if (ret < 0)
1109                 return ret;
1110
1111         /* unmarshall the reply once we've received all of it */
1112         bp = call->buffer;
1113         xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1114                                   &call->store_version);
1115         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1116
1117         afs_pages_written_back(vnode, call);
1118
1119         _leave(" = 0 [done]");
1120         return 0;
1121 }
1122
1123 /*
1124  * FS.StoreData operation type
1125  */
1126 static const struct afs_call_type afs_RXFSStoreData = {
1127         .name           = "FS.StoreData",
1128         .deliver        = afs_deliver_fs_store_data,
1129         .abort_to_error = afs_abort_to_error,
1130         .destructor     = afs_flat_call_destructor,
1131 };
1132
1133 static const struct afs_call_type afs_RXFSStoreData64 = {
1134         .name           = "FS.StoreData64",
1135         .deliver        = afs_deliver_fs_store_data,
1136         .abort_to_error = afs_abort_to_error,
1137         .destructor     = afs_flat_call_destructor,
1138 };
1139
1140 /*
1141  * store a set of pages to a very large file
1142  */
1143 static int afs_fs_store_data64(struct afs_server *server,
1144                                struct afs_writeback *wb,
1145                                pgoff_t first, pgoff_t last,
1146                                unsigned offset, unsigned to,
1147                                loff_t size, loff_t pos, loff_t i_size,
1148                                bool async)
1149 {
1150         struct afs_vnode *vnode = wb->vnode;
1151         struct afs_call *call;
1152         __be32 *bp;
1153
1154         _enter(",%x,{%x:%u},,",
1155                key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1156
1157         call = afs_alloc_flat_call(&afs_RXFSStoreData64,
1158                                    (4 + 6 + 3 * 2) * 4,
1159                                    (21 + 6) * 4);
1160         if (!call)
1161                 return -ENOMEM;
1162
1163         call->wb = wb;
1164         call->key = wb->key;
1165         call->reply = vnode;
1166         call->service_id = FS_SERVICE;
1167         call->port = htons(AFS_FS_PORT);
1168         call->mapping = vnode->vfs_inode.i_mapping;
1169         call->first = first;
1170         call->last = last;
1171         call->first_offset = offset;
1172         call->last_to = to;
1173         call->send_pages = true;
1174         call->store_version = vnode->status.data_version + 1;
1175
1176         /* marshall the parameters */
1177         bp = call->request;
1178         *bp++ = htonl(FSSTOREDATA64);
1179         *bp++ = htonl(vnode->fid.vid);
1180         *bp++ = htonl(vnode->fid.vnode);
1181         *bp++ = htonl(vnode->fid.unique);
1182
1183         *bp++ = 0; /* mask */
1184         *bp++ = 0; /* mtime */
1185         *bp++ = 0; /* owner */
1186         *bp++ = 0; /* group */
1187         *bp++ = 0; /* unix mode */
1188         *bp++ = 0; /* segment size */
1189
1190         *bp++ = htonl(pos >> 32);
1191         *bp++ = htonl((u32) pos);
1192         *bp++ = htonl(size >> 32);
1193         *bp++ = htonl((u32) size);
1194         *bp++ = htonl(i_size >> 32);
1195         *bp++ = htonl((u32) i_size);
1196
1197         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1198 }
1199
1200 /*
1201  * store a set of pages
1202  */
1203 int afs_fs_store_data(struct afs_server *server, struct afs_writeback *wb,
1204                       pgoff_t first, pgoff_t last,
1205                       unsigned offset, unsigned to,
1206                       bool async)
1207 {
1208         struct afs_vnode *vnode = wb->vnode;
1209         struct afs_call *call;
1210         loff_t size, pos, i_size;
1211         __be32 *bp;
1212
1213         _enter(",%x,{%x:%u},,",
1214                key_serial(wb->key), vnode->fid.vid, vnode->fid.vnode);
1215
1216         size = to - offset;
1217         if (first != last)
1218                 size += (loff_t)(last - first) << PAGE_SHIFT;
1219         pos = (loff_t)first << PAGE_SHIFT;
1220         pos += offset;
1221
1222         i_size = i_size_read(&vnode->vfs_inode);
1223         if (pos + size > i_size)
1224                 i_size = size + pos;
1225
1226         _debug("size %llx, at %llx, i_size %llx",
1227                (unsigned long long) size, (unsigned long long) pos,
1228                (unsigned long long) i_size);
1229
1230         if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1231                 return afs_fs_store_data64(server, wb, first, last, offset, to,
1232                                            size, pos, i_size, async);
1233
1234         call = afs_alloc_flat_call(&afs_RXFSStoreData,
1235                                    (4 + 6 + 3) * 4,
1236                                    (21 + 6) * 4);
1237         if (!call)
1238                 return -ENOMEM;
1239
1240         call->wb = wb;
1241         call->key = wb->key;
1242         call->reply = vnode;
1243         call->service_id = FS_SERVICE;
1244         call->port = htons(AFS_FS_PORT);
1245         call->mapping = vnode->vfs_inode.i_mapping;
1246         call->first = first;
1247         call->last = last;
1248         call->first_offset = offset;
1249         call->last_to = to;
1250         call->send_pages = true;
1251         call->store_version = vnode->status.data_version + 1;
1252
1253         /* marshall the parameters */
1254         bp = call->request;
1255         *bp++ = htonl(FSSTOREDATA);
1256         *bp++ = htonl(vnode->fid.vid);
1257         *bp++ = htonl(vnode->fid.vnode);
1258         *bp++ = htonl(vnode->fid.unique);
1259
1260         *bp++ = 0; /* mask */
1261         *bp++ = 0; /* mtime */
1262         *bp++ = 0; /* owner */
1263         *bp++ = 0; /* group */
1264         *bp++ = 0; /* unix mode */
1265         *bp++ = 0; /* segment size */
1266
1267         *bp++ = htonl(pos);
1268         *bp++ = htonl(size);
1269         *bp++ = htonl(i_size);
1270
1271         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1272 }
1273
1274 /*
1275  * deliver reply data to an FS.StoreStatus
1276  */
1277 static int afs_deliver_fs_store_status(struct afs_call *call)
1278 {
1279         afs_dataversion_t *store_version;
1280         struct afs_vnode *vnode = call->reply;
1281         const __be32 *bp;
1282         int ret;
1283
1284         _enter("");
1285
1286         ret = afs_transfer_reply(call);
1287         if (ret < 0)
1288                 return ret;
1289
1290         /* unmarshall the reply once we've received all of it */
1291         store_version = NULL;
1292         if (call->operation_ID == FSSTOREDATA)
1293                 store_version = &call->store_version;
1294
1295         bp = call->buffer;
1296         xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1297         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1298
1299         _leave(" = 0 [done]");
1300         return 0;
1301 }
1302
1303 /*
1304  * FS.StoreStatus operation type
1305  */
1306 static const struct afs_call_type afs_RXFSStoreStatus = {
1307         .name           = "FS.StoreStatus",
1308         .deliver        = afs_deliver_fs_store_status,
1309         .abort_to_error = afs_abort_to_error,
1310         .destructor     = afs_flat_call_destructor,
1311 };
1312
1313 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1314         .name           = "FS.StoreData",
1315         .deliver        = afs_deliver_fs_store_status,
1316         .abort_to_error = afs_abort_to_error,
1317         .destructor     = afs_flat_call_destructor,
1318 };
1319
1320 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1321         .name           = "FS.StoreData64",
1322         .deliver        = afs_deliver_fs_store_status,
1323         .abort_to_error = afs_abort_to_error,
1324         .destructor     = afs_flat_call_destructor,
1325 };
1326
1327 /*
1328  * set the attributes on a very large file, using FS.StoreData rather than
1329  * FS.StoreStatus so as to alter the file size also
1330  */
1331 static int afs_fs_setattr_size64(struct afs_server *server, struct key *key,
1332                                  struct afs_vnode *vnode, struct iattr *attr,
1333                                  bool async)
1334 {
1335         struct afs_call *call;
1336         __be32 *bp;
1337
1338         _enter(",%x,{%x:%u},,",
1339                key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1340
1341         ASSERT(attr->ia_valid & ATTR_SIZE);
1342
1343         call = afs_alloc_flat_call(&afs_RXFSStoreData64_as_Status,
1344                                    (4 + 6 + 3 * 2) * 4,
1345                                    (21 + 6) * 4);
1346         if (!call)
1347                 return -ENOMEM;
1348
1349         call->key = key;
1350         call->reply = vnode;
1351         call->service_id = FS_SERVICE;
1352         call->port = htons(AFS_FS_PORT);
1353         call->store_version = vnode->status.data_version + 1;
1354         call->operation_ID = FSSTOREDATA;
1355
1356         /* marshall the parameters */
1357         bp = call->request;
1358         *bp++ = htonl(FSSTOREDATA64);
1359         *bp++ = htonl(vnode->fid.vid);
1360         *bp++ = htonl(vnode->fid.vnode);
1361         *bp++ = htonl(vnode->fid.unique);
1362
1363         xdr_encode_AFS_StoreStatus(&bp, attr);
1364
1365         *bp++ = 0;                              /* position of start of write */
1366         *bp++ = 0;
1367         *bp++ = 0;                              /* size of write */
1368         *bp++ = 0;
1369         *bp++ = htonl(attr->ia_size >> 32);     /* new file length */
1370         *bp++ = htonl((u32) attr->ia_size);
1371
1372         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1373 }
1374
1375 /*
1376  * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1377  * so as to alter the file size also
1378  */
1379 static int afs_fs_setattr_size(struct afs_server *server, struct key *key,
1380                                struct afs_vnode *vnode, struct iattr *attr,
1381                                bool async)
1382 {
1383         struct afs_call *call;
1384         __be32 *bp;
1385
1386         _enter(",%x,{%x:%u},,",
1387                key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1388
1389         ASSERT(attr->ia_valid & ATTR_SIZE);
1390         if (attr->ia_size >> 32)
1391                 return afs_fs_setattr_size64(server, key, vnode, attr,
1392                                              async);
1393
1394         call = afs_alloc_flat_call(&afs_RXFSStoreData_as_Status,
1395                                    (4 + 6 + 3) * 4,
1396                                    (21 + 6) * 4);
1397         if (!call)
1398                 return -ENOMEM;
1399
1400         call->key = key;
1401         call->reply = vnode;
1402         call->service_id = FS_SERVICE;
1403         call->port = htons(AFS_FS_PORT);
1404         call->store_version = vnode->status.data_version + 1;
1405         call->operation_ID = FSSTOREDATA;
1406
1407         /* marshall the parameters */
1408         bp = call->request;
1409         *bp++ = htonl(FSSTOREDATA);
1410         *bp++ = htonl(vnode->fid.vid);
1411         *bp++ = htonl(vnode->fid.vnode);
1412         *bp++ = htonl(vnode->fid.unique);
1413
1414         xdr_encode_AFS_StoreStatus(&bp, attr);
1415
1416         *bp++ = 0;                              /* position of start of write */
1417         *bp++ = 0;                              /* size of write */
1418         *bp++ = htonl(attr->ia_size);           /* new file length */
1419
1420         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1421 }
1422
1423 /*
1424  * set the attributes on a file, using FS.StoreData if there's a change in file
1425  * size, and FS.StoreStatus otherwise
1426  */
1427 int afs_fs_setattr(struct afs_server *server, struct key *key,
1428                    struct afs_vnode *vnode, struct iattr *attr,
1429                    bool async)
1430 {
1431         struct afs_call *call;
1432         __be32 *bp;
1433
1434         if (attr->ia_valid & ATTR_SIZE)
1435                 return afs_fs_setattr_size(server, key, vnode, attr,
1436                                            async);
1437
1438         _enter(",%x,{%x:%u},,",
1439                key_serial(key), vnode->fid.vid, vnode->fid.vnode);
1440
1441         call = afs_alloc_flat_call(&afs_RXFSStoreStatus,
1442                                    (4 + 6) * 4,
1443                                    (21 + 6) * 4);
1444         if (!call)
1445                 return -ENOMEM;
1446
1447         call->key = key;
1448         call->reply = vnode;
1449         call->service_id = FS_SERVICE;
1450         call->port = htons(AFS_FS_PORT);
1451         call->operation_ID = FSSTORESTATUS;
1452
1453         /* marshall the parameters */
1454         bp = call->request;
1455         *bp++ = htonl(FSSTORESTATUS);
1456         *bp++ = htonl(vnode->fid.vid);
1457         *bp++ = htonl(vnode->fid.vnode);
1458         *bp++ = htonl(vnode->fid.unique);
1459
1460         xdr_encode_AFS_StoreStatus(&bp, attr);
1461
1462         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1463 }
1464
1465 /*
1466  * deliver reply data to an FS.GetVolumeStatus
1467  */
1468 static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1469 {
1470         const __be32 *bp;
1471         char *p;
1472         int ret;
1473
1474         _enter("{%u}", call->unmarshall);
1475
1476         switch (call->unmarshall) {
1477         case 0:
1478                 call->offset = 0;
1479                 call->unmarshall++;
1480
1481                 /* extract the returned status record */
1482         case 1:
1483                 _debug("extract status");
1484                 ret = afs_extract_data(call, call->buffer,
1485                                        12 * 4, true);
1486                 if (ret < 0)
1487                         return ret;
1488
1489                 bp = call->buffer;
1490                 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply2);
1491                 call->offset = 0;
1492                 call->unmarshall++;
1493
1494                 /* extract the volume name length */
1495         case 2:
1496                 ret = afs_extract_data(call, &call->tmp, 4, true);
1497                 if (ret < 0)
1498                         return ret;
1499
1500                 call->count = ntohl(call->tmp);
1501                 _debug("volname length: %u", call->count);
1502                 if (call->count >= AFSNAMEMAX)
1503                         return -EBADMSG;
1504                 call->offset = 0;
1505                 call->unmarshall++;
1506
1507                 /* extract the volume name */
1508         case 3:
1509                 _debug("extract volname");
1510                 if (call->count > 0) {
1511                         ret = afs_extract_data(call, call->reply3,
1512                                                call->count, true);
1513                         if (ret < 0)
1514                                 return ret;
1515                 }
1516
1517                 p = call->reply3;
1518                 p[call->count] = 0;
1519                 _debug("volname '%s'", p);
1520
1521                 call->offset = 0;
1522                 call->unmarshall++;
1523
1524                 /* extract the volume name padding */
1525                 if ((call->count & 3) == 0) {
1526                         call->unmarshall++;
1527                         goto no_volname_padding;
1528                 }
1529                 call->count = 4 - (call->count & 3);
1530
1531         case 4:
1532                 ret = afs_extract_data(call, call->buffer,
1533                                        call->count, true);
1534                 if (ret < 0)
1535                         return ret;
1536
1537                 call->offset = 0;
1538                 call->unmarshall++;
1539         no_volname_padding:
1540
1541                 /* extract the offline message length */
1542         case 5:
1543                 ret = afs_extract_data(call, &call->tmp, 4, true);
1544                 if (ret < 0)
1545                         return ret;
1546
1547                 call->count = ntohl(call->tmp);
1548                 _debug("offline msg length: %u", call->count);
1549                 if (call->count >= AFSNAMEMAX)
1550                         return -EBADMSG;
1551                 call->offset = 0;
1552                 call->unmarshall++;
1553
1554                 /* extract the offline message */
1555         case 6:
1556                 _debug("extract offline");
1557                 if (call->count > 0) {
1558                         ret = afs_extract_data(call, call->reply3,
1559                                                call->count, true);
1560                         if (ret < 0)
1561                                 return ret;
1562                 }
1563
1564                 p = call->reply3;
1565                 p[call->count] = 0;
1566                 _debug("offline '%s'", p);
1567
1568                 call->offset = 0;
1569                 call->unmarshall++;
1570
1571                 /* extract the offline message padding */
1572                 if ((call->count & 3) == 0) {
1573                         call->unmarshall++;
1574                         goto no_offline_padding;
1575                 }
1576                 call->count = 4 - (call->count & 3);
1577
1578         case 7:
1579                 ret = afs_extract_data(call, call->buffer,
1580                                        call->count, true);
1581                 if (ret < 0)
1582                         return ret;
1583
1584                 call->offset = 0;
1585                 call->unmarshall++;
1586         no_offline_padding:
1587
1588                 /* extract the message of the day length */
1589         case 8:
1590                 ret = afs_extract_data(call, &call->tmp, 4, true);
1591                 if (ret < 0)
1592                         return ret;
1593
1594                 call->count = ntohl(call->tmp);
1595                 _debug("motd length: %u", call->count);
1596                 if (call->count >= AFSNAMEMAX)
1597                         return -EBADMSG;
1598                 call->offset = 0;
1599                 call->unmarshall++;
1600
1601                 /* extract the message of the day */
1602         case 9:
1603                 _debug("extract motd");
1604                 if (call->count > 0) {
1605                         ret = afs_extract_data(call, call->reply3,
1606                                                call->count, true);
1607                         if (ret < 0)
1608                                 return ret;
1609                 }
1610
1611                 p = call->reply3;
1612                 p[call->count] = 0;
1613                 _debug("motd '%s'", p);
1614
1615                 call->offset = 0;
1616                 call->unmarshall++;
1617
1618                 /* extract the message of the day padding */
1619                 call->count = (4 - (call->count & 3)) & 3;
1620
1621         case 10:
1622                 ret = afs_extract_data(call, call->buffer,
1623                                        call->count, false);
1624                 if (ret < 0)
1625                         return ret;
1626
1627                 call->offset = 0;
1628                 call->unmarshall++;
1629         case 11:
1630                 break;
1631         }
1632
1633         _leave(" = 0 [done]");
1634         return 0;
1635 }
1636
1637 /*
1638  * destroy an FS.GetVolumeStatus call
1639  */
1640 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1641 {
1642         kfree(call->reply3);
1643         call->reply3 = NULL;
1644         afs_flat_call_destructor(call);
1645 }
1646
1647 /*
1648  * FS.GetVolumeStatus operation type
1649  */
1650 static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1651         .name           = "FS.GetVolumeStatus",
1652         .deliver        = afs_deliver_fs_get_volume_status,
1653         .abort_to_error = afs_abort_to_error,
1654         .destructor     = afs_get_volume_status_call_destructor,
1655 };
1656
1657 /*
1658  * fetch the status of a volume
1659  */
1660 int afs_fs_get_volume_status(struct afs_server *server,
1661                              struct key *key,
1662                              struct afs_vnode *vnode,
1663                              struct afs_volume_status *vs,
1664                              bool async)
1665 {
1666         struct afs_call *call;
1667         __be32 *bp;
1668         void *tmpbuf;
1669
1670         _enter("");
1671
1672         tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1673         if (!tmpbuf)
1674                 return -ENOMEM;
1675
1676         call = afs_alloc_flat_call(&afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1677         if (!call) {
1678                 kfree(tmpbuf);
1679                 return -ENOMEM;
1680         }
1681
1682         call->key = key;
1683         call->reply = vnode;
1684         call->reply2 = vs;
1685         call->reply3 = tmpbuf;
1686         call->service_id = FS_SERVICE;
1687         call->port = htons(AFS_FS_PORT);
1688
1689         /* marshall the parameters */
1690         bp = call->request;
1691         bp[0] = htonl(FSGETVOLUMESTATUS);
1692         bp[1] = htonl(vnode->fid.vid);
1693
1694         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1695 }
1696
1697 /*
1698  * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1699  */
1700 static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
1701 {
1702         const __be32 *bp;
1703         int ret;
1704
1705         _enter("{%u}", call->unmarshall);
1706
1707         ret = afs_transfer_reply(call);
1708         if (ret < 0)
1709                 return ret;
1710
1711         /* unmarshall the reply once we've received all of it */
1712         bp = call->buffer;
1713         /* xdr_decode_AFSVolSync(&bp, call->replyX); */
1714
1715         _leave(" = 0 [done]");
1716         return 0;
1717 }
1718
1719 /*
1720  * FS.SetLock operation type
1721  */
1722 static const struct afs_call_type afs_RXFSSetLock = {
1723         .name           = "FS.SetLock",
1724         .deliver        = afs_deliver_fs_xxxx_lock,
1725         .abort_to_error = afs_abort_to_error,
1726         .destructor     = afs_flat_call_destructor,
1727 };
1728
1729 /*
1730  * FS.ExtendLock operation type
1731  */
1732 static const struct afs_call_type afs_RXFSExtendLock = {
1733         .name           = "FS.ExtendLock",
1734         .deliver        = afs_deliver_fs_xxxx_lock,
1735         .abort_to_error = afs_abort_to_error,
1736         .destructor     = afs_flat_call_destructor,
1737 };
1738
1739 /*
1740  * FS.ReleaseLock operation type
1741  */
1742 static const struct afs_call_type afs_RXFSReleaseLock = {
1743         .name           = "FS.ReleaseLock",
1744         .deliver        = afs_deliver_fs_xxxx_lock,
1745         .abort_to_error = afs_abort_to_error,
1746         .destructor     = afs_flat_call_destructor,
1747 };
1748
1749 /*
1750  * get a lock on a file
1751  */
1752 int afs_fs_set_lock(struct afs_server *server,
1753                     struct key *key,
1754                     struct afs_vnode *vnode,
1755                     afs_lock_type_t type,
1756                     bool async)
1757 {
1758         struct afs_call *call;
1759         __be32 *bp;
1760
1761         _enter("");
1762
1763         call = afs_alloc_flat_call(&afs_RXFSSetLock, 5 * 4, 6 * 4);
1764         if (!call)
1765                 return -ENOMEM;
1766
1767         call->key = key;
1768         call->reply = vnode;
1769         call->service_id = FS_SERVICE;
1770         call->port = htons(AFS_FS_PORT);
1771
1772         /* marshall the parameters */
1773         bp = call->request;
1774         *bp++ = htonl(FSSETLOCK);
1775         *bp++ = htonl(vnode->fid.vid);
1776         *bp++ = htonl(vnode->fid.vnode);
1777         *bp++ = htonl(vnode->fid.unique);
1778         *bp++ = htonl(type);
1779
1780         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1781 }
1782
1783 /*
1784  * extend a lock on a file
1785  */
1786 int afs_fs_extend_lock(struct afs_server *server,
1787                        struct key *key,
1788                        struct afs_vnode *vnode,
1789                        bool async)
1790 {
1791         struct afs_call *call;
1792         __be32 *bp;
1793
1794         _enter("");
1795
1796         call = afs_alloc_flat_call(&afs_RXFSExtendLock, 4 * 4, 6 * 4);
1797         if (!call)
1798                 return -ENOMEM;
1799
1800         call->key = key;
1801         call->reply = vnode;
1802         call->service_id = FS_SERVICE;
1803         call->port = htons(AFS_FS_PORT);
1804
1805         /* marshall the parameters */
1806         bp = call->request;
1807         *bp++ = htonl(FSEXTENDLOCK);
1808         *bp++ = htonl(vnode->fid.vid);
1809         *bp++ = htonl(vnode->fid.vnode);
1810         *bp++ = htonl(vnode->fid.unique);
1811
1812         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1813 }
1814
1815 /*
1816  * release a lock on a file
1817  */
1818 int afs_fs_release_lock(struct afs_server *server,
1819                         struct key *key,
1820                         struct afs_vnode *vnode,
1821                         bool async)
1822 {
1823         struct afs_call *call;
1824         __be32 *bp;
1825
1826         _enter("");
1827
1828         call = afs_alloc_flat_call(&afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1829         if (!call)
1830                 return -ENOMEM;
1831
1832         call->key = key;
1833         call->reply = vnode;
1834         call->service_id = FS_SERVICE;
1835         call->port = htons(AFS_FS_PORT);
1836
1837         /* marshall the parameters */
1838         bp = call->request;
1839         *bp++ = htonl(FSRELEASELOCK);
1840         *bp++ = htonl(vnode->fid.vid);
1841         *bp++ = htonl(vnode->fid.vnode);
1842         *bp++ = htonl(vnode->fid.unique);
1843
1844         return afs_make_call(&server->addr, call, GFP_NOFS, async);
1845 }