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