~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/afs/fsclient.c

Version: ~ [ linux-5.3-rc5 ] ~ [ linux-5.2.9 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.67 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.139 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.189 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.189 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.72 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp