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