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