afs: Split wait from afs_make_call()
[linux-2.6-block.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>
a01179e6 16#include <linux/iversion.h>
1da177e4 17#include "internal.h"
08e0e7c8 18#include "afs_fs.h"
dd9fbcb8 19#include "xdr_fs.h"
30062bd1 20#include "protocol_yfs.h"
1da177e4 21
025db80c
DH
22static const struct afs_fid afs_zero_fid;
23
d2ddc776 24static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
c435ee34 25{
d2ddc776 26 call->cbi = afs_get_cb_interest(cbi);
c435ee34
DH
27}
28
260a9803
DH
29/*
30 * decode an AFSFid block
31 */
32static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
33{
34 const __be32 *bp = *_bp;
35
36 fid->vid = ntohl(*bp++);
37 fid->vnode = ntohl(*bp++);
38 fid->unique = ntohl(*bp++);
39 *_bp = bp;
40}
41
888b3384
DH
42/*
43 * Dump a bad file status record.
44 */
45static void xdr_dump_bad(const __be32 *bp)
46{
47 __be32 x[4];
48 int i;
49
50 pr_notice("AFS XDR: Bad status record\n");
51 for (i = 0; i < 5 * 4 * 4; i += 16) {
52 memcpy(x, bp, 16);
53 bp += 4;
54 pr_notice("%03x: %08x %08x %08x %08x\n",
55 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
56 }
57
58 memcpy(x, bp, 4);
59 pr_notice("0x50: %08x\n", ntohl(x[0]));
60}
61
1da177e4 62/*
dd9fbcb8 63 * Update the core inode struct from a returned status record.
1da177e4 64 */
dd9fbcb8
DH
65void afs_update_inode_from_status(struct afs_vnode *vnode,
66 struct afs_file_status *status,
67 const afs_dataversion_t *expected_version,
68 u8 flags)
1da177e4 69{
95582b00 70 struct timespec64 t;
08e0e7c8 71 umode_t mode;
dd9fbcb8 72
d4936803 73 t = status->mtime_client;
dd9fbcb8
DH
74 vnode->vfs_inode.i_ctime = t;
75 vnode->vfs_inode.i_mtime = t;
76 vnode->vfs_inode.i_atime = t;
77
78 if (flags & (AFS_VNODE_META_CHANGED | AFS_VNODE_NOT_YET_SET)) {
79 vnode->vfs_inode.i_uid = make_kuid(&init_user_ns, status->owner);
80 vnode->vfs_inode.i_gid = make_kgid(&init_user_ns, status->group);
81 set_nlink(&vnode->vfs_inode, status->nlink);
82
83 mode = vnode->vfs_inode.i_mode;
84 mode &= ~S_IALLUGO;
85 mode |= status->mode;
86 barrier();
87 vnode->vfs_inode.i_mode = mode;
88 }
89
90 if (!(flags & AFS_VNODE_NOT_YET_SET)) {
91 if (expected_version &&
92 *expected_version != status->data_version) {
3b6492df 93 _debug("vnode modified %llx on {%llx:%llu} [exp %llx]",
dd9fbcb8
DH
94 (unsigned long long) status->data_version,
95 vnode->fid.vid, vnode->fid.vnode,
96 (unsigned long long) *expected_version);
a4ff7401 97 vnode->invalid_before = status->data_version;
f3ddee8d
DH
98 if (vnode->status.type == AFS_FTYPE_DIR) {
99 if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
100 afs_stat_v(vnode, n_inval);
101 } else {
102 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
103 }
63a4681f
DH
104 } else if (vnode->status.type == AFS_FTYPE_DIR) {
105 /* Expected directory change is handled elsewhere so
106 * that we can locally edit the directory and save on a
107 * download.
108 */
109 if (test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
110 flags &= ~AFS_VNODE_DATA_CHANGED;
dd9fbcb8
DH
111 }
112 }
113
114 if (flags & (AFS_VNODE_DATA_CHANGED | AFS_VNODE_NOT_YET_SET)) {
115 inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
116 i_size_write(&vnode->vfs_inode, status->size);
117 }
118}
119
120/*
121 * decode an AFSFetchStatus block
122 */
5f702c8e
DH
123static int xdr_decode_AFSFetchStatus(struct afs_call *call,
124 const __be32 **_bp,
dd9fbcb8
DH
125 struct afs_file_status *status,
126 struct afs_vnode *vnode,
127 const afs_dataversion_t *expected_version,
f3ddee8d 128 struct afs_read *read_req)
dd9fbcb8
DH
129{
130 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
684b0f68 131 bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
260a9803 132 u64 data_version, size;
dd9fbcb8
DH
133 u32 type, abort_code;
134 u8 flags = 0;
c435ee34 135
684b0f68
DH
136 abort_code = ntohl(xdr->abort_code);
137
dd9fbcb8 138 if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {
684b0f68
DH
139 if (xdr->if_version == htonl(0) &&
140 abort_code != 0 &&
141 inline_error) {
142 /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus
143 * whereby it doesn't set the interface version in the error
144 * case.
145 */
146 status->abort_code = abort_code;
de52cf92 147 return 0;
684b0f68
DH
148 }
149
dd9fbcb8
DH
150 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
151 goto bad;
152 }
08e0e7c8 153
684b0f68
DH
154 if (abort_code != 0 && inline_error) {
155 status->abort_code = abort_code;
de52cf92 156 return 0;
684b0f68
DH
157 }
158
dd9fbcb8 159 type = ntohl(xdr->type);
dd9fbcb8 160 switch (type) {
888b3384
DH
161 case AFS_FTYPE_FILE:
162 case AFS_FTYPE_DIR:
163 case AFS_FTYPE_SYMLINK:
dd9fbcb8
DH
164 if (type != status->type &&
165 vnode &&
166 !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
3b6492df 167 pr_warning("Vnode %llx:%llx:%x changed type %u to %u\n",
dd9fbcb8
DH
168 vnode->fid.vid,
169 vnode->fid.vnode,
170 vnode->fid.unique,
171 status->type, type);
172 goto bad;
173 }
174 status->type = type;
888b3384 175 break;
888b3384 176 default:
dd9fbcb8 177 goto bad;
888b3384
DH
178 }
179
dd9fbcb8
DH
180#define EXTRACT_M(FIELD) \
181 do { \
182 u32 x = ntohl(xdr->FIELD); \
183 if (status->FIELD != x) { \
184 flags |= AFS_VNODE_META_CHANGED; \
185 status->FIELD = x; \
186 } \
187 } while (0)
188
189 EXTRACT_M(nlink);
190 EXTRACT_M(author);
191 EXTRACT_M(owner);
192 EXTRACT_M(caller_access); /* call ticket dependent */
193 EXTRACT_M(anon_access);
194 EXTRACT_M(mode);
195 EXTRACT_M(group);
196
d4936803
DH
197 status->mtime_client.tv_sec = ntohl(xdr->mtime_client);
198 status->mtime_client.tv_nsec = 0;
199 status->mtime_server.tv_sec = ntohl(xdr->mtime_server);
200 status->mtime_server.tv_nsec = 0;
dd9fbcb8
DH
201 status->lock_count = ntohl(xdr->lock_count);
202
203 size = (u64)ntohl(xdr->size_lo);
204 size |= (u64)ntohl(xdr->size_hi) << 32;
63a4681f 205 status->size = size;
dd9fbcb8
DH
206
207 data_version = (u64)ntohl(xdr->data_version_lo);
208 data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
209 if (data_version != status->data_version) {
210 status->data_version = data_version;
211 flags |= AFS_VNODE_DATA_CHANGED;
08e0e7c8 212 }
f3ddee8d
DH
213
214 if (read_req) {
215 read_req->data_version = data_version;
216 read_req->file_size = size;
217 }
08e0e7c8 218
dd9fbcb8 219 *_bp = (const void *)*_bp + sizeof(*xdr);
260a9803
DH
220
221 if (vnode) {
dd9fbcb8
DH
222 if (test_bit(AFS_VNODE_UNSET, &vnode->flags))
223 flags |= AFS_VNODE_NOT_YET_SET;
224 afs_update_inode_from_status(vnode, status, expected_version,
225 flags);
260a9803
DH
226 }
227
c875c76a 228 return 0;
dd9fbcb8
DH
229
230bad:
231 xdr_dump_bad(*_bp);
160cb957 232 return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
c875c76a
DH
233}
234
235/*
236 * Decode the file status. We need to lock the target vnode if we're going to
237 * update its status so that stat() sees the attributes update atomically.
238 */
239static int afs_decode_status(struct afs_call *call,
240 const __be32 **_bp,
241 struct afs_file_status *status,
242 struct afs_vnode *vnode,
243 const afs_dataversion_t *expected_version,
244 struct afs_read *read_req)
245{
246 int ret;
247
248 if (!vnode)
249 return xdr_decode_AFSFetchStatus(call, _bp, status, vnode,
250 expected_version, read_req);
251
252 write_seqlock(&vnode->cb_lock);
253 ret = xdr_decode_AFSFetchStatus(call, _bp, status, vnode,
254 expected_version, read_req);
255 write_sequnlock(&vnode->cb_lock);
256 return ret;
ec26815a 257}
1da177e4 258
1da177e4 259/*
08e0e7c8 260 * decode an AFSCallBack block
1da177e4 261 */
c435ee34
DH
262static void xdr_decode_AFSCallBack(struct afs_call *call,
263 struct afs_vnode *vnode,
264 const __be32 **_bp)
1da177e4 265{
d2ddc776 266 struct afs_cb_interest *old, *cbi = call->cbi;
08e0e7c8 267 const __be32 *bp = *_bp;
c435ee34
DH
268 u32 cb_expiry;
269
270 write_seqlock(&vnode->cb_lock);
271
18ac6185 272 if (!afs_cb_is_broken(call->cb_break, vnode, cbi)) {
c435ee34
DH
273 vnode->cb_version = ntohl(*bp++);
274 cb_expiry = ntohl(*bp++);
275 vnode->cb_type = ntohl(*bp++);
276 vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds();
d2ddc776
DH
277 old = vnode->cb_interest;
278 if (old != call->cbi) {
279 vnode->cb_interest = cbi;
280 cbi = old;
281 }
c435ee34
DH
282 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
283 } else {
284 bp += 3;
285 }
1da177e4 286
c435ee34 287 write_sequnlock(&vnode->cb_lock);
d2ddc776 288 call->cbi = cbi;
08e0e7c8 289 *_bp = bp;
ec26815a 290}
1da177e4 291
12d8e95a
DH
292static ktime_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
293{
294 return ktime_add_ns(call->reply_time, expiry * NSEC_PER_SEC);
295}
296
297static void xdr_decode_AFSCallBack_raw(struct afs_call *call,
298 const __be32 **_bp,
260a9803
DH
299 struct afs_callback *cb)
300{
301 const __be32 *bp = *_bp;
302
303 cb->version = ntohl(*bp++);
12d8e95a 304 cb->expires_at = xdr_decode_expiry(call, ntohl(*bp++));
260a9803
DH
305 cb->type = ntohl(*bp++);
306 *_bp = bp;
307}
308
1da177e4 309/*
08e0e7c8 310 * decode an AFSVolSync block
1da177e4 311 */
08e0e7c8
DH
312static void xdr_decode_AFSVolSync(const __be32 **_bp,
313 struct afs_volsync *volsync)
1da177e4 314{
08e0e7c8 315 const __be32 *bp = *_bp;
30062bd1 316 u32 creation;
1da177e4 317
30062bd1 318 creation = ntohl(*bp++);
08e0e7c8
DH
319 bp++; /* spare2 */
320 bp++; /* spare3 */
321 bp++; /* spare4 */
322 bp++; /* spare5 */
323 bp++; /* spare6 */
324 *_bp = bp;
30062bd1
DH
325
326 if (volsync)
327 volsync->creation = creation;
08e0e7c8 328}
1da177e4 329
31143d5d
DH
330/*
331 * encode the requested attributes into an AFSStoreStatus block
332 */
333static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
334{
335 __be32 *bp = *_bp;
336 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
337
338 mask = 0;
339 if (attr->ia_valid & ATTR_MTIME) {
340 mask |= AFS_SET_MTIME;
341 mtime = attr->ia_mtime.tv_sec;
342 }
343
344 if (attr->ia_valid & ATTR_UID) {
345 mask |= AFS_SET_OWNER;
a0a5386a 346 owner = from_kuid(&init_user_ns, attr->ia_uid);
31143d5d
DH
347 }
348
349 if (attr->ia_valid & ATTR_GID) {
350 mask |= AFS_SET_GROUP;
a0a5386a 351 group = from_kgid(&init_user_ns, attr->ia_gid);
31143d5d
DH
352 }
353
354 if (attr->ia_valid & ATTR_MODE) {
355 mask |= AFS_SET_MODE;
356 mode = attr->ia_mode & S_IALLUGO;
357 }
358
359 *bp++ = htonl(mask);
360 *bp++ = htonl(mtime);
361 *bp++ = htonl(owner);
362 *bp++ = htonl(group);
363 *bp++ = htonl(mode);
364 *bp++ = 0; /* segment size */
365 *_bp = bp;
366}
367
45222b9e
DH
368/*
369 * decode an AFSFetchVolumeStatus block
370 */
371static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
372 struct afs_volume_status *vs)
373{
374 const __be32 *bp = *_bp;
375
376 vs->vid = ntohl(*bp++);
377 vs->parent_id = ntohl(*bp++);
378 vs->online = ntohl(*bp++);
379 vs->in_service = ntohl(*bp++);
380 vs->blessed = ntohl(*bp++);
381 vs->needs_salvage = ntohl(*bp++);
382 vs->type = ntohl(*bp++);
383 vs->min_quota = ntohl(*bp++);
384 vs->max_quota = ntohl(*bp++);
385 vs->blocks_in_use = ntohl(*bp++);
386 vs->part_blocks_avail = ntohl(*bp++);
387 vs->part_max_blocks = ntohl(*bp++);
30062bd1
DH
388 vs->vol_copy_date = 0;
389 vs->vol_backup_date = 0;
45222b9e
DH
390 *_bp = bp;
391}
392
08e0e7c8
DH
393/*
394 * deliver reply data to an FS.FetchStatus
395 */
5cf9dd55 396static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)
08e0e7c8 397{
97e3043a 398 struct afs_vnode *vnode = call->reply[0];
08e0e7c8 399 const __be32 *bp;
372ee163 400 int ret;
1da177e4 401
d001648e 402 ret = afs_transfer_reply(call);
372ee163
DH
403 if (ret < 0)
404 return ret;
1da177e4 405
3b6492df 406 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
c435ee34 407
08e0e7c8
DH
408 /* unmarshall the reply once we've received all of it */
409 bp = call->buffer;
160cb957
DH
410 ret = afs_decode_status(call, &bp, &vnode->status, vnode,
411 &call->expected_version, NULL);
412 if (ret < 0)
413 return ret;
c435ee34 414 xdr_decode_AFSCallBack(call, vnode, &bp);
30062bd1 415 xdr_decode_AFSVolSync(&bp, call->reply[1]);
1da177e4 416
08e0e7c8
DH
417 _leave(" = 0 [done]");
418 return 0;
ec26815a 419}
08e0e7c8
DH
420
421/*
422 * FS.FetchStatus operation type
423 */
5cf9dd55
DH
424static const struct afs_call_type afs_RXFSFetchStatus_vnode = {
425 .name = "FS.FetchStatus(vnode)",
025db80c 426 .op = afs_FS_FetchStatus,
5cf9dd55 427 .deliver = afs_deliver_fs_fetch_status_vnode,
08e0e7c8
DH
428 .destructor = afs_flat_call_destructor,
429};
1da177e4 430
1da177e4
LT
431/*
432 * fetch the status information for a file
433 */
0c3a5ac2
DH
434int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync,
435 bool new_inode)
1da177e4 436{
d2ddc776 437 struct afs_vnode *vnode = fc->vnode;
08e0e7c8 438 struct afs_call *call;
f044c884 439 struct afs_net *net = afs_v2net(vnode);
1da177e4
LT
440 __be32 *bp;
441
30062bd1
DH
442 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
443 return yfs_fs_fetch_file_status(fc, volsync, new_inode);
444
3b6492df 445 _enter(",%x,{%llx:%llu},,",
d2ddc776 446 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1da177e4 447
5cf9dd55
DH
448 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus_vnode,
449 16, (21 + 3 + 6) * 4);
d2ddc776
DH
450 if (!call) {
451 fc->ac.error = -ENOMEM;
08e0e7c8 452 return -ENOMEM;
d2ddc776 453 }
1da177e4 454
d2ddc776 455 call->key = fc->key;
97e3043a
DH
456 call->reply[0] = vnode;
457 call->reply[1] = volsync;
0c3a5ac2 458 call->expected_version = new_inode ? 1 : vnode->status.data_version;
12d8e95a 459 call->want_reply_time = true;
1da177e4
LT
460
461 /* marshall the parameters */
08e0e7c8 462 bp = call->request;
1da177e4
LT
463 bp[0] = htonl(FSFETCHSTATUS);
464 bp[1] = htonl(vnode->fid.vid);
465 bp[2] = htonl(vnode->fid.vnode);
466 bp[3] = htonl(vnode->fid.unique);
467
d2ddc776
DH
468 call->cb_break = fc->cb_break;
469 afs_use_fs_server(call, fc->cbi);
025db80c 470 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
471
472 afs_make_call(&fc->ac, call, GFP_NOFS);
473 return afs_wait_for_call_to_complete(call, &fc->ac);
ec26815a 474}
1da177e4 475
1da177e4 476/*
08e0e7c8 477 * deliver reply data to an FS.FetchData
1da177e4 478 */
d001648e 479static int afs_deliver_fs_fetch_data(struct afs_call *call)
1da177e4 480{
97e3043a
DH
481 struct afs_vnode *vnode = call->reply[0];
482 struct afs_read *req = call->reply[2];
08e0e7c8 483 const __be32 *bp;
196ee9cd 484 unsigned int size;
1da177e4 485 int ret;
1da177e4 486
12bdcf33
DH
487 _enter("{%u,%zu/%llu}",
488 call->unmarshall, iov_iter_count(&call->iter), req->actual_len);
08e0e7c8
DH
489
490 switch (call->unmarshall) {
491 case 0:
196ee9cd 492 req->actual_len = 0;
12bdcf33
DH
493 req->index = 0;
494 req->offset = req->pos & (PAGE_SIZE - 1);
08e0e7c8 495 call->unmarshall++;
12bdcf33
DH
496 if (call->operation_ID == FSFETCHDATA64) {
497 afs_extract_to_tmp64(call);
498 } else {
499 call->tmp_u = htonl(0);
500 afs_extract_to_tmp(call);
b9b1f8d5 501 }
08e0e7c8 502
b9b1f8d5 503 /* extract the returned data length */
12bdcf33 504 case 1:
08e0e7c8 505 _debug("extract data length");
12bdcf33 506 ret = afs_extract_data(call, true);
372ee163
DH
507 if (ret < 0)
508 return ret;
1da177e4 509
12bdcf33 510 req->actual_len = be64_to_cpu(call->tmp64);
196ee9cd 511 _debug("DATA length: %llu", req->actual_len);
12bdcf33
DH
512 req->remain = min(req->len, req->actual_len);
513 if (req->remain == 0)
196ee9cd 514 goto no_more_data;
12bdcf33 515
08e0e7c8
DH
516 call->unmarshall++;
517
196ee9cd 518 begin_page:
6db3ac3c 519 ASSERTCMP(req->index, <, req->nr_pages);
12bdcf33
DH
520 if (req->remain > PAGE_SIZE - req->offset)
521 size = PAGE_SIZE - req->offset;
196ee9cd
DH
522 else
523 size = req->remain;
12bdcf33
DH
524 call->bvec[0].bv_len = size;
525 call->bvec[0].bv_offset = req->offset;
526 call->bvec[0].bv_page = req->pages[req->index];
527 iov_iter_bvec(&call->iter, READ, call->bvec, 1, size);
528 ASSERTCMP(size, <=, PAGE_SIZE);
196ee9cd 529
08e0e7c8 530 /* extract the returned data */
12bdcf33
DH
531 case 2:
532 _debug("extract data %zu/%llu",
533 iov_iter_count(&call->iter), req->remain);
196ee9cd 534
12bdcf33 535 ret = afs_extract_data(call, true);
196ee9cd
DH
536 if (ret < 0)
537 return ret;
12bdcf33
DH
538 req->remain -= call->bvec[0].bv_len;
539 req->offset += call->bvec[0].bv_len;
540 ASSERTCMP(req->offset, <=, PAGE_SIZE);
541 if (req->offset == PAGE_SIZE) {
542 req->offset = 0;
196ee9cd
DH
543 if (req->page_done)
544 req->page_done(call, req);
29f06985 545 req->index++;
12bdcf33 546 if (req->remain > 0)
196ee9cd 547 goto begin_page;
08e0e7c8 548 }
12bdcf33
DH
549
550 ASSERTCMP(req->remain, ==, 0);
551 if (req->actual_len <= req->len)
552 goto no_more_data;
6db3ac3c
DH
553
554 /* Discard any excess data the server gave us */
12bdcf33
DH
555 iov_iter_discard(&call->iter, READ, req->actual_len - req->len);
556 call->unmarshall = 3;
557 case 3:
558 _debug("extract discard %zu/%llu",
559 iov_iter_count(&call->iter), req->actual_len - req->len);
560
561 ret = afs_extract_data(call, true);
6db3ac3c
DH
562 if (ret < 0)
563 return ret;
1da177e4 564
196ee9cd 565 no_more_data:
12bdcf33
DH
566 call->unmarshall = 4;
567 afs_extract_to_buf(call, (21 + 3 + 6) * 4);
1da177e4 568
08e0e7c8 569 /* extract the metadata */
12bdcf33
DH
570 case 4:
571 ret = afs_extract_data(call, false);
372ee163
DH
572 if (ret < 0)
573 return ret;
08e0e7c8
DH
574
575 bp = call->buffer;
160cb957
DH
576 ret = afs_decode_status(call, &bp, &vnode->status, vnode,
577 &vnode->status.data_version, req);
578 if (ret < 0)
579 return ret;
c435ee34 580 xdr_decode_AFSCallBack(call, vnode, &bp);
30062bd1 581 xdr_decode_AFSVolSync(&bp, call->reply[1]);
08e0e7c8 582
08e0e7c8 583 call->unmarshall++;
1da177e4 584
12bdcf33 585 case 5:
08e0e7c8 586 break;
1da177e4
LT
587 }
588
6db3ac3c 589 for (; req->index < req->nr_pages; req->index++) {
12bdcf33 590 if (req->offset < PAGE_SIZE)
6db3ac3c 591 zero_user_segment(req->pages[req->index],
12bdcf33 592 req->offset, PAGE_SIZE);
196ee9cd
DH
593 if (req->page_done)
594 req->page_done(call, req);
12bdcf33 595 req->offset = 0;
416351f2
DH
596 }
597
08e0e7c8
DH
598 _leave(" = 0 [done]");
599 return 0;
ec26815a 600}
1da177e4 601
196ee9cd
DH
602static void afs_fetch_data_destructor(struct afs_call *call)
603{
97e3043a 604 struct afs_read *req = call->reply[2];
196ee9cd
DH
605
606 afs_put_read(req);
607 afs_flat_call_destructor(call);
608}
609
1da177e4 610/*
08e0e7c8 611 * FS.FetchData operation type
1da177e4 612 */
08e0e7c8 613static const struct afs_call_type afs_RXFSFetchData = {
00d3b7a4 614 .name = "FS.FetchData",
025db80c 615 .op = afs_FS_FetchData,
08e0e7c8 616 .deliver = afs_deliver_fs_fetch_data,
196ee9cd 617 .destructor = afs_fetch_data_destructor,
08e0e7c8
DH
618};
619
b9b1f8d5
DH
620static const struct afs_call_type afs_RXFSFetchData64 = {
621 .name = "FS.FetchData64",
025db80c 622 .op = afs_FS_FetchData64,
b9b1f8d5 623 .deliver = afs_deliver_fs_fetch_data,
196ee9cd 624 .destructor = afs_fetch_data_destructor,
b9b1f8d5
DH
625};
626
627/*
628 * fetch data from a very large file
629 */
d2ddc776 630static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
b9b1f8d5 631{
d2ddc776 632 struct afs_vnode *vnode = fc->vnode;
b9b1f8d5 633 struct afs_call *call;
f044c884 634 struct afs_net *net = afs_v2net(vnode);
b9b1f8d5
DH
635 __be32 *bp;
636
637 _enter("");
638
f044c884 639 call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
b9b1f8d5
DH
640 if (!call)
641 return -ENOMEM;
642
d2ddc776 643 call->key = fc->key;
97e3043a
DH
644 call->reply[0] = vnode;
645 call->reply[1] = NULL; /* volsync */
646 call->reply[2] = req;
0c3a5ac2 647 call->expected_version = vnode->status.data_version;
12d8e95a 648 call->want_reply_time = true;
b9b1f8d5
DH
649
650 /* marshall the parameters */
651 bp = call->request;
652 bp[0] = htonl(FSFETCHDATA64);
653 bp[1] = htonl(vnode->fid.vid);
654 bp[2] = htonl(vnode->fid.vnode);
655 bp[3] = htonl(vnode->fid.unique);
196ee9cd
DH
656 bp[4] = htonl(upper_32_bits(req->pos));
657 bp[5] = htonl(lower_32_bits(req->pos));
b9b1f8d5 658 bp[6] = 0;
196ee9cd 659 bp[7] = htonl(lower_32_bits(req->len));
b9b1f8d5 660
f3ddee8d 661 refcount_inc(&req->usage);
d2ddc776
DH
662 call->cb_break = fc->cb_break;
663 afs_use_fs_server(call, fc->cbi);
025db80c 664 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
665 afs_make_call(&fc->ac, call, GFP_NOFS);
666 return afs_wait_for_call_to_complete(call, &fc->ac);
b9b1f8d5
DH
667}
668
08e0e7c8
DH
669/*
670 * fetch data from a file
671 */
d2ddc776 672int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
1da177e4 673{
d2ddc776 674 struct afs_vnode *vnode = fc->vnode;
08e0e7c8 675 struct afs_call *call;
f044c884 676 struct afs_net *net = afs_v2net(vnode);
1da177e4
LT
677 __be32 *bp;
678
30062bd1
DH
679 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
680 return yfs_fs_fetch_data(fc, req);
681
196ee9cd
DH
682 if (upper_32_bits(req->pos) ||
683 upper_32_bits(req->len) ||
684 upper_32_bits(req->pos + req->len))
d2ddc776 685 return afs_fs_fetch_data64(fc, req);
b9b1f8d5 686
08e0e7c8 687 _enter("");
1da177e4 688
f044c884 689 call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
08e0e7c8
DH
690 if (!call)
691 return -ENOMEM;
1da177e4 692
d2ddc776 693 call->key = fc->key;
97e3043a
DH
694 call->reply[0] = vnode;
695 call->reply[1] = NULL; /* volsync */
696 call->reply[2] = req;
0c3a5ac2 697 call->expected_version = vnode->status.data_version;
12d8e95a 698 call->want_reply_time = true;
1da177e4
LT
699
700 /* marshall the parameters */
08e0e7c8
DH
701 bp = call->request;
702 bp[0] = htonl(FSFETCHDATA);
703 bp[1] = htonl(vnode->fid.vid);
704 bp[2] = htonl(vnode->fid.vnode);
705 bp[3] = htonl(vnode->fid.unique);
196ee9cd
DH
706 bp[4] = htonl(lower_32_bits(req->pos));
707 bp[5] = htonl(lower_32_bits(req->len));
1da177e4 708
f3ddee8d 709 refcount_inc(&req->usage);
d2ddc776
DH
710 call->cb_break = fc->cb_break;
711 afs_use_fs_server(call, fc->cbi);
025db80c 712 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
713 afs_make_call(&fc->ac, call, GFP_NOFS);
714 return afs_wait_for_call_to_complete(call, &fc->ac);
ec26815a 715}
260a9803
DH
716
717/*
718 * deliver reply data to an FS.CreateFile or an FS.MakeDir
719 */
d001648e 720static int afs_deliver_fs_create_vnode(struct afs_call *call)
260a9803 721{
97e3043a 722 struct afs_vnode *vnode = call->reply[0];
260a9803 723 const __be32 *bp;
372ee163 724 int ret;
260a9803 725
d001648e 726 _enter("{%u}", call->unmarshall);
260a9803 727
d001648e 728 ret = afs_transfer_reply(call);
372ee163
DH
729 if (ret < 0)
730 return ret;
260a9803
DH
731
732 /* unmarshall the reply once we've received all of it */
733 bp = call->buffer;
97e3043a 734 xdr_decode_AFSFid(&bp, call->reply[1]);
160cb957
DH
735 ret = afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
736 if (ret < 0)
737 return ret;
738 ret = afs_decode_status(call, &bp, &vnode->status, vnode,
739 &call->expected_version, NULL);
740 if (ret < 0)
741 return ret;
12d8e95a 742 xdr_decode_AFSCallBack_raw(call, &bp, call->reply[3]);
97e3043a 743 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
744
745 _leave(" = 0 [done]");
746 return 0;
747}
748
749/*
750 * FS.CreateFile and FS.MakeDir operation type
751 */
025db80c
DH
752static const struct afs_call_type afs_RXFSCreateFile = {
753 .name = "FS.CreateFile",
754 .op = afs_FS_CreateFile,
755 .deliver = afs_deliver_fs_create_vnode,
756 .destructor = afs_flat_call_destructor,
757};
758
759static const struct afs_call_type afs_RXFSMakeDir = {
760 .name = "FS.MakeDir",
761 .op = afs_FS_MakeDir,
260a9803 762 .deliver = afs_deliver_fs_create_vnode,
260a9803
DH
763 .destructor = afs_flat_call_destructor,
764};
765
766/*
767 * create a file or make a directory
768 */
8b2a464c 769int afs_fs_create(struct afs_fs_cursor *fc,
260a9803
DH
770 const char *name,
771 umode_t mode,
63a4681f 772 u64 current_data_version,
260a9803
DH
773 struct afs_fid *newfid,
774 struct afs_file_status *newstatus,
d2ddc776 775 struct afs_callback *newcb)
260a9803 776{
d2ddc776 777 struct afs_vnode *vnode = fc->vnode;
260a9803 778 struct afs_call *call;
f044c884 779 struct afs_net *net = afs_v2net(vnode);
260a9803
DH
780 size_t namesz, reqsz, padsz;
781 __be32 *bp;
782
30062bd1
DH
783 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags)){
784 if (S_ISDIR(mode))
785 return yfs_fs_make_dir(fc, name, mode, current_data_version,
786 newfid, newstatus, newcb);
787 else
788 return yfs_fs_create_file(fc, name, mode, current_data_version,
789 newfid, newstatus, newcb);
790 }
791
260a9803
DH
792 _enter("");
793
794 namesz = strlen(name);
795 padsz = (4 - (namesz & 3)) & 3;
796 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
797
025db80c
DH
798 call = afs_alloc_flat_call(
799 net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile,
800 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
260a9803
DH
801 if (!call)
802 return -ENOMEM;
803
d2ddc776 804 call->key = fc->key;
97e3043a
DH
805 call->reply[0] = vnode;
806 call->reply[1] = newfid;
807 call->reply[2] = newstatus;
808 call->reply[3] = newcb;
63a4681f 809 call->expected_version = current_data_version + 1;
12d8e95a 810 call->want_reply_time = true;
260a9803
DH
811
812 /* marshall the parameters */
813 bp = call->request;
814 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
815 *bp++ = htonl(vnode->fid.vid);
816 *bp++ = htonl(vnode->fid.vnode);
817 *bp++ = htonl(vnode->fid.unique);
818 *bp++ = htonl(namesz);
819 memcpy(bp, name, namesz);
820 bp = (void *) bp + namesz;
821 if (padsz > 0) {
822 memset(bp, 0, padsz);
823 bp = (void *) bp + padsz;
824 }
ab94f5d0
MD
825 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
826 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
260a9803
DH
827 *bp++ = 0; /* owner */
828 *bp++ = 0; /* group */
829 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
830 *bp++ = 0; /* segment size */
831
d2ddc776 832 afs_use_fs_server(call, fc->cbi);
025db80c 833 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
834 afs_make_call(&fc->ac, call, GFP_NOFS);
835 return afs_wait_for_call_to_complete(call, &fc->ac);
260a9803
DH
836}
837
838/*
839 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
840 */
d001648e 841static int afs_deliver_fs_remove(struct afs_call *call)
260a9803 842{
97e3043a 843 struct afs_vnode *vnode = call->reply[0];
260a9803 844 const __be32 *bp;
372ee163 845 int ret;
260a9803 846
d001648e 847 _enter("{%u}", call->unmarshall);
260a9803 848
d001648e 849 ret = afs_transfer_reply(call);
372ee163
DH
850 if (ret < 0)
851 return ret;
260a9803
DH
852
853 /* unmarshall the reply once we've received all of it */
854 bp = call->buffer;
160cb957
DH
855 ret = afs_decode_status(call, &bp, &vnode->status, vnode,
856 &call->expected_version, NULL);
857 if (ret < 0)
858 return ret;
97e3043a 859 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
860
861 _leave(" = 0 [done]");
862 return 0;
863}
864
865/*
866 * FS.RemoveDir/FS.RemoveFile operation type
867 */
025db80c
DH
868static const struct afs_call_type afs_RXFSRemoveFile = {
869 .name = "FS.RemoveFile",
870 .op = afs_FS_RemoveFile,
871 .deliver = afs_deliver_fs_remove,
872 .destructor = afs_flat_call_destructor,
873};
874
875static const struct afs_call_type afs_RXFSRemoveDir = {
876 .name = "FS.RemoveDir",
877 .op = afs_FS_RemoveDir,
260a9803 878 .deliver = afs_deliver_fs_remove,
260a9803
DH
879 .destructor = afs_flat_call_destructor,
880};
881
882/*
883 * remove a file or directory
884 */
30062bd1
DH
885int afs_fs_remove(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
886 const char *name, bool isdir, u64 current_data_version)
260a9803 887{
30062bd1 888 struct afs_vnode *dvnode = fc->vnode;
260a9803 889 struct afs_call *call;
30062bd1 890 struct afs_net *net = afs_v2net(dvnode);
260a9803
DH
891 size_t namesz, reqsz, padsz;
892 __be32 *bp;
893
30062bd1
DH
894 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
895 return yfs_fs_remove(fc, vnode, name, isdir, current_data_version);
896
260a9803
DH
897 _enter("");
898
899 namesz = strlen(name);
900 padsz = (4 - (namesz & 3)) & 3;
901 reqsz = (5 * 4) + namesz + padsz;
902
025db80c
DH
903 call = afs_alloc_flat_call(
904 net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile,
905 reqsz, (21 + 6) * 4);
260a9803
DH
906 if (!call)
907 return -ENOMEM;
908
d2ddc776 909 call->key = fc->key;
30062bd1
DH
910 call->reply[0] = dvnode;
911 call->reply[1] = vnode;
63a4681f 912 call->expected_version = current_data_version + 1;
260a9803
DH
913
914 /* marshall the parameters */
915 bp = call->request;
916 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
30062bd1
DH
917 *bp++ = htonl(dvnode->fid.vid);
918 *bp++ = htonl(dvnode->fid.vnode);
919 *bp++ = htonl(dvnode->fid.unique);
260a9803
DH
920 *bp++ = htonl(namesz);
921 memcpy(bp, name, namesz);
922 bp = (void *) bp + namesz;
923 if (padsz > 0) {
924 memset(bp, 0, padsz);
925 bp = (void *) bp + padsz;
926 }
927
d2ddc776 928 afs_use_fs_server(call, fc->cbi);
30062bd1 929 trace_afs_make_fs_call(call, &dvnode->fid);
0b9bf381
DH
930 afs_make_call(&fc->ac, call, GFP_NOFS);
931 return afs_wait_for_call_to_complete(call, &fc->ac);
260a9803
DH
932}
933
934/*
935 * deliver reply data to an FS.Link
936 */
d001648e 937static int afs_deliver_fs_link(struct afs_call *call)
260a9803 938{
97e3043a 939 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
260a9803 940 const __be32 *bp;
372ee163 941 int ret;
260a9803 942
d001648e 943 _enter("{%u}", call->unmarshall);
260a9803 944
d001648e 945 ret = afs_transfer_reply(call);
372ee163
DH
946 if (ret < 0)
947 return ret;
260a9803
DH
948
949 /* unmarshall the reply once we've received all of it */
950 bp = call->buffer;
160cb957
DH
951 ret = afs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
952 if (ret < 0)
953 return ret;
954 ret = afs_decode_status(call, &bp, &dvnode->status, dvnode,
955 &call->expected_version, NULL);
956 if (ret < 0)
957 return ret;
97e3043a 958 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
959
960 _leave(" = 0 [done]");
961 return 0;
962}
963
964/*
965 * FS.Link operation type
966 */
967static const struct afs_call_type afs_RXFSLink = {
968 .name = "FS.Link",
025db80c 969 .op = afs_FS_Link,
260a9803 970 .deliver = afs_deliver_fs_link,
260a9803
DH
971 .destructor = afs_flat_call_destructor,
972};
973
974/*
975 * make a hard link
976 */
d2ddc776 977int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
63a4681f 978 const char *name, u64 current_data_version)
260a9803 979{
d2ddc776 980 struct afs_vnode *dvnode = fc->vnode;
260a9803 981 struct afs_call *call;
f044c884 982 struct afs_net *net = afs_v2net(vnode);
260a9803
DH
983 size_t namesz, reqsz, padsz;
984 __be32 *bp;
985
30062bd1
DH
986 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
987 return yfs_fs_link(fc, vnode, name, current_data_version);
988
260a9803
DH
989 _enter("");
990
991 namesz = strlen(name);
992 padsz = (4 - (namesz & 3)) & 3;
993 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
994
f044c884 995 call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
260a9803
DH
996 if (!call)
997 return -ENOMEM;
998
d2ddc776 999 call->key = fc->key;
97e3043a
DH
1000 call->reply[0] = dvnode;
1001 call->reply[1] = vnode;
63a4681f 1002 call->expected_version = current_data_version + 1;
260a9803
DH
1003
1004 /* marshall the parameters */
1005 bp = call->request;
1006 *bp++ = htonl(FSLINK);
1007 *bp++ = htonl(dvnode->fid.vid);
1008 *bp++ = htonl(dvnode->fid.vnode);
1009 *bp++ = htonl(dvnode->fid.unique);
1010 *bp++ = htonl(namesz);
1011 memcpy(bp, name, namesz);
1012 bp = (void *) bp + namesz;
1013 if (padsz > 0) {
1014 memset(bp, 0, padsz);
1015 bp = (void *) bp + padsz;
1016 }
1017 *bp++ = htonl(vnode->fid.vid);
1018 *bp++ = htonl(vnode->fid.vnode);
1019 *bp++ = htonl(vnode->fid.unique);
1020
d2ddc776 1021 afs_use_fs_server(call, fc->cbi);
025db80c 1022 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1023 afs_make_call(&fc->ac, call, GFP_NOFS);
1024 return afs_wait_for_call_to_complete(call, &fc->ac);
260a9803
DH
1025}
1026
1027/*
1028 * deliver reply data to an FS.Symlink
1029 */
d001648e 1030static int afs_deliver_fs_symlink(struct afs_call *call)
260a9803 1031{
97e3043a 1032 struct afs_vnode *vnode = call->reply[0];
260a9803 1033 const __be32 *bp;
372ee163 1034 int ret;
260a9803 1035
d001648e 1036 _enter("{%u}", call->unmarshall);
260a9803 1037
d001648e 1038 ret = afs_transfer_reply(call);
372ee163
DH
1039 if (ret < 0)
1040 return ret;
260a9803
DH
1041
1042 /* unmarshall the reply once we've received all of it */
1043 bp = call->buffer;
97e3043a 1044 xdr_decode_AFSFid(&bp, call->reply[1]);
160cb957
DH
1045 ret = afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
1046 if (ret < 0)
1047 return ret;
1048 ret = afs_decode_status(call, &bp, &vnode->status, vnode,
1049 &call->expected_version, NULL);
1050 if (ret < 0)
1051 return ret;
97e3043a 1052 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
1053
1054 _leave(" = 0 [done]");
1055 return 0;
1056}
1057
1058/*
1059 * FS.Symlink operation type
1060 */
1061static const struct afs_call_type afs_RXFSSymlink = {
1062 .name = "FS.Symlink",
025db80c 1063 .op = afs_FS_Symlink,
260a9803 1064 .deliver = afs_deliver_fs_symlink,
260a9803
DH
1065 .destructor = afs_flat_call_destructor,
1066};
1067
1068/*
1069 * create a symbolic link
1070 */
8b2a464c 1071int afs_fs_symlink(struct afs_fs_cursor *fc,
260a9803
DH
1072 const char *name,
1073 const char *contents,
63a4681f 1074 u64 current_data_version,
260a9803 1075 struct afs_fid *newfid,
d2ddc776 1076 struct afs_file_status *newstatus)
260a9803 1077{
d2ddc776 1078 struct afs_vnode *vnode = fc->vnode;
260a9803 1079 struct afs_call *call;
f044c884 1080 struct afs_net *net = afs_v2net(vnode);
260a9803
DH
1081 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
1082 __be32 *bp;
1083
30062bd1
DH
1084 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1085 return yfs_fs_symlink(fc, name, contents, current_data_version,
1086 newfid, newstatus);
1087
260a9803
DH
1088 _enter("");
1089
1090 namesz = strlen(name);
1091 padsz = (4 - (namesz & 3)) & 3;
1092
1093 c_namesz = strlen(contents);
1094 c_padsz = (4 - (c_namesz & 3)) & 3;
1095
1096 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
1097
f044c884 1098 call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,
260a9803
DH
1099 (3 + 21 + 21 + 6) * 4);
1100 if (!call)
1101 return -ENOMEM;
1102
d2ddc776 1103 call->key = fc->key;
97e3043a
DH
1104 call->reply[0] = vnode;
1105 call->reply[1] = newfid;
1106 call->reply[2] = newstatus;
63a4681f 1107 call->expected_version = current_data_version + 1;
260a9803
DH
1108
1109 /* marshall the parameters */
1110 bp = call->request;
1111 *bp++ = htonl(FSSYMLINK);
1112 *bp++ = htonl(vnode->fid.vid);
1113 *bp++ = htonl(vnode->fid.vnode);
1114 *bp++ = htonl(vnode->fid.unique);
1115 *bp++ = htonl(namesz);
1116 memcpy(bp, name, namesz);
1117 bp = (void *) bp + namesz;
1118 if (padsz > 0) {
1119 memset(bp, 0, padsz);
1120 bp = (void *) bp + padsz;
1121 }
1122 *bp++ = htonl(c_namesz);
1123 memcpy(bp, contents, c_namesz);
1124 bp = (void *) bp + c_namesz;
1125 if (c_padsz > 0) {
1126 memset(bp, 0, c_padsz);
1127 bp = (void *) bp + c_padsz;
1128 }
ab94f5d0
MD
1129 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
1130 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
260a9803
DH
1131 *bp++ = 0; /* owner */
1132 *bp++ = 0; /* group */
1133 *bp++ = htonl(S_IRWXUGO); /* unix mode */
1134 *bp++ = 0; /* segment size */
1135
d2ddc776 1136 afs_use_fs_server(call, fc->cbi);
025db80c 1137 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1138 afs_make_call(&fc->ac, call, GFP_NOFS);
1139 return afs_wait_for_call_to_complete(call, &fc->ac);
260a9803
DH
1140}
1141
1142/*
1143 * deliver reply data to an FS.Rename
1144 */
d001648e 1145static int afs_deliver_fs_rename(struct afs_call *call)
260a9803 1146{
97e3043a 1147 struct afs_vnode *orig_dvnode = call->reply[0], *new_dvnode = call->reply[1];
260a9803 1148 const __be32 *bp;
372ee163 1149 int ret;
260a9803 1150
d001648e 1151 _enter("{%u}", call->unmarshall);
260a9803 1152
d001648e 1153 ret = afs_transfer_reply(call);
372ee163
DH
1154 if (ret < 0)
1155 return ret;
260a9803
DH
1156
1157 /* unmarshall the reply once we've received all of it */
1158 bp = call->buffer;
160cb957
DH
1159 ret = afs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
1160 &call->expected_version, NULL);
1161 if (ret < 0)
1162 return ret;
1163 if (new_dvnode != orig_dvnode) {
1164 ret = afs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
1165 &call->expected_version_2, NULL);
1166 if (ret < 0)
1167 return ret;
1168 }
97e3043a 1169 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
1170
1171 _leave(" = 0 [done]");
1172 return 0;
1173}
1174
1175/*
1176 * FS.Rename operation type
1177 */
1178static const struct afs_call_type afs_RXFSRename = {
1179 .name = "FS.Rename",
025db80c 1180 .op = afs_FS_Rename,
260a9803 1181 .deliver = afs_deliver_fs_rename,
260a9803
DH
1182 .destructor = afs_flat_call_destructor,
1183};
1184
1185/*
1186 * create a symbolic link
1187 */
8b2a464c 1188int afs_fs_rename(struct afs_fs_cursor *fc,
260a9803
DH
1189 const char *orig_name,
1190 struct afs_vnode *new_dvnode,
63a4681f
DH
1191 const char *new_name,
1192 u64 current_orig_data_version,
1193 u64 current_new_data_version)
260a9803 1194{
d2ddc776 1195 struct afs_vnode *orig_dvnode = fc->vnode;
260a9803 1196 struct afs_call *call;
f044c884 1197 struct afs_net *net = afs_v2net(orig_dvnode);
260a9803
DH
1198 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1199 __be32 *bp;
1200
30062bd1
DH
1201 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1202 return yfs_fs_rename(fc, orig_name,
1203 new_dvnode, new_name,
1204 current_orig_data_version,
1205 current_new_data_version);
1206
260a9803
DH
1207 _enter("");
1208
1209 o_namesz = strlen(orig_name);
1210 o_padsz = (4 - (o_namesz & 3)) & 3;
1211
1212 n_namesz = strlen(new_name);
1213 n_padsz = (4 - (n_namesz & 3)) & 3;
1214
1215 reqsz = (4 * 4) +
1216 4 + o_namesz + o_padsz +
1217 (3 * 4) +
1218 4 + n_namesz + n_padsz;
1219
f044c884 1220 call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
260a9803
DH
1221 if (!call)
1222 return -ENOMEM;
1223
d2ddc776 1224 call->key = fc->key;
97e3043a
DH
1225 call->reply[0] = orig_dvnode;
1226 call->reply[1] = new_dvnode;
63a4681f
DH
1227 call->expected_version = current_orig_data_version + 1;
1228 call->expected_version_2 = current_new_data_version + 1;
260a9803
DH
1229
1230 /* marshall the parameters */
1231 bp = call->request;
1232 *bp++ = htonl(FSRENAME);
1233 *bp++ = htonl(orig_dvnode->fid.vid);
1234 *bp++ = htonl(orig_dvnode->fid.vnode);
1235 *bp++ = htonl(orig_dvnode->fid.unique);
1236 *bp++ = htonl(o_namesz);
1237 memcpy(bp, orig_name, o_namesz);
1238 bp = (void *) bp + o_namesz;
1239 if (o_padsz > 0) {
1240 memset(bp, 0, o_padsz);
1241 bp = (void *) bp + o_padsz;
1242 }
1243
1244 *bp++ = htonl(new_dvnode->fid.vid);
1245 *bp++ = htonl(new_dvnode->fid.vnode);
1246 *bp++ = htonl(new_dvnode->fid.unique);
1247 *bp++ = htonl(n_namesz);
1248 memcpy(bp, new_name, n_namesz);
1249 bp = (void *) bp + n_namesz;
1250 if (n_padsz > 0) {
1251 memset(bp, 0, n_padsz);
1252 bp = (void *) bp + n_padsz;
1253 }
1254
d2ddc776 1255 afs_use_fs_server(call, fc->cbi);
025db80c 1256 trace_afs_make_fs_call(call, &orig_dvnode->fid);
0b9bf381
DH
1257 afs_make_call(&fc->ac, call, GFP_NOFS);
1258 return afs_wait_for_call_to_complete(call, &fc->ac);
260a9803 1259}
31143d5d
DH
1260
1261/*
1262 * deliver reply data to an FS.StoreData
1263 */
d001648e 1264static int afs_deliver_fs_store_data(struct afs_call *call)
31143d5d 1265{
97e3043a 1266 struct afs_vnode *vnode = call->reply[0];
31143d5d 1267 const __be32 *bp;
372ee163 1268 int ret;
31143d5d 1269
d001648e 1270 _enter("");
31143d5d 1271
d001648e 1272 ret = afs_transfer_reply(call);
372ee163
DH
1273 if (ret < 0)
1274 return ret;
31143d5d
DH
1275
1276 /* unmarshall the reply once we've received all of it */
1277 bp = call->buffer;
160cb957
DH
1278 ret = afs_decode_status(call, &bp, &vnode->status, vnode,
1279 &call->expected_version, NULL);
1280 if (ret < 0)
1281 return ret;
97e3043a 1282 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
31143d5d
DH
1283
1284 afs_pages_written_back(vnode, call);
1285
1286 _leave(" = 0 [done]");
1287 return 0;
1288}
1289
1290/*
1291 * FS.StoreData operation type
1292 */
1293static const struct afs_call_type afs_RXFSStoreData = {
1294 .name = "FS.StoreData",
025db80c 1295 .op = afs_FS_StoreData,
31143d5d 1296 .deliver = afs_deliver_fs_store_data,
31143d5d
DH
1297 .destructor = afs_flat_call_destructor,
1298};
1299
b9b1f8d5
DH
1300static const struct afs_call_type afs_RXFSStoreData64 = {
1301 .name = "FS.StoreData64",
025db80c 1302 .op = afs_FS_StoreData64,
b9b1f8d5 1303 .deliver = afs_deliver_fs_store_data,
b9b1f8d5
DH
1304 .destructor = afs_flat_call_destructor,
1305};
1306
1307/*
1308 * store a set of pages to a very large file
1309 */
8b2a464c 1310static int afs_fs_store_data64(struct afs_fs_cursor *fc,
4343d008 1311 struct address_space *mapping,
b9b1f8d5
DH
1312 pgoff_t first, pgoff_t last,
1313 unsigned offset, unsigned to,
d2ddc776 1314 loff_t size, loff_t pos, loff_t i_size)
b9b1f8d5 1315{
4343d008 1316 struct afs_vnode *vnode = fc->vnode;
b9b1f8d5 1317 struct afs_call *call;
f044c884 1318 struct afs_net *net = afs_v2net(vnode);
b9b1f8d5
DH
1319 __be32 *bp;
1320
3b6492df 1321 _enter(",%x,{%llx:%llu},,",
4343d008 1322 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
b9b1f8d5 1323
f044c884 1324 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,
b9b1f8d5
DH
1325 (4 + 6 + 3 * 2) * 4,
1326 (21 + 6) * 4);
1327 if (!call)
1328 return -ENOMEM;
1329
4343d008
DH
1330 call->key = fc->key;
1331 call->mapping = mapping;
97e3043a 1332 call->reply[0] = vnode;
b9b1f8d5
DH
1333 call->first = first;
1334 call->last = last;
1335 call->first_offset = offset;
1336 call->last_to = to;
1337 call->send_pages = true;
0c3a5ac2 1338 call->expected_version = vnode->status.data_version + 1;
b9b1f8d5
DH
1339
1340 /* marshall the parameters */
1341 bp = call->request;
1342 *bp++ = htonl(FSSTOREDATA64);
1343 *bp++ = htonl(vnode->fid.vid);
1344 *bp++ = htonl(vnode->fid.vnode);
1345 *bp++ = htonl(vnode->fid.unique);
1346
ab94f5d0
MD
1347 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1348 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
b9b1f8d5
DH
1349 *bp++ = 0; /* owner */
1350 *bp++ = 0; /* group */
1351 *bp++ = 0; /* unix mode */
1352 *bp++ = 0; /* segment size */
1353
1354 *bp++ = htonl(pos >> 32);
1355 *bp++ = htonl((u32) pos);
1356 *bp++ = htonl(size >> 32);
1357 *bp++ = htonl((u32) size);
1358 *bp++ = htonl(i_size >> 32);
1359 *bp++ = htonl((u32) i_size);
1360
025db80c 1361 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1362 afs_make_call(&fc->ac, call, GFP_NOFS);
1363 return afs_wait_for_call_to_complete(call, &fc->ac);
b9b1f8d5
DH
1364}
1365
31143d5d
DH
1366/*
1367 * store a set of pages
1368 */
4343d008 1369int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
31143d5d 1370 pgoff_t first, pgoff_t last,
d2ddc776 1371 unsigned offset, unsigned to)
31143d5d 1372{
4343d008 1373 struct afs_vnode *vnode = fc->vnode;
31143d5d 1374 struct afs_call *call;
f044c884 1375 struct afs_net *net = afs_v2net(vnode);
31143d5d
DH
1376 loff_t size, pos, i_size;
1377 __be32 *bp;
1378
30062bd1
DH
1379 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1380 return yfs_fs_store_data(fc, mapping, first, last, offset, to);
1381
3b6492df 1382 _enter(",%x,{%llx:%llu},,",
4343d008 1383 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
31143d5d 1384
146a1192 1385 size = (loff_t)to - (loff_t)offset;
31143d5d
DH
1386 if (first != last)
1387 size += (loff_t)(last - first) << PAGE_SHIFT;
1388 pos = (loff_t)first << PAGE_SHIFT;
1389 pos += offset;
1390
1391 i_size = i_size_read(&vnode->vfs_inode);
1392 if (pos + size > i_size)
1393 i_size = size + pos;
1394
1395 _debug("size %llx, at %llx, i_size %llx",
1396 (unsigned long long) size, (unsigned long long) pos,
1397 (unsigned long long) i_size);
1398
b9b1f8d5 1399 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
4343d008 1400 return afs_fs_store_data64(fc, mapping, first, last, offset, to,
d2ddc776 1401 size, pos, i_size);
31143d5d 1402
f044c884 1403 call = afs_alloc_flat_call(net, &afs_RXFSStoreData,
31143d5d
DH
1404 (4 + 6 + 3) * 4,
1405 (21 + 6) * 4);
1406 if (!call)
1407 return -ENOMEM;
1408
4343d008
DH
1409 call->key = fc->key;
1410 call->mapping = mapping;
97e3043a 1411 call->reply[0] = vnode;
31143d5d
DH
1412 call->first = first;
1413 call->last = last;
1414 call->first_offset = offset;
1415 call->last_to = to;
1416 call->send_pages = true;
0c3a5ac2 1417 call->expected_version = vnode->status.data_version + 1;
31143d5d
DH
1418
1419 /* marshall the parameters */
1420 bp = call->request;
1421 *bp++ = htonl(FSSTOREDATA);
1422 *bp++ = htonl(vnode->fid.vid);
1423 *bp++ = htonl(vnode->fid.vnode);
1424 *bp++ = htonl(vnode->fid.unique);
1425
ab94f5d0
MD
1426 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1427 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
31143d5d
DH
1428 *bp++ = 0; /* owner */
1429 *bp++ = 0; /* group */
1430 *bp++ = 0; /* unix mode */
1431 *bp++ = 0; /* segment size */
1432
1433 *bp++ = htonl(pos);
1434 *bp++ = htonl(size);
1435 *bp++ = htonl(i_size);
1436
d2ddc776 1437 afs_use_fs_server(call, fc->cbi);
025db80c 1438 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1439 afs_make_call(&fc->ac, call, GFP_NOFS);
1440 return afs_wait_for_call_to_complete(call, &fc->ac);
31143d5d
DH
1441}
1442
1443/*
1444 * deliver reply data to an FS.StoreStatus
1445 */
d001648e 1446static int afs_deliver_fs_store_status(struct afs_call *call)
31143d5d 1447{
97e3043a 1448 struct afs_vnode *vnode = call->reply[0];
31143d5d 1449 const __be32 *bp;
372ee163 1450 int ret;
31143d5d 1451
d001648e 1452 _enter("");
31143d5d 1453
d001648e 1454 ret = afs_transfer_reply(call);
372ee163
DH
1455 if (ret < 0)
1456 return ret;
31143d5d
DH
1457
1458 /* unmarshall the reply once we've received all of it */
31143d5d 1459 bp = call->buffer;
160cb957
DH
1460 ret = afs_decode_status(call, &bp, &vnode->status, vnode,
1461 &call->expected_version, NULL);
1462 if (ret < 0)
1463 return ret;
97e3043a 1464 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
31143d5d
DH
1465
1466 _leave(" = 0 [done]");
1467 return 0;
1468}
1469
1470/*
1471 * FS.StoreStatus operation type
1472 */
1473static const struct afs_call_type afs_RXFSStoreStatus = {
1474 .name = "FS.StoreStatus",
025db80c 1475 .op = afs_FS_StoreStatus,
31143d5d 1476 .deliver = afs_deliver_fs_store_status,
31143d5d
DH
1477 .destructor = afs_flat_call_destructor,
1478};
1479
1480static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1481 .name = "FS.StoreData",
025db80c 1482 .op = afs_FS_StoreData,
31143d5d 1483 .deliver = afs_deliver_fs_store_status,
31143d5d
DH
1484 .destructor = afs_flat_call_destructor,
1485};
1486
b9b1f8d5
DH
1487static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1488 .name = "FS.StoreData64",
025db80c 1489 .op = afs_FS_StoreData64,
b9b1f8d5 1490 .deliver = afs_deliver_fs_store_status,
b9b1f8d5
DH
1491 .destructor = afs_flat_call_destructor,
1492};
1493
1494/*
1495 * set the attributes on a very large file, using FS.StoreData rather than
1496 * FS.StoreStatus so as to alter the file size also
1497 */
d2ddc776 1498static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
b9b1f8d5 1499{
d2ddc776 1500 struct afs_vnode *vnode = fc->vnode;
b9b1f8d5 1501 struct afs_call *call;
f044c884 1502 struct afs_net *net = afs_v2net(vnode);
b9b1f8d5
DH
1503 __be32 *bp;
1504
3b6492df 1505 _enter(",%x,{%llx:%llu},,",
d2ddc776 1506 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
b9b1f8d5
DH
1507
1508 ASSERT(attr->ia_valid & ATTR_SIZE);
1509
f044c884 1510 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,
b9b1f8d5
DH
1511 (4 + 6 + 3 * 2) * 4,
1512 (21 + 6) * 4);
1513 if (!call)
1514 return -ENOMEM;
1515
d2ddc776 1516 call->key = fc->key;
97e3043a 1517 call->reply[0] = vnode;
0c3a5ac2 1518 call->expected_version = vnode->status.data_version + 1;
b9b1f8d5
DH
1519
1520 /* marshall the parameters */
1521 bp = call->request;
1522 *bp++ = htonl(FSSTOREDATA64);
1523 *bp++ = htonl(vnode->fid.vid);
1524 *bp++ = htonl(vnode->fid.vnode);
1525 *bp++ = htonl(vnode->fid.unique);
1526
1527 xdr_encode_AFS_StoreStatus(&bp, attr);
1528
8c7ae38d
DH
1529 *bp++ = htonl(attr->ia_size >> 32); /* position of start of write */
1530 *bp++ = htonl((u32) attr->ia_size);
b9b1f8d5
DH
1531 *bp++ = 0; /* size of write */
1532 *bp++ = 0;
1533 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1534 *bp++ = htonl((u32) attr->ia_size);
1535
d2ddc776 1536 afs_use_fs_server(call, fc->cbi);
025db80c 1537 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1538 afs_make_call(&fc->ac, call, GFP_NOFS);
1539 return afs_wait_for_call_to_complete(call, &fc->ac);
b9b1f8d5
DH
1540}
1541
31143d5d
DH
1542/*
1543 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1544 * so as to alter the file size also
1545 */
d2ddc776 1546static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
31143d5d 1547{
d2ddc776 1548 struct afs_vnode *vnode = fc->vnode;
31143d5d 1549 struct afs_call *call;
f044c884 1550 struct afs_net *net = afs_v2net(vnode);
31143d5d
DH
1551 __be32 *bp;
1552
3b6492df 1553 _enter(",%x,{%llx:%llu},,",
d2ddc776 1554 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
31143d5d
DH
1555
1556 ASSERT(attr->ia_valid & ATTR_SIZE);
b9b1f8d5 1557 if (attr->ia_size >> 32)
d2ddc776 1558 return afs_fs_setattr_size64(fc, attr);
31143d5d 1559
f044c884 1560 call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,
31143d5d
DH
1561 (4 + 6 + 3) * 4,
1562 (21 + 6) * 4);
1563 if (!call)
1564 return -ENOMEM;
1565
d2ddc776 1566 call->key = fc->key;
97e3043a 1567 call->reply[0] = vnode;
0c3a5ac2 1568 call->expected_version = vnode->status.data_version + 1;
31143d5d
DH
1569
1570 /* marshall the parameters */
1571 bp = call->request;
1572 *bp++ = htonl(FSSTOREDATA);
1573 *bp++ = htonl(vnode->fid.vid);
1574 *bp++ = htonl(vnode->fid.vnode);
1575 *bp++ = htonl(vnode->fid.unique);
1576
1577 xdr_encode_AFS_StoreStatus(&bp, attr);
1578
8c7ae38d 1579 *bp++ = htonl(attr->ia_size); /* position of start of write */
31143d5d
DH
1580 *bp++ = 0; /* size of write */
1581 *bp++ = htonl(attr->ia_size); /* new file length */
1582
d2ddc776 1583 afs_use_fs_server(call, fc->cbi);
025db80c 1584 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1585 afs_make_call(&fc->ac, call, GFP_NOFS);
1586 return afs_wait_for_call_to_complete(call, &fc->ac);
31143d5d
DH
1587}
1588
1589/*
1590 * set the attributes on a file, using FS.StoreData if there's a change in file
1591 * size, and FS.StoreStatus otherwise
1592 */
d2ddc776 1593int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
31143d5d 1594{
d2ddc776 1595 struct afs_vnode *vnode = fc->vnode;
31143d5d 1596 struct afs_call *call;
f044c884 1597 struct afs_net *net = afs_v2net(vnode);
31143d5d
DH
1598 __be32 *bp;
1599
30062bd1
DH
1600 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1601 return yfs_fs_setattr(fc, attr);
1602
31143d5d 1603 if (attr->ia_valid & ATTR_SIZE)
d2ddc776 1604 return afs_fs_setattr_size(fc, attr);
31143d5d 1605
3b6492df 1606 _enter(",%x,{%llx:%llu},,",
d2ddc776 1607 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
31143d5d 1608
f044c884 1609 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,
31143d5d
DH
1610 (4 + 6) * 4,
1611 (21 + 6) * 4);
1612 if (!call)
1613 return -ENOMEM;
1614
d2ddc776 1615 call->key = fc->key;
97e3043a 1616 call->reply[0] = vnode;
0c3a5ac2 1617 call->expected_version = vnode->status.data_version;
31143d5d
DH
1618
1619 /* marshall the parameters */
1620 bp = call->request;
1621 *bp++ = htonl(FSSTORESTATUS);
1622 *bp++ = htonl(vnode->fid.vid);
1623 *bp++ = htonl(vnode->fid.vnode);
1624 *bp++ = htonl(vnode->fid.unique);
1625
1626 xdr_encode_AFS_StoreStatus(&bp, attr);
1627
d2ddc776 1628 afs_use_fs_server(call, fc->cbi);
025db80c 1629 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1630 afs_make_call(&fc->ac, call, GFP_NOFS);
1631 return afs_wait_for_call_to_complete(call, &fc->ac);
31143d5d 1632}
45222b9e
DH
1633
1634/*
1635 * deliver reply data to an FS.GetVolumeStatus
1636 */
d001648e 1637static int afs_deliver_fs_get_volume_status(struct afs_call *call)
45222b9e
DH
1638{
1639 const __be32 *bp;
1640 char *p;
12bdcf33 1641 u32 size;
45222b9e
DH
1642 int ret;
1643
d001648e 1644 _enter("{%u}", call->unmarshall);
45222b9e
DH
1645
1646 switch (call->unmarshall) {
1647 case 0:
45222b9e 1648 call->unmarshall++;
12bdcf33 1649 afs_extract_to_buf(call, 12 * 4);
45222b9e
DH
1650
1651 /* extract the returned status record */
1652 case 1:
1653 _debug("extract status");
12bdcf33 1654 ret = afs_extract_data(call, true);
372ee163
DH
1655 if (ret < 0)
1656 return ret;
45222b9e
DH
1657
1658 bp = call->buffer;
97e3043a 1659 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply[1]);
45222b9e 1660 call->unmarshall++;
12bdcf33 1661 afs_extract_to_tmp(call);
45222b9e
DH
1662
1663 /* extract the volume name length */
1664 case 2:
12bdcf33 1665 ret = afs_extract_data(call, true);
372ee163
DH
1666 if (ret < 0)
1667 return ret;
45222b9e
DH
1668
1669 call->count = ntohl(call->tmp);
1670 _debug("volname length: %u", call->count);
1671 if (call->count >= AFSNAMEMAX)
160cb957
DH
1672 return afs_protocol_error(call, -EBADMSG,
1673 afs_eproto_volname_len);
12bdcf33
DH
1674 size = (call->count + 3) & ~3; /* It's padded */
1675 afs_extract_begin(call, call->reply[2], size);
45222b9e
DH
1676 call->unmarshall++;
1677
1678 /* extract the volume name */
1679 case 3:
1680 _debug("extract volname");
12bdcf33
DH
1681 ret = afs_extract_data(call, true);
1682 if (ret < 0)
1683 return ret;
45222b9e 1684
97e3043a 1685 p = call->reply[2];
45222b9e
DH
1686 p[call->count] = 0;
1687 _debug("volname '%s'", p);
12bdcf33 1688 afs_extract_to_tmp(call);
45222b9e
DH
1689 call->unmarshall++;
1690
45222b9e 1691 /* extract the offline message length */
12bdcf33
DH
1692 case 4:
1693 ret = afs_extract_data(call, true);
372ee163
DH
1694 if (ret < 0)
1695 return ret;
45222b9e
DH
1696
1697 call->count = ntohl(call->tmp);
1698 _debug("offline msg length: %u", call->count);
1699 if (call->count >= AFSNAMEMAX)
160cb957
DH
1700 return afs_protocol_error(call, -EBADMSG,
1701 afs_eproto_offline_msg_len);
12bdcf33
DH
1702 size = (call->count + 3) & ~3; /* It's padded */
1703 afs_extract_begin(call, call->reply[2], size);
45222b9e
DH
1704 call->unmarshall++;
1705
1706 /* extract the offline message */
12bdcf33 1707 case 5:
45222b9e 1708 _debug("extract offline");
12bdcf33
DH
1709 ret = afs_extract_data(call, true);
1710 if (ret < 0)
1711 return ret;
45222b9e 1712
97e3043a 1713 p = call->reply[2];
45222b9e
DH
1714 p[call->count] = 0;
1715 _debug("offline '%s'", p);
1716
12bdcf33 1717 afs_extract_to_tmp(call);
45222b9e
DH
1718 call->unmarshall++;
1719
45222b9e 1720 /* extract the message of the day length */
12bdcf33
DH
1721 case 6:
1722 ret = afs_extract_data(call, true);
372ee163
DH
1723 if (ret < 0)
1724 return ret;
45222b9e
DH
1725
1726 call->count = ntohl(call->tmp);
1727 _debug("motd length: %u", call->count);
1728 if (call->count >= AFSNAMEMAX)
160cb957
DH
1729 return afs_protocol_error(call, -EBADMSG,
1730 afs_eproto_motd_len);
12bdcf33
DH
1731 size = (call->count + 3) & ~3; /* It's padded */
1732 afs_extract_begin(call, call->reply[2], size);
45222b9e
DH
1733 call->unmarshall++;
1734
1735 /* extract the message of the day */
12bdcf33 1736 case 7:
45222b9e 1737 _debug("extract motd");
12bdcf33
DH
1738 ret = afs_extract_data(call, false);
1739 if (ret < 0)
1740 return ret;
45222b9e 1741
97e3043a 1742 p = call->reply[2];
45222b9e
DH
1743 p[call->count] = 0;
1744 _debug("motd '%s'", p);
1745
45222b9e
DH
1746 call->unmarshall++;
1747
12bdcf33 1748 case 8:
45222b9e
DH
1749 break;
1750 }
1751
45222b9e
DH
1752 _leave(" = 0 [done]");
1753 return 0;
1754}
1755
1756/*
1757 * destroy an FS.GetVolumeStatus call
1758 */
1759static void afs_get_volume_status_call_destructor(struct afs_call *call)
1760{
97e3043a
DH
1761 kfree(call->reply[2]);
1762 call->reply[2] = NULL;
45222b9e
DH
1763 afs_flat_call_destructor(call);
1764}
1765
1766/*
1767 * FS.GetVolumeStatus operation type
1768 */
1769static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1770 .name = "FS.GetVolumeStatus",
025db80c 1771 .op = afs_FS_GetVolumeStatus,
45222b9e 1772 .deliver = afs_deliver_fs_get_volume_status,
45222b9e
DH
1773 .destructor = afs_get_volume_status_call_destructor,
1774};
1775
1776/*
1777 * fetch the status of a volume
1778 */
8b2a464c 1779int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
d2ddc776 1780 struct afs_volume_status *vs)
45222b9e 1781{
d2ddc776 1782 struct afs_vnode *vnode = fc->vnode;
45222b9e 1783 struct afs_call *call;
f044c884 1784 struct afs_net *net = afs_v2net(vnode);
45222b9e
DH
1785 __be32 *bp;
1786 void *tmpbuf;
1787
30062bd1
DH
1788 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1789 return yfs_fs_get_volume_status(fc, vs);
1790
45222b9e
DH
1791 _enter("");
1792
1793 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1794 if (!tmpbuf)
1795 return -ENOMEM;
1796
f044c884 1797 call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
45222b9e
DH
1798 if (!call) {
1799 kfree(tmpbuf);
1800 return -ENOMEM;
1801 }
1802
d2ddc776 1803 call->key = fc->key;
97e3043a
DH
1804 call->reply[0] = vnode;
1805 call->reply[1] = vs;
1806 call->reply[2] = tmpbuf;
45222b9e
DH
1807
1808 /* marshall the parameters */
1809 bp = call->request;
1810 bp[0] = htonl(FSGETVOLUMESTATUS);
1811 bp[1] = htonl(vnode->fid.vid);
1812
d2ddc776 1813 afs_use_fs_server(call, fc->cbi);
025db80c 1814 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1815 afs_make_call(&fc->ac, call, GFP_NOFS);
1816 return afs_wait_for_call_to_complete(call, &fc->ac);
45222b9e 1817}
e8d6c554
DH
1818
1819/*
1820 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1821 */
d001648e 1822static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
e8d6c554
DH
1823{
1824 const __be32 *bp;
372ee163 1825 int ret;
e8d6c554 1826
d001648e 1827 _enter("{%u}", call->unmarshall);
e8d6c554 1828
d001648e 1829 ret = afs_transfer_reply(call);
372ee163
DH
1830 if (ret < 0)
1831 return ret;
e8d6c554
DH
1832
1833 /* unmarshall the reply once we've received all of it */
1834 bp = call->buffer;
97e3043a 1835 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
e8d6c554
DH
1836
1837 _leave(" = 0 [done]");
1838 return 0;
1839}
1840
1841/*
1842 * FS.SetLock operation type
1843 */
1844static const struct afs_call_type afs_RXFSSetLock = {
1845 .name = "FS.SetLock",
025db80c 1846 .op = afs_FS_SetLock,
e8d6c554 1847 .deliver = afs_deliver_fs_xxxx_lock,
e8d6c554
DH
1848 .destructor = afs_flat_call_destructor,
1849};
1850
1851/*
1852 * FS.ExtendLock operation type
1853 */
1854static const struct afs_call_type afs_RXFSExtendLock = {
1855 .name = "FS.ExtendLock",
025db80c 1856 .op = afs_FS_ExtendLock,
e8d6c554 1857 .deliver = afs_deliver_fs_xxxx_lock,
e8d6c554
DH
1858 .destructor = afs_flat_call_destructor,
1859};
1860
1861/*
1862 * FS.ReleaseLock operation type
1863 */
1864static const struct afs_call_type afs_RXFSReleaseLock = {
1865 .name = "FS.ReleaseLock",
025db80c 1866 .op = afs_FS_ReleaseLock,
e8d6c554 1867 .deliver = afs_deliver_fs_xxxx_lock,
e8d6c554
DH
1868 .destructor = afs_flat_call_destructor,
1869};
1870
1871/*
d2ddc776 1872 * Set a lock on a file
e8d6c554 1873 */
d2ddc776 1874int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
e8d6c554 1875{
d2ddc776 1876 struct afs_vnode *vnode = fc->vnode;
e8d6c554 1877 struct afs_call *call;
f044c884 1878 struct afs_net *net = afs_v2net(vnode);
e8d6c554
DH
1879 __be32 *bp;
1880
30062bd1
DH
1881 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1882 return yfs_fs_set_lock(fc, type);
1883
e8d6c554
DH
1884 _enter("");
1885
f044c884 1886 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
e8d6c554
DH
1887 if (!call)
1888 return -ENOMEM;
1889
d2ddc776 1890 call->key = fc->key;
97e3043a 1891 call->reply[0] = vnode;
e8d6c554
DH
1892
1893 /* marshall the parameters */
1894 bp = call->request;
1895 *bp++ = htonl(FSSETLOCK);
1896 *bp++ = htonl(vnode->fid.vid);
1897 *bp++ = htonl(vnode->fid.vnode);
1898 *bp++ = htonl(vnode->fid.unique);
1899 *bp++ = htonl(type);
1900
d2ddc776 1901 afs_use_fs_server(call, fc->cbi);
025db80c 1902 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1903 afs_make_call(&fc->ac, call, GFP_NOFS);
1904 return afs_wait_for_call_to_complete(call, &fc->ac);
e8d6c554
DH
1905}
1906
1907/*
1908 * extend a lock on a file
1909 */
d2ddc776 1910int afs_fs_extend_lock(struct afs_fs_cursor *fc)
e8d6c554 1911{
d2ddc776 1912 struct afs_vnode *vnode = fc->vnode;
e8d6c554 1913 struct afs_call *call;
f044c884 1914 struct afs_net *net = afs_v2net(vnode);
e8d6c554
DH
1915 __be32 *bp;
1916
30062bd1
DH
1917 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1918 return yfs_fs_extend_lock(fc);
1919
e8d6c554
DH
1920 _enter("");
1921
f044c884 1922 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
e8d6c554
DH
1923 if (!call)
1924 return -ENOMEM;
1925
d2ddc776 1926 call->key = fc->key;
97e3043a 1927 call->reply[0] = vnode;
e8d6c554
DH
1928
1929 /* marshall the parameters */
1930 bp = call->request;
1931 *bp++ = htonl(FSEXTENDLOCK);
1932 *bp++ = htonl(vnode->fid.vid);
1933 *bp++ = htonl(vnode->fid.vnode);
1934 *bp++ = htonl(vnode->fid.unique);
1935
d2ddc776 1936 afs_use_fs_server(call, fc->cbi);
025db80c 1937 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1938 afs_make_call(&fc->ac, call, GFP_NOFS);
1939 return afs_wait_for_call_to_complete(call, &fc->ac);
e8d6c554
DH
1940}
1941
1942/*
1943 * release a lock on a file
1944 */
d2ddc776 1945int afs_fs_release_lock(struct afs_fs_cursor *fc)
e8d6c554 1946{
d2ddc776 1947 struct afs_vnode *vnode = fc->vnode;
e8d6c554 1948 struct afs_call *call;
f044c884 1949 struct afs_net *net = afs_v2net(vnode);
e8d6c554
DH
1950 __be32 *bp;
1951
30062bd1
DH
1952 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
1953 return yfs_fs_release_lock(fc);
1954
e8d6c554
DH
1955 _enter("");
1956
f044c884 1957 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
e8d6c554
DH
1958 if (!call)
1959 return -ENOMEM;
1960
d2ddc776 1961 call->key = fc->key;
97e3043a 1962 call->reply[0] = vnode;
e8d6c554
DH
1963
1964 /* marshall the parameters */
1965 bp = call->request;
1966 *bp++ = htonl(FSRELEASELOCK);
1967 *bp++ = htonl(vnode->fid.vid);
1968 *bp++ = htonl(vnode->fid.vnode);
1969 *bp++ = htonl(vnode->fid.unique);
1970
d2ddc776 1971 afs_use_fs_server(call, fc->cbi);
025db80c 1972 trace_afs_make_fs_call(call, &vnode->fid);
0b9bf381
DH
1973 afs_make_call(&fc->ac, call, GFP_NOFS);
1974 return afs_wait_for_call_to_complete(call, &fc->ac);
c435ee34
DH
1975}
1976
1977/*
1978 * Deliver reply data to an FS.GiveUpAllCallBacks operation.
1979 */
1980static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)
1981{
1982 return afs_transfer_reply(call);
1983}
1984
1985/*
1986 * FS.GiveUpAllCallBacks operation type
1987 */
1988static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
1989 .name = "FS.GiveUpAllCallBacks",
025db80c 1990 .op = afs_FS_GiveUpAllCallBacks,
c435ee34
DH
1991 .deliver = afs_deliver_fs_give_up_all_callbacks,
1992 .destructor = afs_flat_call_destructor,
1993};
1994
1995/*
1996 * Flush all the callbacks we have on a server.
1997 */
d2ddc776
DH
1998int afs_fs_give_up_all_callbacks(struct afs_net *net,
1999 struct afs_server *server,
8b2a464c 2000 struct afs_addr_cursor *ac,
d2ddc776 2001 struct key *key)
c435ee34
DH
2002{
2003 struct afs_call *call;
2004 __be32 *bp;
2005
2006 _enter("");
2007
d2ddc776 2008 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);
c435ee34
DH
2009 if (!call)
2010 return -ENOMEM;
2011
2012 call->key = key;
2013
2014 /* marshall the parameters */
2015 bp = call->request;
2016 *bp++ = htonl(FSGIVEUPALLCALLBACKS);
2017
2018 /* Can't take a ref on server */
0b9bf381
DH
2019 afs_make_call(ac, call, GFP_NOFS);
2020 return afs_wait_for_call_to_complete(call, ac);
d2ddc776
DH
2021}
2022
2023/*
2024 * Deliver reply data to an FS.GetCapabilities operation.
2025 */
2026static int afs_deliver_fs_get_capabilities(struct afs_call *call)
2027{
2028 u32 count;
2029 int ret;
2030
12bdcf33 2031 _enter("{%u,%zu}", call->unmarshall, iov_iter_count(&call->iter));
d2ddc776 2032
d2ddc776
DH
2033 switch (call->unmarshall) {
2034 case 0:
12bdcf33 2035 afs_extract_to_tmp(call);
d2ddc776
DH
2036 call->unmarshall++;
2037
2038 /* Extract the capabilities word count */
2039 case 1:
12bdcf33 2040 ret = afs_extract_data(call, true);
d2ddc776
DH
2041 if (ret < 0)
2042 return ret;
2043
2044 count = ntohl(call->tmp);
2045
2046 call->count = count;
2047 call->count2 = count;
12bdcf33 2048 iov_iter_discard(&call->iter, READ, count * sizeof(__be32));
d2ddc776
DH
2049 call->unmarshall++;
2050
2051 /* Extract capabilities words */
2052 case 2:
12bdcf33 2053 ret = afs_extract_data(call, false);
d2ddc776
DH
2054 if (ret < 0)
2055 return ret;
2056
2057 /* TODO: Examine capabilities */
2058
d2ddc776
DH
2059 call->unmarshall++;
2060 break;
2061 }
2062
2063 _leave(" = 0 [done]");
2064 return 0;
2065}
2066
3bf0fb6f
DH
2067static void afs_destroy_fs_get_capabilities(struct afs_call *call)
2068{
2069 struct afs_server *server = call->reply[0];
2070
2071 afs_put_server(call->net, server);
2072 afs_flat_call_destructor(call);
2073}
2074
d2ddc776
DH
2075/*
2076 * FS.GetCapabilities operation type
2077 */
2078static const struct afs_call_type afs_RXFSGetCapabilities = {
2079 .name = "FS.GetCapabilities",
025db80c 2080 .op = afs_FS_GetCapabilities,
d2ddc776 2081 .deliver = afs_deliver_fs_get_capabilities,
3bf0fb6f
DH
2082 .done = afs_fileserver_probe_result,
2083 .destructor = afs_destroy_fs_get_capabilities,
d2ddc776
DH
2084};
2085
2086/*
2087 * Probe a fileserver for the capabilities that it supports. This can
2088 * return up to 196 words.
2089 */
0b9bf381
DH
2090struct afs_call *afs_fs_get_capabilities(struct afs_net *net,
2091 struct afs_server *server,
2092 struct afs_addr_cursor *ac,
2093 struct key *key,
2094 unsigned int server_index)
d2ddc776
DH
2095{
2096 struct afs_call *call;
2097 __be32 *bp;
2098
2099 _enter("");
2100
2101 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
2102 if (!call)
0b9bf381 2103 return ERR_PTR(-ENOMEM);
d2ddc776
DH
2104
2105 call->key = key;
3bf0fb6f
DH
2106 call->reply[0] = afs_get_server(server);
2107 call->reply[1] = (void *)(long)server_index;
30062bd1 2108 call->upgrade = true;
3bf0fb6f 2109 call->want_reply_time = true;
0b9bf381 2110 call->async = true;
d2ddc776
DH
2111
2112 /* marshall the parameters */
2113 bp = call->request;
2114 *bp++ = htonl(FSGETCAPABILITIES);
2115
2116 /* Can't take a ref on server */
025db80c 2117 trace_afs_make_fs_call(call, NULL);
0b9bf381
DH
2118 afs_make_call(ac, call, GFP_NOFS);
2119 return call;
e8d6c554 2120}
5cf9dd55
DH
2121
2122/*
2123 * Deliver reply data to an FS.FetchStatus with no vnode.
2124 */
2125static int afs_deliver_fs_fetch_status(struct afs_call *call)
2126{
2127 struct afs_file_status *status = call->reply[1];
2128 struct afs_callback *callback = call->reply[2];
2129 struct afs_volsync *volsync = call->reply[3];
36bb5f49 2130 struct afs_fid *fid = call->reply[0];
5cf9dd55
DH
2131 const __be32 *bp;
2132 int ret;
2133
2134 ret = afs_transfer_reply(call);
2135 if (ret < 0)
2136 return ret;
2137
36bb5f49 2138 _enter("{%llx:%llu}", fid->vid, fid->vnode);
5cf9dd55
DH
2139
2140 /* unmarshall the reply once we've received all of it */
2141 bp = call->buffer;
36bb5f49 2142 ret = afs_decode_status(call, &bp, status, NULL,
160cb957
DH
2143 &call->expected_version, NULL);
2144 if (ret < 0)
2145 return ret;
12d8e95a 2146 xdr_decode_AFSCallBack_raw(call, &bp, callback);
30062bd1 2147 xdr_decode_AFSVolSync(&bp, volsync);
5cf9dd55
DH
2148
2149 _leave(" = 0 [done]");
2150 return 0;
2151}
2152
2153/*
2154 * FS.FetchStatus operation type
2155 */
2156static const struct afs_call_type afs_RXFSFetchStatus = {
2157 .name = "FS.FetchStatus",
2158 .op = afs_FS_FetchStatus,
2159 .deliver = afs_deliver_fs_fetch_status,
2160 .destructor = afs_flat_call_destructor,
2161};
2162
2163/*
2164 * Fetch the status information for a fid without needing a vnode handle.
2165 */
2166int afs_fs_fetch_status(struct afs_fs_cursor *fc,
2167 struct afs_net *net,
2168 struct afs_fid *fid,
2169 struct afs_file_status *status,
2170 struct afs_callback *callback,
2171 struct afs_volsync *volsync)
2172{
2173 struct afs_call *call;
2174 __be32 *bp;
2175
30062bd1
DH
2176 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
2177 return yfs_fs_fetch_status(fc, net, fid, status, callback, volsync);
2178
3b6492df 2179 _enter(",%x,{%llx:%llu},,",
5cf9dd55
DH
2180 key_serial(fc->key), fid->vid, fid->vnode);
2181
2182 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
2183 if (!call) {
2184 fc->ac.error = -ENOMEM;
2185 return -ENOMEM;
2186 }
2187
2188 call->key = fc->key;
36bb5f49 2189 call->reply[0] = fid;
5cf9dd55
DH
2190 call->reply[1] = status;
2191 call->reply[2] = callback;
2192 call->reply[3] = volsync;
0c3a5ac2 2193 call->expected_version = 1; /* vnode->status.data_version */
12d8e95a 2194 call->want_reply_time = true;
5cf9dd55
DH
2195
2196 /* marshall the parameters */
2197 bp = call->request;
2198 bp[0] = htonl(FSFETCHSTATUS);
2199 bp[1] = htonl(fid->vid);
2200 bp[2] = htonl(fid->vnode);
2201 bp[3] = htonl(fid->unique);
2202
2203 call->cb_break = fc->cb_break;
2204 afs_use_fs_server(call, fc->cbi);
2205 trace_afs_make_fs_call(call, fid);
0b9bf381
DH
2206 afs_make_call(&fc->ac, call, GFP_NOFS);
2207 return afs_wait_for_call_to_complete(call, &fc->ac);
5cf9dd55
DH
2208}
2209
2210/*
2211 * Deliver reply data to an FS.InlineBulkStatus call
2212 */
2213static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
2214{
2215 struct afs_file_status *statuses;
2216 struct afs_callback *callbacks;
2217 struct afs_vnode *vnode = call->reply[0];
2218 const __be32 *bp;
2219 u32 tmp;
2220 int ret;
2221
2222 _enter("{%u}", call->unmarshall);
2223
2224 switch (call->unmarshall) {
2225 case 0:
12bdcf33 2226 afs_extract_to_tmp(call);
5cf9dd55
DH
2227 call->unmarshall++;
2228
2229 /* Extract the file status count and array in two steps */
2230 case 1:
2231 _debug("extract status count");
12bdcf33 2232 ret = afs_extract_data(call, true);
5cf9dd55
DH
2233 if (ret < 0)
2234 return ret;
2235
2236 tmp = ntohl(call->tmp);
2237 _debug("status count: %u/%u", tmp, call->count2);
2238 if (tmp != call->count2)
160cb957
DH
2239 return afs_protocol_error(call, -EBADMSG,
2240 afs_eproto_ibulkst_count);
5cf9dd55
DH
2241
2242 call->count = 0;
2243 call->unmarshall++;
2244 more_counts:
12bdcf33 2245 afs_extract_to_buf(call, 21 * sizeof(__be32));
5cf9dd55
DH
2246
2247 case 2:
2248 _debug("extract status array %u", call->count);
12bdcf33 2249 ret = afs_extract_data(call, true);
5cf9dd55
DH
2250 if (ret < 0)
2251 return ret;
2252
2253 bp = call->buffer;
2254 statuses = call->reply[1];
160cb957
DH
2255 ret = afs_decode_status(call, &bp, &statuses[call->count],
2256 call->count == 0 ? vnode : NULL,
2257 NULL, NULL);
2258 if (ret < 0)
2259 return ret;
5cf9dd55
DH
2260
2261 call->count++;
2262 if (call->count < call->count2)
2263 goto more_counts;
2264
2265 call->count = 0;
2266 call->unmarshall++;
12bdcf33 2267 afs_extract_to_tmp(call);
5cf9dd55
DH
2268
2269 /* Extract the callback count and array in two steps */
2270 case 3:
2271 _debug("extract CB count");
12bdcf33 2272 ret = afs_extract_data(call, true);
5cf9dd55
DH
2273 if (ret < 0)
2274 return ret;
2275
2276 tmp = ntohl(call->tmp);
2277 _debug("CB count: %u", tmp);
2278 if (tmp != call->count2)
160cb957
DH
2279 return afs_protocol_error(call, -EBADMSG,
2280 afs_eproto_ibulkst_cb_count);
5cf9dd55
DH
2281 call->count = 0;
2282 call->unmarshall++;
2283 more_cbs:
12bdcf33 2284 afs_extract_to_buf(call, 3 * sizeof(__be32));
5cf9dd55
DH
2285
2286 case 4:
2287 _debug("extract CB array");
12bdcf33 2288 ret = afs_extract_data(call, true);
5cf9dd55
DH
2289 if (ret < 0)
2290 return ret;
2291
2292 _debug("unmarshall CB array");
2293 bp = call->buffer;
2294 callbacks = call->reply[2];
2295 callbacks[call->count].version = ntohl(bp[0]);
12d8e95a 2296 callbacks[call->count].expires_at = xdr_decode_expiry(call, ntohl(bp[1]));
5cf9dd55
DH
2297 callbacks[call->count].type = ntohl(bp[2]);
2298 statuses = call->reply[1];
2299 if (call->count == 0 && vnode && statuses[0].abort_code == 0)
2300 xdr_decode_AFSCallBack(call, vnode, &bp);
2301 call->count++;
2302 if (call->count < call->count2)
2303 goto more_cbs;
2304
12bdcf33 2305 afs_extract_to_buf(call, 6 * sizeof(__be32));
5cf9dd55
DH
2306 call->unmarshall++;
2307
2308 case 5:
12bdcf33 2309 ret = afs_extract_data(call, false);
5cf9dd55
DH
2310 if (ret < 0)
2311 return ret;
2312
2313 bp = call->buffer;
30062bd1 2314 xdr_decode_AFSVolSync(&bp, call->reply[3]);
5cf9dd55 2315
5cf9dd55
DH
2316 call->unmarshall++;
2317
2318 case 6:
2319 break;
2320 }
2321
2322 _leave(" = 0 [done]");
2323 return 0;
2324}
2325
2326/*
2327 * FS.InlineBulkStatus operation type
2328 */
2329static const struct afs_call_type afs_RXFSInlineBulkStatus = {
2330 .name = "FS.InlineBulkStatus",
2331 .op = afs_FS_InlineBulkStatus,
2332 .deliver = afs_deliver_fs_inline_bulk_status,
2333 .destructor = afs_flat_call_destructor,
2334};
2335
2336/*
2337 * Fetch the status information for up to 50 files
2338 */
2339int afs_fs_inline_bulk_status(struct afs_fs_cursor *fc,
2340 struct afs_net *net,
2341 struct afs_fid *fids,
2342 struct afs_file_status *statuses,
2343 struct afs_callback *callbacks,
2344 unsigned int nr_fids,
2345 struct afs_volsync *volsync)
2346{
2347 struct afs_call *call;
2348 __be32 *bp;
2349 int i;
2350
30062bd1
DH
2351 if (test_bit(AFS_SERVER_FL_IS_YFS, &fc->cbi->server->flags))
2352 return yfs_fs_inline_bulk_status(fc, net, fids, statuses, callbacks,
2353 nr_fids, volsync);
2354
3b6492df 2355 _enter(",%x,{%llx:%llu},%u",
5cf9dd55
DH
2356 key_serial(fc->key), fids[0].vid, fids[1].vnode, nr_fids);
2357
2358 call = afs_alloc_flat_call(net, &afs_RXFSInlineBulkStatus,
2359 (2 + nr_fids * 3) * 4,
2360 21 * 4);
2361 if (!call) {
2362 fc->ac.error = -ENOMEM;
2363 return -ENOMEM;
2364 }
2365
2366 call->key = fc->key;
2367 call->reply[0] = NULL; /* vnode for fid[0] */
2368 call->reply[1] = statuses;
2369 call->reply[2] = callbacks;
2370 call->reply[3] = volsync;
2371 call->count2 = nr_fids;
12d8e95a 2372 call->want_reply_time = true;
5cf9dd55
DH
2373
2374 /* marshall the parameters */
2375 bp = call->request;
2376 *bp++ = htonl(FSINLINEBULKSTATUS);
2377 *bp++ = htonl(nr_fids);
2378 for (i = 0; i < nr_fids; i++) {
2379 *bp++ = htonl(fids[i].vid);
2380 *bp++ = htonl(fids[i].vnode);
2381 *bp++ = htonl(fids[i].unique);
2382 }
2383
2384 call->cb_break = fc->cb_break;
2385 afs_use_fs_server(call, fc->cbi);
2386 trace_afs_make_fs_call(call, &fids[0]);
0b9bf381
DH
2387 afs_make_call(&fc->ac, call, GFP_NOFS);
2388 return afs_wait_for_call_to_complete(call, &fc->ac);
5cf9dd55 2389}