Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[cris-mirror.git] / fs / afs / fsclient.c
blob88ec38c2d83cc0d3989d02258444b21325b6abd2
1 /* AFS File Server client stubs
3 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/init.h>
13 #include <linux/slab.h>
14 #include <linux/sched.h>
15 #include <linux/circ_buf.h>
16 #include <linux/iversion.h>
17 #include "internal.h"
18 #include "afs_fs.h"
20 static const struct afs_fid afs_zero_fid;
23 * We need somewhere to discard into in case the server helpfully returns more
24 * than we asked for in FS.FetchData{,64}.
26 static u8 afs_discard_buffer[64];
28 static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
30 call->cbi = afs_get_cb_interest(cbi);
34 * decode an AFSFid block
36 static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
38 const __be32 *bp = *_bp;
40 fid->vid = ntohl(*bp++);
41 fid->vnode = ntohl(*bp++);
42 fid->unique = ntohl(*bp++);
43 *_bp = bp;
47 * decode an AFSFetchStatus block
49 static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
50 struct afs_file_status *status,
51 struct afs_vnode *vnode,
52 afs_dataversion_t *store_version)
54 afs_dataversion_t expected_version;
55 const __be32 *bp = *_bp;
56 umode_t mode;
57 u64 data_version, size;
58 bool changed = false;
59 kuid_t owner;
60 kgid_t group;
62 if (vnode)
63 write_seqlock(&vnode->cb_lock);
65 #define EXTRACT(DST) \
66 do { \
67 u32 x = ntohl(*bp++); \
68 if (DST != x) \
69 changed |= true; \
70 DST = x; \
71 } while (0)
73 status->if_version = ntohl(*bp++);
74 EXTRACT(status->type);
75 EXTRACT(status->nlink);
76 size = ntohl(*bp++);
77 data_version = ntohl(*bp++);
78 EXTRACT(status->author);
79 owner = make_kuid(&init_user_ns, ntohl(*bp++));
80 changed |= !uid_eq(owner, status->owner);
81 status->owner = owner;
82 EXTRACT(status->caller_access); /* call ticket dependent */
83 EXTRACT(status->anon_access);
84 EXTRACT(status->mode);
85 bp++; /* parent.vnode */
86 bp++; /* parent.unique */
87 bp++; /* seg size */
88 status->mtime_client = ntohl(*bp++);
89 status->mtime_server = ntohl(*bp++);
90 group = make_kgid(&init_user_ns, ntohl(*bp++));
91 changed |= !gid_eq(group, status->group);
92 status->group = group;
93 bp++; /* sync counter */
94 data_version |= (u64) ntohl(*bp++) << 32;
95 EXTRACT(status->lock_count);
96 size |= (u64) ntohl(*bp++) << 32;
97 bp++; /* spare 4 */
98 *_bp = bp;
100 if (size != status->size) {
101 status->size = size;
102 changed |= true;
104 status->mode &= S_IALLUGO;
106 _debug("vnode time %lx, %lx",
107 status->mtime_client, status->mtime_server);
109 if (vnode) {
110 if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
111 _debug("vnode changed");
112 i_size_write(&vnode->vfs_inode, size);
113 vnode->vfs_inode.i_uid = status->owner;
114 vnode->vfs_inode.i_gid = status->group;
115 vnode->vfs_inode.i_generation = vnode->fid.unique;
116 set_nlink(&vnode->vfs_inode, status->nlink);
118 mode = vnode->vfs_inode.i_mode;
119 mode &= ~S_IALLUGO;
120 mode |= status->mode;
121 barrier();
122 vnode->vfs_inode.i_mode = mode;
125 vnode->vfs_inode.i_ctime.tv_sec = status->mtime_client;
126 vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime;
127 vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime;
128 inode_set_iversion_raw(&vnode->vfs_inode, data_version);
131 expected_version = status->data_version;
132 if (store_version)
133 expected_version = *store_version;
135 if (expected_version != data_version) {
136 status->data_version = data_version;
137 if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
138 _debug("vnode modified %llx on {%x:%u}",
139 (unsigned long long) data_version,
140 vnode->fid.vid, vnode->fid.vnode);
141 set_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags);
142 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
144 } else if (store_version) {
145 status->data_version = data_version;
148 if (vnode)
149 write_sequnlock(&vnode->cb_lock);
153 * decode an AFSCallBack block
155 static void xdr_decode_AFSCallBack(struct afs_call *call,
156 struct afs_vnode *vnode,
157 const __be32 **_bp)
159 struct afs_cb_interest *old, *cbi = call->cbi;
160 const __be32 *bp = *_bp;
161 u32 cb_expiry;
163 write_seqlock(&vnode->cb_lock);
165 if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) {
166 vnode->cb_version = ntohl(*bp++);
167 cb_expiry = ntohl(*bp++);
168 vnode->cb_type = ntohl(*bp++);
169 vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds();
170 old = vnode->cb_interest;
171 if (old != call->cbi) {
172 vnode->cb_interest = cbi;
173 cbi = old;
175 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
176 } else {
177 bp += 3;
180 write_sequnlock(&vnode->cb_lock);
181 call->cbi = cbi;
182 *_bp = bp;
185 static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
186 struct afs_callback *cb)
188 const __be32 *bp = *_bp;
190 cb->version = ntohl(*bp++);
191 cb->expiry = ntohl(*bp++);
192 cb->type = ntohl(*bp++);
193 *_bp = bp;
197 * decode an AFSVolSync block
199 static void xdr_decode_AFSVolSync(const __be32 **_bp,
200 struct afs_volsync *volsync)
202 const __be32 *bp = *_bp;
204 volsync->creation = ntohl(*bp++);
205 bp++; /* spare2 */
206 bp++; /* spare3 */
207 bp++; /* spare4 */
208 bp++; /* spare5 */
209 bp++; /* spare6 */
210 *_bp = bp;
214 * encode the requested attributes into an AFSStoreStatus block
216 static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
218 __be32 *bp = *_bp;
219 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
221 mask = 0;
222 if (attr->ia_valid & ATTR_MTIME) {
223 mask |= AFS_SET_MTIME;
224 mtime = attr->ia_mtime.tv_sec;
227 if (attr->ia_valid & ATTR_UID) {
228 mask |= AFS_SET_OWNER;
229 owner = from_kuid(&init_user_ns, attr->ia_uid);
232 if (attr->ia_valid & ATTR_GID) {
233 mask |= AFS_SET_GROUP;
234 group = from_kgid(&init_user_ns, attr->ia_gid);
237 if (attr->ia_valid & ATTR_MODE) {
238 mask |= AFS_SET_MODE;
239 mode = attr->ia_mode & S_IALLUGO;
242 *bp++ = htonl(mask);
243 *bp++ = htonl(mtime);
244 *bp++ = htonl(owner);
245 *bp++ = htonl(group);
246 *bp++ = htonl(mode);
247 *bp++ = 0; /* segment size */
248 *_bp = bp;
252 * decode an AFSFetchVolumeStatus block
254 static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
255 struct afs_volume_status *vs)
257 const __be32 *bp = *_bp;
259 vs->vid = ntohl(*bp++);
260 vs->parent_id = ntohl(*bp++);
261 vs->online = ntohl(*bp++);
262 vs->in_service = ntohl(*bp++);
263 vs->blessed = ntohl(*bp++);
264 vs->needs_salvage = ntohl(*bp++);
265 vs->type = ntohl(*bp++);
266 vs->min_quota = ntohl(*bp++);
267 vs->max_quota = ntohl(*bp++);
268 vs->blocks_in_use = ntohl(*bp++);
269 vs->part_blocks_avail = ntohl(*bp++);
270 vs->part_max_blocks = ntohl(*bp++);
271 *_bp = bp;
275 * deliver reply data to an FS.FetchStatus
277 static int afs_deliver_fs_fetch_status(struct afs_call *call)
279 struct afs_vnode *vnode = call->reply[0];
280 const __be32 *bp;
281 int ret;
283 ret = afs_transfer_reply(call);
284 if (ret < 0)
285 return ret;
287 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
289 /* unmarshall the reply once we've received all of it */
290 bp = call->buffer;
291 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
292 xdr_decode_AFSCallBack(call, vnode, &bp);
293 if (call->reply[1])
294 xdr_decode_AFSVolSync(&bp, call->reply[1]);
296 _leave(" = 0 [done]");
297 return 0;
301 * FS.FetchStatus operation type
303 static const struct afs_call_type afs_RXFSFetchStatus = {
304 .name = "FS.FetchStatus",
305 .op = afs_FS_FetchStatus,
306 .deliver = afs_deliver_fs_fetch_status,
307 .destructor = afs_flat_call_destructor,
311 * fetch the status information for a file
313 int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync)
315 struct afs_vnode *vnode = fc->vnode;
316 struct afs_call *call;
317 struct afs_net *net = afs_v2net(vnode);
318 __be32 *bp;
320 _enter(",%x,{%x:%u},,",
321 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
323 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
324 if (!call) {
325 fc->ac.error = -ENOMEM;
326 return -ENOMEM;
329 call->key = fc->key;
330 call->reply[0] = vnode;
331 call->reply[1] = volsync;
333 /* marshall the parameters */
334 bp = call->request;
335 bp[0] = htonl(FSFETCHSTATUS);
336 bp[1] = htonl(vnode->fid.vid);
337 bp[2] = htonl(vnode->fid.vnode);
338 bp[3] = htonl(vnode->fid.unique);
340 call->cb_break = fc->cb_break;
341 afs_use_fs_server(call, fc->cbi);
342 trace_afs_make_fs_call(call, &vnode->fid);
343 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
347 * deliver reply data to an FS.FetchData
349 static int afs_deliver_fs_fetch_data(struct afs_call *call)
351 struct afs_vnode *vnode = call->reply[0];
352 struct afs_read *req = call->reply[2];
353 const __be32 *bp;
354 unsigned int size;
355 void *buffer;
356 int ret;
358 _enter("{%u,%zu/%u;%llu/%llu}",
359 call->unmarshall, call->offset, call->count,
360 req->remain, req->actual_len);
362 switch (call->unmarshall) {
363 case 0:
364 req->actual_len = 0;
365 call->offset = 0;
366 call->unmarshall++;
367 if (call->operation_ID != FSFETCHDATA64) {
368 call->unmarshall++;
369 goto no_msw;
372 /* extract the upper part of the returned data length of an
373 * FSFETCHDATA64 op (which should always be 0 using this
374 * client) */
375 case 1:
376 _debug("extract data length (MSW)");
377 ret = afs_extract_data(call, &call->tmp, 4, true);
378 if (ret < 0)
379 return ret;
381 req->actual_len = ntohl(call->tmp);
382 req->actual_len <<= 32;
383 call->offset = 0;
384 call->unmarshall++;
386 no_msw:
387 /* extract the returned data length */
388 case 2:
389 _debug("extract data length");
390 ret = afs_extract_data(call, &call->tmp, 4, true);
391 if (ret < 0)
392 return ret;
394 req->actual_len |= ntohl(call->tmp);
395 _debug("DATA length: %llu", req->actual_len);
397 req->remain = req->actual_len;
398 call->offset = req->pos & (PAGE_SIZE - 1);
399 req->index = 0;
400 if (req->actual_len == 0)
401 goto no_more_data;
402 call->unmarshall++;
404 begin_page:
405 ASSERTCMP(req->index, <, req->nr_pages);
406 if (req->remain > PAGE_SIZE - call->offset)
407 size = PAGE_SIZE - call->offset;
408 else
409 size = req->remain;
410 call->count = call->offset + size;
411 ASSERTCMP(call->count, <=, PAGE_SIZE);
412 req->remain -= size;
414 /* extract the returned data */
415 case 3:
416 _debug("extract data %llu/%llu %zu/%u",
417 req->remain, req->actual_len, call->offset, call->count);
419 buffer = kmap(req->pages[req->index]);
420 ret = afs_extract_data(call, buffer, call->count, true);
421 kunmap(req->pages[req->index]);
422 if (ret < 0)
423 return ret;
424 if (call->offset == PAGE_SIZE) {
425 if (req->page_done)
426 req->page_done(call, req);
427 req->index++;
428 if (req->remain > 0) {
429 call->offset = 0;
430 if (req->index >= req->nr_pages) {
431 call->unmarshall = 4;
432 goto begin_discard;
434 goto begin_page;
437 goto no_more_data;
439 /* Discard any excess data the server gave us */
440 begin_discard:
441 case 4:
442 size = min_t(loff_t, sizeof(afs_discard_buffer), req->remain);
443 call->count = size;
444 _debug("extract discard %llu/%llu %zu/%u",
445 req->remain, req->actual_len, call->offset, call->count);
447 call->offset = 0;
448 ret = afs_extract_data(call, afs_discard_buffer, call->count, true);
449 req->remain -= call->offset;
450 if (ret < 0)
451 return ret;
452 if (req->remain > 0)
453 goto begin_discard;
455 no_more_data:
456 call->offset = 0;
457 call->unmarshall = 5;
459 /* extract the metadata */
460 case 5:
461 ret = afs_extract_data(call, call->buffer,
462 (21 + 3 + 6) * 4, false);
463 if (ret < 0)
464 return ret;
466 bp = call->buffer;
467 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
468 xdr_decode_AFSCallBack(call, vnode, &bp);
469 if (call->reply[1])
470 xdr_decode_AFSVolSync(&bp, call->reply[1]);
472 call->offset = 0;
473 call->unmarshall++;
475 case 6:
476 break;
479 for (; req->index < req->nr_pages; req->index++) {
480 if (call->count < PAGE_SIZE)
481 zero_user_segment(req->pages[req->index],
482 call->count, PAGE_SIZE);
483 if (req->page_done)
484 req->page_done(call, req);
485 call->count = 0;
488 _leave(" = 0 [done]");
489 return 0;
492 static void afs_fetch_data_destructor(struct afs_call *call)
494 struct afs_read *req = call->reply[2];
496 afs_put_read(req);
497 afs_flat_call_destructor(call);
501 * FS.FetchData operation type
503 static const struct afs_call_type afs_RXFSFetchData = {
504 .name = "FS.FetchData",
505 .op = afs_FS_FetchData,
506 .deliver = afs_deliver_fs_fetch_data,
507 .destructor = afs_fetch_data_destructor,
510 static const struct afs_call_type afs_RXFSFetchData64 = {
511 .name = "FS.FetchData64",
512 .op = afs_FS_FetchData64,
513 .deliver = afs_deliver_fs_fetch_data,
514 .destructor = afs_fetch_data_destructor,
518 * fetch data from a very large file
520 static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
522 struct afs_vnode *vnode = fc->vnode;
523 struct afs_call *call;
524 struct afs_net *net = afs_v2net(vnode);
525 __be32 *bp;
527 _enter("");
529 call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
530 if (!call)
531 return -ENOMEM;
533 call->key = fc->key;
534 call->reply[0] = vnode;
535 call->reply[1] = NULL; /* volsync */
536 call->reply[2] = req;
538 /* marshall the parameters */
539 bp = call->request;
540 bp[0] = htonl(FSFETCHDATA64);
541 bp[1] = htonl(vnode->fid.vid);
542 bp[2] = htonl(vnode->fid.vnode);
543 bp[3] = htonl(vnode->fid.unique);
544 bp[4] = htonl(upper_32_bits(req->pos));
545 bp[5] = htonl(lower_32_bits(req->pos));
546 bp[6] = 0;
547 bp[7] = htonl(lower_32_bits(req->len));
549 atomic_inc(&req->usage);
550 call->cb_break = fc->cb_break;
551 afs_use_fs_server(call, fc->cbi);
552 trace_afs_make_fs_call(call, &vnode->fid);
553 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
557 * fetch data from a file
559 int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
561 struct afs_vnode *vnode = fc->vnode;
562 struct afs_call *call;
563 struct afs_net *net = afs_v2net(vnode);
564 __be32 *bp;
566 if (upper_32_bits(req->pos) ||
567 upper_32_bits(req->len) ||
568 upper_32_bits(req->pos + req->len))
569 return afs_fs_fetch_data64(fc, req);
571 _enter("");
573 call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
574 if (!call)
575 return -ENOMEM;
577 call->key = fc->key;
578 call->reply[0] = vnode;
579 call->reply[1] = NULL; /* volsync */
580 call->reply[2] = req;
582 /* marshall the parameters */
583 bp = call->request;
584 bp[0] = htonl(FSFETCHDATA);
585 bp[1] = htonl(vnode->fid.vid);
586 bp[2] = htonl(vnode->fid.vnode);
587 bp[3] = htonl(vnode->fid.unique);
588 bp[4] = htonl(lower_32_bits(req->pos));
589 bp[5] = htonl(lower_32_bits(req->len));
591 atomic_inc(&req->usage);
592 call->cb_break = fc->cb_break;
593 afs_use_fs_server(call, fc->cbi);
594 trace_afs_make_fs_call(call, &vnode->fid);
595 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
599 * deliver reply data to an FS.CreateFile or an FS.MakeDir
601 static int afs_deliver_fs_create_vnode(struct afs_call *call)
603 struct afs_vnode *vnode = call->reply[0];
604 const __be32 *bp;
605 int ret;
607 _enter("{%u}", call->unmarshall);
609 ret = afs_transfer_reply(call);
610 if (ret < 0)
611 return ret;
613 /* unmarshall the reply once we've received all of it */
614 bp = call->buffer;
615 xdr_decode_AFSFid(&bp, call->reply[1]);
616 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
617 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
618 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
619 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
621 _leave(" = 0 [done]");
622 return 0;
626 * FS.CreateFile and FS.MakeDir operation type
628 static const struct afs_call_type afs_RXFSCreateFile = {
629 .name = "FS.CreateFile",
630 .op = afs_FS_CreateFile,
631 .deliver = afs_deliver_fs_create_vnode,
632 .destructor = afs_flat_call_destructor,
635 static const struct afs_call_type afs_RXFSMakeDir = {
636 .name = "FS.MakeDir",
637 .op = afs_FS_MakeDir,
638 .deliver = afs_deliver_fs_create_vnode,
639 .destructor = afs_flat_call_destructor,
643 * create a file or make a directory
645 int afs_fs_create(struct afs_fs_cursor *fc,
646 const char *name,
647 umode_t mode,
648 struct afs_fid *newfid,
649 struct afs_file_status *newstatus,
650 struct afs_callback *newcb)
652 struct afs_vnode *vnode = fc->vnode;
653 struct afs_call *call;
654 struct afs_net *net = afs_v2net(vnode);
655 size_t namesz, reqsz, padsz;
656 __be32 *bp;
658 _enter("");
660 namesz = strlen(name);
661 padsz = (4 - (namesz & 3)) & 3;
662 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
664 call = afs_alloc_flat_call(
665 net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile,
666 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
667 if (!call)
668 return -ENOMEM;
670 call->key = fc->key;
671 call->reply[0] = vnode;
672 call->reply[1] = newfid;
673 call->reply[2] = newstatus;
674 call->reply[3] = newcb;
676 /* marshall the parameters */
677 bp = call->request;
678 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
679 *bp++ = htonl(vnode->fid.vid);
680 *bp++ = htonl(vnode->fid.vnode);
681 *bp++ = htonl(vnode->fid.unique);
682 *bp++ = htonl(namesz);
683 memcpy(bp, name, namesz);
684 bp = (void *) bp + namesz;
685 if (padsz > 0) {
686 memset(bp, 0, padsz);
687 bp = (void *) bp + padsz;
689 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
690 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
691 *bp++ = 0; /* owner */
692 *bp++ = 0; /* group */
693 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
694 *bp++ = 0; /* segment size */
696 afs_use_fs_server(call, fc->cbi);
697 trace_afs_make_fs_call(call, &vnode->fid);
698 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
702 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
704 static int afs_deliver_fs_remove(struct afs_call *call)
706 struct afs_vnode *vnode = call->reply[0];
707 const __be32 *bp;
708 int ret;
710 _enter("{%u}", call->unmarshall);
712 ret = afs_transfer_reply(call);
713 if (ret < 0)
714 return ret;
716 /* unmarshall the reply once we've received all of it */
717 bp = call->buffer;
718 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
719 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
721 _leave(" = 0 [done]");
722 return 0;
726 * FS.RemoveDir/FS.RemoveFile operation type
728 static const struct afs_call_type afs_RXFSRemoveFile = {
729 .name = "FS.RemoveFile",
730 .op = afs_FS_RemoveFile,
731 .deliver = afs_deliver_fs_remove,
732 .destructor = afs_flat_call_destructor,
735 static const struct afs_call_type afs_RXFSRemoveDir = {
736 .name = "FS.RemoveDir",
737 .op = afs_FS_RemoveDir,
738 .deliver = afs_deliver_fs_remove,
739 .destructor = afs_flat_call_destructor,
743 * remove a file or directory
745 int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir)
747 struct afs_vnode *vnode = fc->vnode;
748 struct afs_call *call;
749 struct afs_net *net = afs_v2net(vnode);
750 size_t namesz, reqsz, padsz;
751 __be32 *bp;
753 _enter("");
755 namesz = strlen(name);
756 padsz = (4 - (namesz & 3)) & 3;
757 reqsz = (5 * 4) + namesz + padsz;
759 call = afs_alloc_flat_call(
760 net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile,
761 reqsz, (21 + 6) * 4);
762 if (!call)
763 return -ENOMEM;
765 call->key = fc->key;
766 call->reply[0] = vnode;
768 /* marshall the parameters */
769 bp = call->request;
770 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
771 *bp++ = htonl(vnode->fid.vid);
772 *bp++ = htonl(vnode->fid.vnode);
773 *bp++ = htonl(vnode->fid.unique);
774 *bp++ = htonl(namesz);
775 memcpy(bp, name, namesz);
776 bp = (void *) bp + namesz;
777 if (padsz > 0) {
778 memset(bp, 0, padsz);
779 bp = (void *) bp + padsz;
782 afs_use_fs_server(call, fc->cbi);
783 trace_afs_make_fs_call(call, &vnode->fid);
784 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
788 * deliver reply data to an FS.Link
790 static int afs_deliver_fs_link(struct afs_call *call)
792 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
793 const __be32 *bp;
794 int ret;
796 _enter("{%u}", call->unmarshall);
798 ret = afs_transfer_reply(call);
799 if (ret < 0)
800 return ret;
802 /* unmarshall the reply once we've received all of it */
803 bp = call->buffer;
804 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
805 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
806 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
808 _leave(" = 0 [done]");
809 return 0;
813 * FS.Link operation type
815 static const struct afs_call_type afs_RXFSLink = {
816 .name = "FS.Link",
817 .op = afs_FS_Link,
818 .deliver = afs_deliver_fs_link,
819 .destructor = afs_flat_call_destructor,
823 * make a hard link
825 int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
826 const char *name)
828 struct afs_vnode *dvnode = fc->vnode;
829 struct afs_call *call;
830 struct afs_net *net = afs_v2net(vnode);
831 size_t namesz, reqsz, padsz;
832 __be32 *bp;
834 _enter("");
836 namesz = strlen(name);
837 padsz = (4 - (namesz & 3)) & 3;
838 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
840 call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
841 if (!call)
842 return -ENOMEM;
844 call->key = fc->key;
845 call->reply[0] = dvnode;
846 call->reply[1] = vnode;
848 /* marshall the parameters */
849 bp = call->request;
850 *bp++ = htonl(FSLINK);
851 *bp++ = htonl(dvnode->fid.vid);
852 *bp++ = htonl(dvnode->fid.vnode);
853 *bp++ = htonl(dvnode->fid.unique);
854 *bp++ = htonl(namesz);
855 memcpy(bp, name, namesz);
856 bp = (void *) bp + namesz;
857 if (padsz > 0) {
858 memset(bp, 0, padsz);
859 bp = (void *) bp + padsz;
861 *bp++ = htonl(vnode->fid.vid);
862 *bp++ = htonl(vnode->fid.vnode);
863 *bp++ = htonl(vnode->fid.unique);
865 afs_use_fs_server(call, fc->cbi);
866 trace_afs_make_fs_call(call, &vnode->fid);
867 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
871 * deliver reply data to an FS.Symlink
873 static int afs_deliver_fs_symlink(struct afs_call *call)
875 struct afs_vnode *vnode = call->reply[0];
876 const __be32 *bp;
877 int ret;
879 _enter("{%u}", call->unmarshall);
881 ret = afs_transfer_reply(call);
882 if (ret < 0)
883 return ret;
885 /* unmarshall the reply once we've received all of it */
886 bp = call->buffer;
887 xdr_decode_AFSFid(&bp, call->reply[1]);
888 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
889 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
890 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
892 _leave(" = 0 [done]");
893 return 0;
897 * FS.Symlink operation type
899 static const struct afs_call_type afs_RXFSSymlink = {
900 .name = "FS.Symlink",
901 .op = afs_FS_Symlink,
902 .deliver = afs_deliver_fs_symlink,
903 .destructor = afs_flat_call_destructor,
907 * create a symbolic link
909 int afs_fs_symlink(struct afs_fs_cursor *fc,
910 const char *name,
911 const char *contents,
912 struct afs_fid *newfid,
913 struct afs_file_status *newstatus)
915 struct afs_vnode *vnode = fc->vnode;
916 struct afs_call *call;
917 struct afs_net *net = afs_v2net(vnode);
918 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
919 __be32 *bp;
921 _enter("");
923 namesz = strlen(name);
924 padsz = (4 - (namesz & 3)) & 3;
926 c_namesz = strlen(contents);
927 c_padsz = (4 - (c_namesz & 3)) & 3;
929 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
931 call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,
932 (3 + 21 + 21 + 6) * 4);
933 if (!call)
934 return -ENOMEM;
936 call->key = fc->key;
937 call->reply[0] = vnode;
938 call->reply[1] = newfid;
939 call->reply[2] = newstatus;
941 /* marshall the parameters */
942 bp = call->request;
943 *bp++ = htonl(FSSYMLINK);
944 *bp++ = htonl(vnode->fid.vid);
945 *bp++ = htonl(vnode->fid.vnode);
946 *bp++ = htonl(vnode->fid.unique);
947 *bp++ = htonl(namesz);
948 memcpy(bp, name, namesz);
949 bp = (void *) bp + namesz;
950 if (padsz > 0) {
951 memset(bp, 0, padsz);
952 bp = (void *) bp + padsz;
954 *bp++ = htonl(c_namesz);
955 memcpy(bp, contents, c_namesz);
956 bp = (void *) bp + c_namesz;
957 if (c_padsz > 0) {
958 memset(bp, 0, c_padsz);
959 bp = (void *) bp + c_padsz;
961 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
962 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
963 *bp++ = 0; /* owner */
964 *bp++ = 0; /* group */
965 *bp++ = htonl(S_IRWXUGO); /* unix mode */
966 *bp++ = 0; /* segment size */
968 afs_use_fs_server(call, fc->cbi);
969 trace_afs_make_fs_call(call, &vnode->fid);
970 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
974 * deliver reply data to an FS.Rename
976 static int afs_deliver_fs_rename(struct afs_call *call)
978 struct afs_vnode *orig_dvnode = call->reply[0], *new_dvnode = call->reply[1];
979 const __be32 *bp;
980 int ret;
982 _enter("{%u}", call->unmarshall);
984 ret = afs_transfer_reply(call);
985 if (ret < 0)
986 return ret;
988 /* unmarshall the reply once we've received all of it */
989 bp = call->buffer;
990 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
991 if (new_dvnode != orig_dvnode)
992 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
993 NULL);
994 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
996 _leave(" = 0 [done]");
997 return 0;
1001 * FS.Rename operation type
1003 static const struct afs_call_type afs_RXFSRename = {
1004 .name = "FS.Rename",
1005 .op = afs_FS_Rename,
1006 .deliver = afs_deliver_fs_rename,
1007 .destructor = afs_flat_call_destructor,
1011 * create a symbolic link
1013 int afs_fs_rename(struct afs_fs_cursor *fc,
1014 const char *orig_name,
1015 struct afs_vnode *new_dvnode,
1016 const char *new_name)
1018 struct afs_vnode *orig_dvnode = fc->vnode;
1019 struct afs_call *call;
1020 struct afs_net *net = afs_v2net(orig_dvnode);
1021 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1022 __be32 *bp;
1024 _enter("");
1026 o_namesz = strlen(orig_name);
1027 o_padsz = (4 - (o_namesz & 3)) & 3;
1029 n_namesz = strlen(new_name);
1030 n_padsz = (4 - (n_namesz & 3)) & 3;
1032 reqsz = (4 * 4) +
1033 4 + o_namesz + o_padsz +
1034 (3 * 4) +
1035 4 + n_namesz + n_padsz;
1037 call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
1038 if (!call)
1039 return -ENOMEM;
1041 call->key = fc->key;
1042 call->reply[0] = orig_dvnode;
1043 call->reply[1] = new_dvnode;
1045 /* marshall the parameters */
1046 bp = call->request;
1047 *bp++ = htonl(FSRENAME);
1048 *bp++ = htonl(orig_dvnode->fid.vid);
1049 *bp++ = htonl(orig_dvnode->fid.vnode);
1050 *bp++ = htonl(orig_dvnode->fid.unique);
1051 *bp++ = htonl(o_namesz);
1052 memcpy(bp, orig_name, o_namesz);
1053 bp = (void *) bp + o_namesz;
1054 if (o_padsz > 0) {
1055 memset(bp, 0, o_padsz);
1056 bp = (void *) bp + o_padsz;
1059 *bp++ = htonl(new_dvnode->fid.vid);
1060 *bp++ = htonl(new_dvnode->fid.vnode);
1061 *bp++ = htonl(new_dvnode->fid.unique);
1062 *bp++ = htonl(n_namesz);
1063 memcpy(bp, new_name, n_namesz);
1064 bp = (void *) bp + n_namesz;
1065 if (n_padsz > 0) {
1066 memset(bp, 0, n_padsz);
1067 bp = (void *) bp + n_padsz;
1070 afs_use_fs_server(call, fc->cbi);
1071 trace_afs_make_fs_call(call, &orig_dvnode->fid);
1072 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1076 * deliver reply data to an FS.StoreData
1078 static int afs_deliver_fs_store_data(struct afs_call *call)
1080 struct afs_vnode *vnode = call->reply[0];
1081 const __be32 *bp;
1082 int ret;
1084 _enter("");
1086 ret = afs_transfer_reply(call);
1087 if (ret < 0)
1088 return ret;
1090 /* unmarshall the reply once we've received all of it */
1091 bp = call->buffer;
1092 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1093 &call->store_version);
1094 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1096 afs_pages_written_back(vnode, call);
1098 _leave(" = 0 [done]");
1099 return 0;
1103 * FS.StoreData operation type
1105 static const struct afs_call_type afs_RXFSStoreData = {
1106 .name = "FS.StoreData",
1107 .op = afs_FS_StoreData,
1108 .deliver = afs_deliver_fs_store_data,
1109 .destructor = afs_flat_call_destructor,
1112 static const struct afs_call_type afs_RXFSStoreData64 = {
1113 .name = "FS.StoreData64",
1114 .op = afs_FS_StoreData64,
1115 .deliver = afs_deliver_fs_store_data,
1116 .destructor = afs_flat_call_destructor,
1120 * store a set of pages to a very large file
1122 static int afs_fs_store_data64(struct afs_fs_cursor *fc,
1123 struct address_space *mapping,
1124 pgoff_t first, pgoff_t last,
1125 unsigned offset, unsigned to,
1126 loff_t size, loff_t pos, loff_t i_size)
1128 struct afs_vnode *vnode = fc->vnode;
1129 struct afs_call *call;
1130 struct afs_net *net = afs_v2net(vnode);
1131 __be32 *bp;
1133 _enter(",%x,{%x:%u},,",
1134 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1136 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,
1137 (4 + 6 + 3 * 2) * 4,
1138 (21 + 6) * 4);
1139 if (!call)
1140 return -ENOMEM;
1142 call->key = fc->key;
1143 call->mapping = mapping;
1144 call->reply[0] = vnode;
1145 call->first = first;
1146 call->last = last;
1147 call->first_offset = offset;
1148 call->last_to = to;
1149 call->send_pages = true;
1150 call->store_version = vnode->status.data_version + 1;
1152 /* marshall the parameters */
1153 bp = call->request;
1154 *bp++ = htonl(FSSTOREDATA64);
1155 *bp++ = htonl(vnode->fid.vid);
1156 *bp++ = htonl(vnode->fid.vnode);
1157 *bp++ = htonl(vnode->fid.unique);
1159 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1160 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1161 *bp++ = 0; /* owner */
1162 *bp++ = 0; /* group */
1163 *bp++ = 0; /* unix mode */
1164 *bp++ = 0; /* segment size */
1166 *bp++ = htonl(pos >> 32);
1167 *bp++ = htonl((u32) pos);
1168 *bp++ = htonl(size >> 32);
1169 *bp++ = htonl((u32) size);
1170 *bp++ = htonl(i_size >> 32);
1171 *bp++ = htonl((u32) i_size);
1173 trace_afs_make_fs_call(call, &vnode->fid);
1174 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1178 * store a set of pages
1180 int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
1181 pgoff_t first, pgoff_t last,
1182 unsigned offset, unsigned to)
1184 struct afs_vnode *vnode = fc->vnode;
1185 struct afs_call *call;
1186 struct afs_net *net = afs_v2net(vnode);
1187 loff_t size, pos, i_size;
1188 __be32 *bp;
1190 _enter(",%x,{%x:%u},,",
1191 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1193 size = (loff_t)to - (loff_t)offset;
1194 if (first != last)
1195 size += (loff_t)(last - first) << PAGE_SHIFT;
1196 pos = (loff_t)first << PAGE_SHIFT;
1197 pos += offset;
1199 i_size = i_size_read(&vnode->vfs_inode);
1200 if (pos + size > i_size)
1201 i_size = size + pos;
1203 _debug("size %llx, at %llx, i_size %llx",
1204 (unsigned long long) size, (unsigned long long) pos,
1205 (unsigned long long) i_size);
1207 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
1208 return afs_fs_store_data64(fc, mapping, first, last, offset, to,
1209 size, pos, i_size);
1211 call = afs_alloc_flat_call(net, &afs_RXFSStoreData,
1212 (4 + 6 + 3) * 4,
1213 (21 + 6) * 4);
1214 if (!call)
1215 return -ENOMEM;
1217 call->key = fc->key;
1218 call->mapping = mapping;
1219 call->reply[0] = vnode;
1220 call->first = first;
1221 call->last = last;
1222 call->first_offset = offset;
1223 call->last_to = to;
1224 call->send_pages = true;
1225 call->store_version = vnode->status.data_version + 1;
1227 /* marshall the parameters */
1228 bp = call->request;
1229 *bp++ = htonl(FSSTOREDATA);
1230 *bp++ = htonl(vnode->fid.vid);
1231 *bp++ = htonl(vnode->fid.vnode);
1232 *bp++ = htonl(vnode->fid.unique);
1234 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1235 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
1236 *bp++ = 0; /* owner */
1237 *bp++ = 0; /* group */
1238 *bp++ = 0; /* unix mode */
1239 *bp++ = 0; /* segment size */
1241 *bp++ = htonl(pos);
1242 *bp++ = htonl(size);
1243 *bp++ = htonl(i_size);
1245 afs_use_fs_server(call, fc->cbi);
1246 trace_afs_make_fs_call(call, &vnode->fid);
1247 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1251 * deliver reply data to an FS.StoreStatus
1253 static int afs_deliver_fs_store_status(struct afs_call *call)
1255 afs_dataversion_t *store_version;
1256 struct afs_vnode *vnode = call->reply[0];
1257 const __be32 *bp;
1258 int ret;
1260 _enter("");
1262 ret = afs_transfer_reply(call);
1263 if (ret < 0)
1264 return ret;
1266 /* unmarshall the reply once we've received all of it */
1267 store_version = NULL;
1268 if (call->operation_ID == FSSTOREDATA)
1269 store_version = &call->store_version;
1271 bp = call->buffer;
1272 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
1273 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1275 _leave(" = 0 [done]");
1276 return 0;
1280 * FS.StoreStatus operation type
1282 static const struct afs_call_type afs_RXFSStoreStatus = {
1283 .name = "FS.StoreStatus",
1284 .op = afs_FS_StoreStatus,
1285 .deliver = afs_deliver_fs_store_status,
1286 .destructor = afs_flat_call_destructor,
1289 static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1290 .name = "FS.StoreData",
1291 .op = afs_FS_StoreData,
1292 .deliver = afs_deliver_fs_store_status,
1293 .destructor = afs_flat_call_destructor,
1296 static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1297 .name = "FS.StoreData64",
1298 .op = afs_FS_StoreData64,
1299 .deliver = afs_deliver_fs_store_status,
1300 .destructor = afs_flat_call_destructor,
1304 * set the attributes on a very large file, using FS.StoreData rather than
1305 * FS.StoreStatus so as to alter the file size also
1307 static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
1309 struct afs_vnode *vnode = fc->vnode;
1310 struct afs_call *call;
1311 struct afs_net *net = afs_v2net(vnode);
1312 __be32 *bp;
1314 _enter(",%x,{%x:%u},,",
1315 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1317 ASSERT(attr->ia_valid & ATTR_SIZE);
1319 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,
1320 (4 + 6 + 3 * 2) * 4,
1321 (21 + 6) * 4);
1322 if (!call)
1323 return -ENOMEM;
1325 call->key = fc->key;
1326 call->reply[0] = vnode;
1327 call->store_version = vnode->status.data_version + 1;
1329 /* marshall the parameters */
1330 bp = call->request;
1331 *bp++ = htonl(FSSTOREDATA64);
1332 *bp++ = htonl(vnode->fid.vid);
1333 *bp++ = htonl(vnode->fid.vnode);
1334 *bp++ = htonl(vnode->fid.unique);
1336 xdr_encode_AFS_StoreStatus(&bp, attr);
1338 *bp++ = 0; /* position of start of write */
1339 *bp++ = 0;
1340 *bp++ = 0; /* size of write */
1341 *bp++ = 0;
1342 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1343 *bp++ = htonl((u32) attr->ia_size);
1345 afs_use_fs_server(call, fc->cbi);
1346 trace_afs_make_fs_call(call, &vnode->fid);
1347 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1351 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1352 * so as to alter the file size also
1354 static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
1356 struct afs_vnode *vnode = fc->vnode;
1357 struct afs_call *call;
1358 struct afs_net *net = afs_v2net(vnode);
1359 __be32 *bp;
1361 _enter(",%x,{%x:%u},,",
1362 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1364 ASSERT(attr->ia_valid & ATTR_SIZE);
1365 if (attr->ia_size >> 32)
1366 return afs_fs_setattr_size64(fc, attr);
1368 call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,
1369 (4 + 6 + 3) * 4,
1370 (21 + 6) * 4);
1371 if (!call)
1372 return -ENOMEM;
1374 call->key = fc->key;
1375 call->reply[0] = vnode;
1376 call->store_version = vnode->status.data_version + 1;
1378 /* marshall the parameters */
1379 bp = call->request;
1380 *bp++ = htonl(FSSTOREDATA);
1381 *bp++ = htonl(vnode->fid.vid);
1382 *bp++ = htonl(vnode->fid.vnode);
1383 *bp++ = htonl(vnode->fid.unique);
1385 xdr_encode_AFS_StoreStatus(&bp, attr);
1387 *bp++ = 0; /* position of start of write */
1388 *bp++ = 0; /* size of write */
1389 *bp++ = htonl(attr->ia_size); /* new file length */
1391 afs_use_fs_server(call, fc->cbi);
1392 trace_afs_make_fs_call(call, &vnode->fid);
1393 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1397 * set the attributes on a file, using FS.StoreData if there's a change in file
1398 * size, and FS.StoreStatus otherwise
1400 int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
1402 struct afs_vnode *vnode = fc->vnode;
1403 struct afs_call *call;
1404 struct afs_net *net = afs_v2net(vnode);
1405 __be32 *bp;
1407 if (attr->ia_valid & ATTR_SIZE)
1408 return afs_fs_setattr_size(fc, attr);
1410 _enter(",%x,{%x:%u},,",
1411 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1413 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,
1414 (4 + 6) * 4,
1415 (21 + 6) * 4);
1416 if (!call)
1417 return -ENOMEM;
1419 call->key = fc->key;
1420 call->reply[0] = vnode;
1422 /* marshall the parameters */
1423 bp = call->request;
1424 *bp++ = htonl(FSSTORESTATUS);
1425 *bp++ = htonl(vnode->fid.vid);
1426 *bp++ = htonl(vnode->fid.vnode);
1427 *bp++ = htonl(vnode->fid.unique);
1429 xdr_encode_AFS_StoreStatus(&bp, attr);
1431 afs_use_fs_server(call, fc->cbi);
1432 trace_afs_make_fs_call(call, &vnode->fid);
1433 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1437 * deliver reply data to an FS.GetVolumeStatus
1439 static int afs_deliver_fs_get_volume_status(struct afs_call *call)
1441 const __be32 *bp;
1442 char *p;
1443 int ret;
1445 _enter("{%u}", call->unmarshall);
1447 switch (call->unmarshall) {
1448 case 0:
1449 call->offset = 0;
1450 call->unmarshall++;
1452 /* extract the returned status record */
1453 case 1:
1454 _debug("extract status");
1455 ret = afs_extract_data(call, call->buffer,
1456 12 * 4, true);
1457 if (ret < 0)
1458 return ret;
1460 bp = call->buffer;
1461 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply[1]);
1462 call->offset = 0;
1463 call->unmarshall++;
1465 /* extract the volume name length */
1466 case 2:
1467 ret = afs_extract_data(call, &call->tmp, 4, true);
1468 if (ret < 0)
1469 return ret;
1471 call->count = ntohl(call->tmp);
1472 _debug("volname length: %u", call->count);
1473 if (call->count >= AFSNAMEMAX)
1474 return -EBADMSG;
1475 call->offset = 0;
1476 call->unmarshall++;
1478 /* extract the volume name */
1479 case 3:
1480 _debug("extract volname");
1481 if (call->count > 0) {
1482 ret = afs_extract_data(call, call->reply[2],
1483 call->count, true);
1484 if (ret < 0)
1485 return ret;
1488 p = call->reply[2];
1489 p[call->count] = 0;
1490 _debug("volname '%s'", p);
1492 call->offset = 0;
1493 call->unmarshall++;
1495 /* extract the volume name padding */
1496 if ((call->count & 3) == 0) {
1497 call->unmarshall++;
1498 goto no_volname_padding;
1500 call->count = 4 - (call->count & 3);
1502 case 4:
1503 ret = afs_extract_data(call, call->buffer,
1504 call->count, true);
1505 if (ret < 0)
1506 return ret;
1508 call->offset = 0;
1509 call->unmarshall++;
1510 no_volname_padding:
1512 /* extract the offline message length */
1513 case 5:
1514 ret = afs_extract_data(call, &call->tmp, 4, true);
1515 if (ret < 0)
1516 return ret;
1518 call->count = ntohl(call->tmp);
1519 _debug("offline msg length: %u", call->count);
1520 if (call->count >= AFSNAMEMAX)
1521 return -EBADMSG;
1522 call->offset = 0;
1523 call->unmarshall++;
1525 /* extract the offline message */
1526 case 6:
1527 _debug("extract offline");
1528 if (call->count > 0) {
1529 ret = afs_extract_data(call, call->reply[2],
1530 call->count, true);
1531 if (ret < 0)
1532 return ret;
1535 p = call->reply[2];
1536 p[call->count] = 0;
1537 _debug("offline '%s'", p);
1539 call->offset = 0;
1540 call->unmarshall++;
1542 /* extract the offline message padding */
1543 if ((call->count & 3) == 0) {
1544 call->unmarshall++;
1545 goto no_offline_padding;
1547 call->count = 4 - (call->count & 3);
1549 case 7:
1550 ret = afs_extract_data(call, call->buffer,
1551 call->count, true);
1552 if (ret < 0)
1553 return ret;
1555 call->offset = 0;
1556 call->unmarshall++;
1557 no_offline_padding:
1559 /* extract the message of the day length */
1560 case 8:
1561 ret = afs_extract_data(call, &call->tmp, 4, true);
1562 if (ret < 0)
1563 return ret;
1565 call->count = ntohl(call->tmp);
1566 _debug("motd length: %u", call->count);
1567 if (call->count >= AFSNAMEMAX)
1568 return -EBADMSG;
1569 call->offset = 0;
1570 call->unmarshall++;
1572 /* extract the message of the day */
1573 case 9:
1574 _debug("extract motd");
1575 if (call->count > 0) {
1576 ret = afs_extract_data(call, call->reply[2],
1577 call->count, true);
1578 if (ret < 0)
1579 return ret;
1582 p = call->reply[2];
1583 p[call->count] = 0;
1584 _debug("motd '%s'", p);
1586 call->offset = 0;
1587 call->unmarshall++;
1589 /* extract the message of the day padding */
1590 call->count = (4 - (call->count & 3)) & 3;
1592 case 10:
1593 ret = afs_extract_data(call, call->buffer,
1594 call->count, false);
1595 if (ret < 0)
1596 return ret;
1598 call->offset = 0;
1599 call->unmarshall++;
1600 case 11:
1601 break;
1604 _leave(" = 0 [done]");
1605 return 0;
1609 * destroy an FS.GetVolumeStatus call
1611 static void afs_get_volume_status_call_destructor(struct afs_call *call)
1613 kfree(call->reply[2]);
1614 call->reply[2] = NULL;
1615 afs_flat_call_destructor(call);
1619 * FS.GetVolumeStatus operation type
1621 static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1622 .name = "FS.GetVolumeStatus",
1623 .op = afs_FS_GetVolumeStatus,
1624 .deliver = afs_deliver_fs_get_volume_status,
1625 .destructor = afs_get_volume_status_call_destructor,
1629 * fetch the status of a volume
1631 int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
1632 struct afs_volume_status *vs)
1634 struct afs_vnode *vnode = fc->vnode;
1635 struct afs_call *call;
1636 struct afs_net *net = afs_v2net(vnode);
1637 __be32 *bp;
1638 void *tmpbuf;
1640 _enter("");
1642 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1643 if (!tmpbuf)
1644 return -ENOMEM;
1646 call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
1647 if (!call) {
1648 kfree(tmpbuf);
1649 return -ENOMEM;
1652 call->key = fc->key;
1653 call->reply[0] = vnode;
1654 call->reply[1] = vs;
1655 call->reply[2] = tmpbuf;
1657 /* marshall the parameters */
1658 bp = call->request;
1659 bp[0] = htonl(FSGETVOLUMESTATUS);
1660 bp[1] = htonl(vnode->fid.vid);
1662 afs_use_fs_server(call, fc->cbi);
1663 trace_afs_make_fs_call(call, &vnode->fid);
1664 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1668 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1670 static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
1672 const __be32 *bp;
1673 int ret;
1675 _enter("{%u}", call->unmarshall);
1677 ret = afs_transfer_reply(call);
1678 if (ret < 0)
1679 return ret;
1681 /* unmarshall the reply once we've received all of it */
1682 bp = call->buffer;
1683 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
1685 _leave(" = 0 [done]");
1686 return 0;
1690 * FS.SetLock operation type
1692 static const struct afs_call_type afs_RXFSSetLock = {
1693 .name = "FS.SetLock",
1694 .op = afs_FS_SetLock,
1695 .deliver = afs_deliver_fs_xxxx_lock,
1696 .destructor = afs_flat_call_destructor,
1700 * FS.ExtendLock operation type
1702 static const struct afs_call_type afs_RXFSExtendLock = {
1703 .name = "FS.ExtendLock",
1704 .op = afs_FS_ExtendLock,
1705 .deliver = afs_deliver_fs_xxxx_lock,
1706 .destructor = afs_flat_call_destructor,
1710 * FS.ReleaseLock operation type
1712 static const struct afs_call_type afs_RXFSReleaseLock = {
1713 .name = "FS.ReleaseLock",
1714 .op = afs_FS_ReleaseLock,
1715 .deliver = afs_deliver_fs_xxxx_lock,
1716 .destructor = afs_flat_call_destructor,
1720 * Set a lock on a file
1722 int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
1724 struct afs_vnode *vnode = fc->vnode;
1725 struct afs_call *call;
1726 struct afs_net *net = afs_v2net(vnode);
1727 __be32 *bp;
1729 _enter("");
1731 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
1732 if (!call)
1733 return -ENOMEM;
1735 call->key = fc->key;
1736 call->reply[0] = vnode;
1738 /* marshall the parameters */
1739 bp = call->request;
1740 *bp++ = htonl(FSSETLOCK);
1741 *bp++ = htonl(vnode->fid.vid);
1742 *bp++ = htonl(vnode->fid.vnode);
1743 *bp++ = htonl(vnode->fid.unique);
1744 *bp++ = htonl(type);
1746 afs_use_fs_server(call, fc->cbi);
1747 trace_afs_make_fs_call(call, &vnode->fid);
1748 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1752 * extend a lock on a file
1754 int afs_fs_extend_lock(struct afs_fs_cursor *fc)
1756 struct afs_vnode *vnode = fc->vnode;
1757 struct afs_call *call;
1758 struct afs_net *net = afs_v2net(vnode);
1759 __be32 *bp;
1761 _enter("");
1763 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
1764 if (!call)
1765 return -ENOMEM;
1767 call->key = fc->key;
1768 call->reply[0] = vnode;
1770 /* marshall the parameters */
1771 bp = call->request;
1772 *bp++ = htonl(FSEXTENDLOCK);
1773 *bp++ = htonl(vnode->fid.vid);
1774 *bp++ = htonl(vnode->fid.vnode);
1775 *bp++ = htonl(vnode->fid.unique);
1777 afs_use_fs_server(call, fc->cbi);
1778 trace_afs_make_fs_call(call, &vnode->fid);
1779 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1783 * release a lock on a file
1785 int afs_fs_release_lock(struct afs_fs_cursor *fc)
1787 struct afs_vnode *vnode = fc->vnode;
1788 struct afs_call *call;
1789 struct afs_net *net = afs_v2net(vnode);
1790 __be32 *bp;
1792 _enter("");
1794 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
1795 if (!call)
1796 return -ENOMEM;
1798 call->key = fc->key;
1799 call->reply[0] = vnode;
1801 /* marshall the parameters */
1802 bp = call->request;
1803 *bp++ = htonl(FSRELEASELOCK);
1804 *bp++ = htonl(vnode->fid.vid);
1805 *bp++ = htonl(vnode->fid.vnode);
1806 *bp++ = htonl(vnode->fid.unique);
1808 afs_use_fs_server(call, fc->cbi);
1809 trace_afs_make_fs_call(call, &vnode->fid);
1810 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
1814 * Deliver reply data to an FS.GiveUpAllCallBacks operation.
1816 static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)
1818 return afs_transfer_reply(call);
1822 * FS.GiveUpAllCallBacks operation type
1824 static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
1825 .name = "FS.GiveUpAllCallBacks",
1826 .op = afs_FS_GiveUpAllCallBacks,
1827 .deliver = afs_deliver_fs_give_up_all_callbacks,
1828 .destructor = afs_flat_call_destructor,
1832 * Flush all the callbacks we have on a server.
1834 int afs_fs_give_up_all_callbacks(struct afs_net *net,
1835 struct afs_server *server,
1836 struct afs_addr_cursor *ac,
1837 struct key *key)
1839 struct afs_call *call;
1840 __be32 *bp;
1842 _enter("");
1844 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);
1845 if (!call)
1846 return -ENOMEM;
1848 call->key = key;
1850 /* marshall the parameters */
1851 bp = call->request;
1852 *bp++ = htonl(FSGIVEUPALLCALLBACKS);
1854 /* Can't take a ref on server */
1855 return afs_make_call(ac, call, GFP_NOFS, false);
1859 * Deliver reply data to an FS.GetCapabilities operation.
1861 static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1863 u32 count;
1864 int ret;
1866 _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count);
1868 again:
1869 switch (call->unmarshall) {
1870 case 0:
1871 call->offset = 0;
1872 call->unmarshall++;
1874 /* Extract the capabilities word count */
1875 case 1:
1876 ret = afs_extract_data(call, &call->tmp,
1877 1 * sizeof(__be32),
1878 true);
1879 if (ret < 0)
1880 return ret;
1882 count = ntohl(call->tmp);
1884 call->count = count;
1885 call->count2 = count;
1886 call->offset = 0;
1887 call->unmarshall++;
1889 /* Extract capabilities words */
1890 case 2:
1891 count = min(call->count, 16U);
1892 ret = afs_extract_data(call, call->buffer,
1893 count * sizeof(__be32),
1894 call->count > 16);
1895 if (ret < 0)
1896 return ret;
1898 /* TODO: Examine capabilities */
1900 call->count -= count;
1901 if (call->count > 0)
1902 goto again;
1903 call->offset = 0;
1904 call->unmarshall++;
1905 break;
1908 _leave(" = 0 [done]");
1909 return 0;
1913 * FS.GetCapabilities operation type
1915 static const struct afs_call_type afs_RXFSGetCapabilities = {
1916 .name = "FS.GetCapabilities",
1917 .op = afs_FS_GetCapabilities,
1918 .deliver = afs_deliver_fs_get_capabilities,
1919 .destructor = afs_flat_call_destructor,
1923 * Probe a fileserver for the capabilities that it supports. This can
1924 * return up to 196 words.
1926 int afs_fs_get_capabilities(struct afs_net *net,
1927 struct afs_server *server,
1928 struct afs_addr_cursor *ac,
1929 struct key *key)
1931 struct afs_call *call;
1932 __be32 *bp;
1934 _enter("");
1936 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
1937 if (!call)
1938 return -ENOMEM;
1940 call->key = key;
1942 /* marshall the parameters */
1943 bp = call->request;
1944 *bp++ = htonl(FSGETCAPABILITIES);
1946 /* Can't take a ref on server */
1947 trace_afs_make_fs_call(call, NULL);
1948 return afs_make_call(ac, call, GFP_NOFS, false);