Merge tag 'pm-6.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
[linux-2.6-block.git] / fs / afs / fsclient.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
08e0e7c8 2/* AFS File Server client stubs
1da177e4 3 *
08e0e7c8 4 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
1da177e4 5 * Written by David Howells (dhowells@redhat.com)
1da177e4
LT
6 */
7
8#include <linux/init.h>
5a0e3ad6 9#include <linux/slab.h>
1da177e4 10#include <linux/sched.h>
08e0e7c8 11#include <linux/circ_buf.h>
a01179e6 12#include <linux/iversion.h>
5cbf0398 13#include <linux/netfs.h>
1da177e4 14#include "internal.h"
08e0e7c8 15#include "afs_fs.h"
dd9fbcb8 16#include "xdr_fs.h"
c435ee34 17
260a9803
DH
18/*
19 * decode an AFSFid block
20 */
21static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
22{
23 const __be32 *bp = *_bp;
24
25 fid->vid = ntohl(*bp++);
26 fid->vnode = ntohl(*bp++);
27 fid->unique = ntohl(*bp++);
28 *_bp = bp;
29}
30
888b3384
DH
31/*
32 * Dump a bad file status record.
33 */
34static void xdr_dump_bad(const __be32 *bp)
35{
36 __be32 x[4];
37 int i;
38
39 pr_notice("AFS XDR: Bad status record\n");
40 for (i = 0; i < 5 * 4 * 4; i += 16) {
41 memcpy(x, bp, 16);
42 bp += 4;
43 pr_notice("%03x: %08x %08x %08x %08x\n",
44 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
45 }
46
47 memcpy(x, bp, 4);
48 pr_notice("0x50: %08x\n", ntohl(x[0]));
49}
50
dd9fbcb8
DH
51/*
52 * decode an AFSFetchStatus block
53 */
38355eec
DH
54static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
55 struct afs_call *call,
56 struct afs_status_cb *scb)
dd9fbcb8
DH
57{
58 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
a58823ac 59 struct afs_file_status *status = &scb->status;
684b0f68 60 bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
260a9803 61 u64 data_version, size;
dd9fbcb8 62 u32 type, abort_code;
c435ee34 63
684b0f68
DH
64 abort_code = ntohl(xdr->abort_code);
65
dd9fbcb8 66 if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {
684b0f68
DH
67 if (xdr->if_version == htonl(0) &&
68 abort_code != 0 &&
69 inline_error) {
70 /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus
71 * whereby it doesn't set the interface version in the error
72 * case.
73 */
74 status->abort_code = abort_code;
a38a7558 75 scb->have_error = true;
38355eec 76 goto advance;
684b0f68
DH
77 }
78
dd9fbcb8
DH
79 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
80 goto bad;
81 }
08e0e7c8 82
684b0f68
DH
83 if (abort_code != 0 && inline_error) {
84 status->abort_code = abort_code;
3e0d9892 85 scb->have_error = true;
38355eec 86 goto advance;
684b0f68
DH
87 }
88
dd9fbcb8 89 type = ntohl(xdr->type);
dd9fbcb8 90 switch (type) {
888b3384
DH
91 case AFS_FTYPE_FILE:
92 case AFS_FTYPE_DIR:
93 case AFS_FTYPE_SYMLINK:
dd9fbcb8 94 status->type = type;
888b3384 95 break;
888b3384 96 default:
dd9fbcb8 97 goto bad;
888b3384
DH
98 }
99
a58823ac
DH
100 status->nlink = ntohl(xdr->nlink);
101 status->author = ntohl(xdr->author);
102 status->owner = ntohl(xdr->owner);
103 status->caller_access = ntohl(xdr->caller_access); /* Ticket dependent */
104 status->anon_access = ntohl(xdr->anon_access);
105 status->mode = ntohl(xdr->mode) & S_IALLUGO;
106 status->group = ntohl(xdr->group);
107 status->lock_count = ntohl(xdr->lock_count);
dd9fbcb8 108
d4936803
DH
109 status->mtime_client.tv_sec = ntohl(xdr->mtime_client);
110 status->mtime_client.tv_nsec = 0;
111 status->mtime_server.tv_sec = ntohl(xdr->mtime_server);
112 status->mtime_server.tv_nsec = 0;
dd9fbcb8
DH
113
114 size = (u64)ntohl(xdr->size_lo);
115 size |= (u64)ntohl(xdr->size_hi) << 32;
63a4681f 116 status->size = size;
dd9fbcb8
DH
117
118 data_version = (u64)ntohl(xdr->data_version_lo);
119 data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
a58823ac 120 status->data_version = data_version;
a38a7558 121 scb->have_status = true;
c72057b5 122advance:
dd9fbcb8 123 *_bp = (const void *)*_bp + sizeof(*xdr);
38355eec 124 return;
dd9fbcb8
DH
125
126bad:
127 xdr_dump_bad(*_bp);
7126ead9 128 afs_protocol_error(call, afs_eproto_bad_status);
c72057b5 129 goto advance;
c875c76a
DH
130}
131
78107055
DH
132static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
133{
7903192c 134 return ktime_divns(call->issue_time, NSEC_PER_SEC) + expiry;
78107055
DH
135}
136
a58823ac
DH
137static void xdr_decode_AFSCallBack(const __be32 **_bp,
138 struct afs_call *call,
139 struct afs_status_cb *scb)
78107055 140{
a58823ac 141 struct afs_callback *cb = &scb->callback;
78107055
DH
142 const __be32 *bp = *_bp;
143
7c712458 144 bp++; /* version */
78107055 145 cb->expires_at = xdr_decode_expiry(call, ntohl(*bp++));
7c712458 146 bp++; /* type */
a58823ac 147 scb->have_cb = true;
78107055
DH
148 *_bp = bp;
149}
150
1da177e4 151/*
08e0e7c8 152 * decode an AFSVolSync block
1da177e4 153 */
08e0e7c8
DH
154static void xdr_decode_AFSVolSync(const __be32 **_bp,
155 struct afs_volsync *volsync)
1da177e4 156{
08e0e7c8 157 const __be32 *bp = *_bp;
30062bd1 158 u32 creation;
1da177e4 159
30062bd1 160 creation = ntohl(*bp++);
08e0e7c8
DH
161 bp++; /* spare2 */
162 bp++; /* spare3 */
163 bp++; /* spare4 */
164 bp++; /* spare5 */
165 bp++; /* spare6 */
166 *_bp = bp;
30062bd1
DH
167
168 if (volsync)
169 volsync->creation = creation;
08e0e7c8 170}
1da177e4 171
31143d5d
DH
172/*
173 * encode the requested attributes into an AFSStoreStatus block
174 */
175static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
176{
177 __be32 *bp = *_bp;
178 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
179
180 mask = 0;
181 if (attr->ia_valid & ATTR_MTIME) {
182 mask |= AFS_SET_MTIME;
183 mtime = attr->ia_mtime.tv_sec;
184 }
185
186 if (attr->ia_valid & ATTR_UID) {
187 mask |= AFS_SET_OWNER;
a0a5386a 188 owner = from_kuid(&init_user_ns, attr->ia_uid);
31143d5d
DH
189 }
190
191 if (attr->ia_valid & ATTR_GID) {
192 mask |= AFS_SET_GROUP;
a0a5386a 193 group = from_kgid(&init_user_ns, attr->ia_gid);
31143d5d
DH
194 }
195
196 if (attr->ia_valid & ATTR_MODE) {
197 mask |= AFS_SET_MODE;
198 mode = attr->ia_mode & S_IALLUGO;
199 }
200
201 *bp++ = htonl(mask);
202 *bp++ = htonl(mtime);
203 *bp++ = htonl(owner);
204 *bp++ = htonl(group);
205 *bp++ = htonl(mode);
206 *bp++ = 0; /* segment size */
207 *_bp = bp;
208}
209
45222b9e
DH
210/*
211 * decode an AFSFetchVolumeStatus block
212 */
213static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
214 struct afs_volume_status *vs)
215{
216 const __be32 *bp = *_bp;
217
218 vs->vid = ntohl(*bp++);
219 vs->parent_id = ntohl(*bp++);
220 vs->online = ntohl(*bp++);
221 vs->in_service = ntohl(*bp++);
222 vs->blessed = ntohl(*bp++);
223 vs->needs_salvage = ntohl(*bp++);
224 vs->type = ntohl(*bp++);
225 vs->min_quota = ntohl(*bp++);
226 vs->max_quota = ntohl(*bp++);
227 vs->blocks_in_use = ntohl(*bp++);
228 vs->part_blocks_avail = ntohl(*bp++);
229 vs->part_max_blocks = ntohl(*bp++);
30062bd1
DH
230 vs->vol_copy_date = 0;
231 vs->vol_backup_date = 0;
45222b9e
DH
232 *_bp = bp;
233}
234
08e0e7c8
DH
235/*
236 * deliver reply data to an FS.FetchStatus
237 */
e49c7b2f 238static int afs_deliver_fs_fetch_status(struct afs_call *call)
08e0e7c8 239{
e49c7b2f
DH
240 struct afs_operation *op = call->op;
241 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
08e0e7c8 242 const __be32 *bp;
372ee163 243 int ret;
1da177e4 244
d001648e 245 ret = afs_transfer_reply(call);
372ee163
DH
246 if (ret < 0)
247 return ret;
1da177e4 248
08e0e7c8
DH
249 /* unmarshall the reply once we've received all of it */
250 bp = call->buffer;
e49c7b2f
DH
251 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
252 xdr_decode_AFSCallBack(&bp, call, &vp->scb);
253 xdr_decode_AFSVolSync(&bp, &op->volsync);
1da177e4 254
08e0e7c8
DH
255 _leave(" = 0 [done]");
256 return 0;
ec26815a 257}
08e0e7c8
DH
258
259/*
260 * FS.FetchStatus operation type
261 */
e49c7b2f
DH
262static const struct afs_call_type afs_RXFSFetchStatus = {
263 .name = "FS.FetchStatus",
025db80c 264 .op = afs_FS_FetchStatus,
e49c7b2f 265 .deliver = afs_deliver_fs_fetch_status,
08e0e7c8
DH
266 .destructor = afs_flat_call_destructor,
267};
1da177e4 268
1da177e4
LT
269/*
270 * fetch the status information for a file
271 */
e49c7b2f 272void afs_fs_fetch_status(struct afs_operation *op)
1da177e4 273{
e49c7b2f 274 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
08e0e7c8 275 struct afs_call *call;
1da177e4
LT
276 __be32 *bp;
277
3b6492df 278 _enter(",%x,{%llx:%llu},,",
e49c7b2f 279 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1da177e4 280
e49c7b2f 281 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchStatus,
5cf9dd55 282 16, (21 + 3 + 6) * 4);
e49c7b2f
DH
283 if (!call)
284 return afs_op_nomem(op);
1da177e4
LT
285
286 /* marshall the parameters */
08e0e7c8 287 bp = call->request;
1da177e4 288 bp[0] = htonl(FSFETCHSTATUS);
e49c7b2f
DH
289 bp[1] = htonl(vp->fid.vid);
290 bp[2] = htonl(vp->fid.vnode);
291 bp[3] = htonl(vp->fid.unique);
1da177e4 292
abcbd3bf 293 call->fid = vp->fid;
e49c7b2f
DH
294 trace_afs_make_fs_call(call, &vp->fid);
295 afs_make_op_call(op, call, GFP_NOFS);
ec26815a 296}
1da177e4 297
1da177e4 298/*
08e0e7c8 299 * deliver reply data to an FS.FetchData
1da177e4 300 */
d001648e 301static int afs_deliver_fs_fetch_data(struct afs_call *call)
1da177e4 302{
e49c7b2f 303 struct afs_operation *op = call->op;
f28fc201 304 struct netfs_io_subrequest *subreq = op->fetch.subreq;
e49c7b2f 305 struct afs_vnode_param *vp = &op->file[0];
08e0e7c8 306 const __be32 *bp;
ee4cdf7b 307 size_t count_before;
1da177e4 308 int ret;
1da177e4 309
f105da1a
DH
310 _enter("{%u,%zu,%zu/%llu}",
311 call->unmarshall, call->iov_len, iov_iter_count(call->iter),
f28fc201 312 call->remaining);
08e0e7c8
DH
313
314 switch (call->unmarshall) {
315 case 0:
f28fc201 316 call->remaining = 0;
08e0e7c8 317 call->unmarshall++;
12bdcf33
DH
318 if (call->operation_ID == FSFETCHDATA64) {
319 afs_extract_to_tmp64(call);
320 } else {
321 call->tmp_u = htonl(0);
322 afs_extract_to_tmp(call);
b9b1f8d5 323 }
df561f66 324 fallthrough;
08e0e7c8 325
f28fc201
DH
326 /* Extract the returned data length into ->remaining.
327 * This may indicate more or less data than was
c4508464
DH
328 * requested will be returned.
329 */
12bdcf33 330 case 1:
08e0e7c8 331 _debug("extract data length");
12bdcf33 332 ret = afs_extract_data(call, true);
372ee163
DH
333 if (ret < 0)
334 return ret;
1da177e4 335
f28fc201
DH
336 call->remaining = be64_to_cpu(call->tmp64);
337 _debug("DATA length: %llu", call->remaining);
c4508464 338
f28fc201 339 if (call->remaining == 0)
196ee9cd 340 goto no_more_data;
12bdcf33 341
f28fc201
DH
342 call->iter = &subreq->io_iter;
343 call->iov_len = umin(call->remaining, subreq->len - subreq->transferred);
08e0e7c8 344 call->unmarshall++;
df561f66 345 fallthrough;
196ee9cd 346
29881608 347 /* extract the returned data */
12bdcf33 348 case 2:
ee4cdf7b 349 count_before = call->iov_len;
f28fc201 350 _debug("extract data %zu/%llu", count_before, call->remaining);
196ee9cd 351
12bdcf33 352 ret = afs_extract_data(call, true);
f28fc201
DH
353 subreq->transferred += count_before - call->iov_len;
354 call->remaining -= count_before - call->iov_len;
196ee9cd
DH
355 if (ret < 0)
356 return ret;
12bdcf33 357
c4508464 358 call->iter = &call->def_iter;
f28fc201 359 if (call->remaining)
12bdcf33 360 goto no_more_data;
6db3ac3c
DH
361
362 /* Discard any excess data the server gave us */
f28fc201 363 afs_extract_discard(call, call->remaining);
12bdcf33 364 call->unmarshall = 3;
df561f66 365 fallthrough;
29881608 366
12bdcf33
DH
367 case 3:
368 _debug("extract discard %zu/%llu",
f28fc201 369 iov_iter_count(call->iter), call->remaining);
12bdcf33
DH
370
371 ret = afs_extract_data(call, true);
6db3ac3c
DH
372 if (ret < 0)
373 return ret;
1da177e4 374
196ee9cd 375 no_more_data:
12bdcf33
DH
376 call->unmarshall = 4;
377 afs_extract_to_buf(call, (21 + 3 + 6) * 4);
df561f66 378 fallthrough;
1da177e4 379
29881608 380 /* extract the metadata */
12bdcf33
DH
381 case 4:
382 ret = afs_extract_data(call, false);
372ee163
DH
383 if (ret < 0)
384 return ret;
08e0e7c8
DH
385
386 bp = call->buffer;
e49c7b2f
DH
387 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
388 xdr_decode_AFSCallBack(&bp, call, &vp->scb);
389 xdr_decode_AFSVolSync(&bp, &op->volsync);
08e0e7c8 390
f28fc201
DH
391 if (subreq->start + subreq->transferred >= vp->scb.status.size)
392 __set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
a58823ac 393
08e0e7c8 394 call->unmarshall++;
b2db6c35 395 fallthrough;
1da177e4 396
12bdcf33 397 case 5:
08e0e7c8 398 break;
1da177e4
LT
399 }
400
08e0e7c8
DH
401 _leave(" = 0 [done]");
402 return 0;
ec26815a 403}
1da177e4 404
1da177e4 405/*
08e0e7c8 406 * FS.FetchData operation type
1da177e4 407 */
08e0e7c8 408static const struct afs_call_type afs_RXFSFetchData = {
00d3b7a4 409 .name = "FS.FetchData",
025db80c 410 .op = afs_FS_FetchData,
eddf51f2 411 .async_rx = afs_fetch_data_async_rx,
08e0e7c8 412 .deliver = afs_deliver_fs_fetch_data,
eddf51f2 413 .immediate_cancel = afs_fetch_data_immediate_cancel,
e49c7b2f 414 .destructor = afs_flat_call_destructor,
08e0e7c8
DH
415};
416
b9b1f8d5
DH
417static const struct afs_call_type afs_RXFSFetchData64 = {
418 .name = "FS.FetchData64",
025db80c 419 .op = afs_FS_FetchData64,
eddf51f2 420 .async_rx = afs_fetch_data_async_rx,
b9b1f8d5 421 .deliver = afs_deliver_fs_fetch_data,
eddf51f2 422 .immediate_cancel = afs_fetch_data_immediate_cancel,
e49c7b2f 423 .destructor = afs_flat_call_destructor,
b9b1f8d5
DH
424};
425
426/*
427 * fetch data from a very large file
428 */
e49c7b2f 429static void afs_fs_fetch_data64(struct afs_operation *op)
b9b1f8d5 430{
f28fc201 431 struct netfs_io_subrequest *subreq = op->fetch.subreq;
e49c7b2f 432 struct afs_vnode_param *vp = &op->file[0];
b9b1f8d5
DH
433 struct afs_call *call;
434 __be32 *bp;
435
436 _enter("");
437
e49c7b2f 438 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
b9b1f8d5 439 if (!call)
e49c7b2f 440 return afs_op_nomem(op);
b9b1f8d5 441
eddf51f2
DH
442 if (op->flags & AFS_OPERATION_ASYNC)
443 call->async = true;
444
b9b1f8d5
DH
445 /* marshall the parameters */
446 bp = call->request;
447 bp[0] = htonl(FSFETCHDATA64);
e49c7b2f
DH
448 bp[1] = htonl(vp->fid.vid);
449 bp[2] = htonl(vp->fid.vnode);
450 bp[3] = htonl(vp->fid.unique);
f28fc201
DH
451 bp[4] = htonl(upper_32_bits(subreq->start + subreq->transferred));
452 bp[5] = htonl(lower_32_bits(subreq->start + subreq->transferred));
b9b1f8d5 453 bp[6] = 0;
f28fc201 454 bp[7] = htonl(lower_32_bits(subreq->len - subreq->transferred));
b9b1f8d5 455
abcbd3bf 456 call->fid = vp->fid;
e49c7b2f
DH
457 trace_afs_make_fs_call(call, &vp->fid);
458 afs_make_op_call(op, call, GFP_NOFS);
b9b1f8d5
DH
459}
460
08e0e7c8
DH
461/*
462 * fetch data from a file
463 */
e49c7b2f 464void afs_fs_fetch_data(struct afs_operation *op)
1da177e4 465{
f28fc201 466 struct netfs_io_subrequest *subreq = op->fetch.subreq;
e49c7b2f 467 struct afs_vnode_param *vp = &op->file[0];
08e0e7c8 468 struct afs_call *call;
1da177e4
LT
469 __be32 *bp;
470
b537a3c2 471 if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))
e49c7b2f 472 return afs_fs_fetch_data64(op);
b9b1f8d5 473
08e0e7c8 474 _enter("");
1da177e4 475
e49c7b2f 476 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
08e0e7c8 477 if (!call)
e49c7b2f 478 return afs_op_nomem(op);
1da177e4
LT
479
480 /* marshall the parameters */
08e0e7c8
DH
481 bp = call->request;
482 bp[0] = htonl(FSFETCHDATA);
e49c7b2f
DH
483 bp[1] = htonl(vp->fid.vid);
484 bp[2] = htonl(vp->fid.vnode);
485 bp[3] = htonl(vp->fid.unique);
f28fc201
DH
486 bp[4] = htonl(lower_32_bits(subreq->start + subreq->transferred));
487 bp[5] = htonl(lower_32_bits(subreq->len + subreq->transferred));
1da177e4 488
abcbd3bf 489 call->fid = vp->fid;
e49c7b2f
DH
490 trace_afs_make_fs_call(call, &vp->fid);
491 afs_make_op_call(op, call, GFP_NOFS);
ec26815a 492}
260a9803
DH
493
494/*
495 * deliver reply data to an FS.CreateFile or an FS.MakeDir
496 */
d001648e 497static int afs_deliver_fs_create_vnode(struct afs_call *call)
260a9803 498{
e49c7b2f
DH
499 struct afs_operation *op = call->op;
500 struct afs_vnode_param *dvp = &op->file[0];
501 struct afs_vnode_param *vp = &op->file[1];
260a9803 502 const __be32 *bp;
372ee163 503 int ret;
260a9803 504
d001648e 505 ret = afs_transfer_reply(call);
372ee163
DH
506 if (ret < 0)
507 return ret;
260a9803
DH
508
509 /* unmarshall the reply once we've received all of it */
510 bp = call->buffer;
e49c7b2f
DH
511 xdr_decode_AFSFid(&bp, &op->file[1].fid);
512 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
513 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);
514 xdr_decode_AFSCallBack(&bp, call, &vp->scb);
515 xdr_decode_AFSVolSync(&bp, &op->volsync);
260a9803
DH
516
517 _leave(" = 0 [done]");
518 return 0;
519}
520
521/*
522 * FS.CreateFile and FS.MakeDir operation type
523 */
025db80c
DH
524static const struct afs_call_type afs_RXFSCreateFile = {
525 .name = "FS.CreateFile",
526 .op = afs_FS_CreateFile,
527 .deliver = afs_deliver_fs_create_vnode,
528 .destructor = afs_flat_call_destructor,
529};
530
e49c7b2f
DH
531/*
532 * Create a file.
533 */
534void afs_fs_create_file(struct afs_operation *op)
535{
536 const struct qstr *name = &op->dentry->d_name;
537 struct afs_vnode_param *dvp = &op->file[0];
538 struct afs_call *call;
539 size_t namesz, reqsz, padsz;
540 __be32 *bp;
541
542 _enter("");
543
544 namesz = name->len;
545 padsz = (4 - (namesz & 3)) & 3;
546 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
547
548 call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile,
549 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
550 if (!call)
551 return afs_op_nomem(op);
552
553 /* marshall the parameters */
554 bp = call->request;
555 *bp++ = htonl(FSCREATEFILE);
556 *bp++ = htonl(dvp->fid.vid);
557 *bp++ = htonl(dvp->fid.vnode);
558 *bp++ = htonl(dvp->fid.unique);
559 *bp++ = htonl(namesz);
560 memcpy(bp, name->name, namesz);
561 bp = (void *) bp + namesz;
562 if (padsz > 0) {
563 memset(bp, 0, padsz);
564 bp = (void *) bp + padsz;
565 }
566 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
567 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
568 *bp++ = 0; /* owner */
569 *bp++ = 0; /* group */
570 *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */
571 *bp++ = 0; /* segment size */
572
abcbd3bf 573 call->fid = dvp->fid;
e49c7b2f
DH
574 trace_afs_make_fs_call1(call, &dvp->fid, name);
575 afs_make_op_call(op, call, GFP_NOFS);
576}
577
025db80c
DH
578static const struct afs_call_type afs_RXFSMakeDir = {
579 .name = "FS.MakeDir",
580 .op = afs_FS_MakeDir,
260a9803 581 .deliver = afs_deliver_fs_create_vnode,
260a9803
DH
582 .destructor = afs_flat_call_destructor,
583};
584
585/*
e49c7b2f 586 * Create a new directory
260a9803 587 */
e49c7b2f 588void afs_fs_make_dir(struct afs_operation *op)
260a9803 589{
e49c7b2f
DH
590 const struct qstr *name = &op->dentry->d_name;
591 struct afs_vnode_param *dvp = &op->file[0];
260a9803
DH
592 struct afs_call *call;
593 size_t namesz, reqsz, padsz;
594 __be32 *bp;
595
596 _enter("");
597
e49c7b2f 598 namesz = name->len;
260a9803
DH
599 padsz = (4 - (namesz & 3)) & 3;
600 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
601
e49c7b2f
DH
602 call = afs_alloc_flat_call(op->net, &afs_RXFSMakeDir,
603 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
260a9803 604 if (!call)
e49c7b2f 605 return afs_op_nomem(op);
260a9803
DH
606
607 /* marshall the parameters */
608 bp = call->request;
e49c7b2f
DH
609 *bp++ = htonl(FSMAKEDIR);
610 *bp++ = htonl(dvp->fid.vid);
611 *bp++ = htonl(dvp->fid.vnode);
612 *bp++ = htonl(dvp->fid.unique);
260a9803 613 *bp++ = htonl(namesz);
e49c7b2f 614 memcpy(bp, name->name, namesz);
260a9803
DH
615 bp = (void *) bp + namesz;
616 if (padsz > 0) {
617 memset(bp, 0, padsz);
618 bp = (void *) bp + padsz;
619 }
ab94f5d0 620 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
e49c7b2f 621 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
260a9803
DH
622 *bp++ = 0; /* owner */
623 *bp++ = 0; /* group */
e49c7b2f 624 *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */
260a9803
DH
625 *bp++ = 0; /* segment size */
626
abcbd3bf 627 call->fid = dvp->fid;
e49c7b2f
DH
628 trace_afs_make_fs_call1(call, &dvp->fid, name);
629 afs_make_op_call(op, call, GFP_NOFS);
260a9803
DH
630}
631
632/*
e49c7b2f 633 * Deliver reply data to any operation that returns status and volume sync.
260a9803 634 */
e49c7b2f 635static int afs_deliver_fs_file_status_and_vol(struct afs_call *call)
260a9803 636{
e49c7b2f
DH
637 struct afs_operation *op = call->op;
638 struct afs_vnode_param *vp = &op->file[0];
260a9803 639 const __be32 *bp;
372ee163 640 int ret;
260a9803 641
d001648e 642 ret = afs_transfer_reply(call);
372ee163
DH
643 if (ret < 0)
644 return ret;
260a9803
DH
645
646 /* unmarshall the reply once we've received all of it */
647 bp = call->buffer;
e49c7b2f
DH
648 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
649 xdr_decode_AFSVolSync(&bp, &op->volsync);
260a9803
DH
650
651 _leave(" = 0 [done]");
652 return 0;
653}
654
655/*
e49c7b2f 656 * FS.RemoveFile operation type
260a9803 657 */
025db80c
DH
658static const struct afs_call_type afs_RXFSRemoveFile = {
659 .name = "FS.RemoveFile",
660 .op = afs_FS_RemoveFile,
e49c7b2f 661 .deliver = afs_deliver_fs_file_status_and_vol,
025db80c
DH
662 .destructor = afs_flat_call_destructor,
663};
664
e49c7b2f
DH
665/*
666 * Remove a file.
667 */
668void afs_fs_remove_file(struct afs_operation *op)
669{
670 const struct qstr *name = &op->dentry->d_name;
671 struct afs_vnode_param *dvp = &op->file[0];
672 struct afs_call *call;
673 size_t namesz, reqsz, padsz;
674 __be32 *bp;
675
676 _enter("");
677
678 namesz = name->len;
679 padsz = (4 - (namesz & 3)) & 3;
680 reqsz = (5 * 4) + namesz + padsz;
681
682 call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveFile,
683 reqsz, (21 + 6) * 4);
684 if (!call)
685 return afs_op_nomem(op);
686
687 /* marshall the parameters */
688 bp = call->request;
689 *bp++ = htonl(FSREMOVEFILE);
690 *bp++ = htonl(dvp->fid.vid);
691 *bp++ = htonl(dvp->fid.vnode);
692 *bp++ = htonl(dvp->fid.unique);
693 *bp++ = htonl(namesz);
694 memcpy(bp, name->name, namesz);
695 bp = (void *) bp + namesz;
696 if (padsz > 0) {
697 memset(bp, 0, padsz);
698 bp = (void *) bp + padsz;
699 }
700
abcbd3bf 701 call->fid = dvp->fid;
e49c7b2f
DH
702 trace_afs_make_fs_call1(call, &dvp->fid, name);
703 afs_make_op_call(op, call, GFP_NOFS);
704}
705
025db80c
DH
706static const struct afs_call_type afs_RXFSRemoveDir = {
707 .name = "FS.RemoveDir",
708 .op = afs_FS_RemoveDir,
e49c7b2f 709 .deliver = afs_deliver_fs_file_status_and_vol,
260a9803
DH
710 .destructor = afs_flat_call_destructor,
711};
712
713/*
e49c7b2f 714 * Remove a directory.
260a9803 715 */
e49c7b2f 716void afs_fs_remove_dir(struct afs_operation *op)
260a9803 717{
e49c7b2f
DH
718 const struct qstr *name = &op->dentry->d_name;
719 struct afs_vnode_param *dvp = &op->file[0];
260a9803
DH
720 struct afs_call *call;
721 size_t namesz, reqsz, padsz;
722 __be32 *bp;
723
724 _enter("");
725
e49c7b2f 726 namesz = name->len;
260a9803
DH
727 padsz = (4 - (namesz & 3)) & 3;
728 reqsz = (5 * 4) + namesz + padsz;
729
e49c7b2f
DH
730 call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveDir,
731 reqsz, (21 + 6) * 4);
260a9803 732 if (!call)
e49c7b2f 733 return afs_op_nomem(op);
260a9803
DH
734
735 /* marshall the parameters */
736 bp = call->request;
e49c7b2f
DH
737 *bp++ = htonl(FSREMOVEDIR);
738 *bp++ = htonl(dvp->fid.vid);
739 *bp++ = htonl(dvp->fid.vnode);
740 *bp++ = htonl(dvp->fid.unique);
260a9803 741 *bp++ = htonl(namesz);
e49c7b2f 742 memcpy(bp, name->name, namesz);
260a9803
DH
743 bp = (void *) bp + namesz;
744 if (padsz > 0) {
745 memset(bp, 0, padsz);
746 bp = (void *) bp + padsz;
747 }
748
abcbd3bf 749 call->fid = dvp->fid;
e49c7b2f
DH
750 trace_afs_make_fs_call1(call, &dvp->fid, name);
751 afs_make_op_call(op, call, GFP_NOFS);
260a9803
DH
752}
753
754/*
755 * deliver reply data to an FS.Link
756 */
d001648e 757static int afs_deliver_fs_link(struct afs_call *call)
260a9803 758{
e49c7b2f
DH
759 struct afs_operation *op = call->op;
760 struct afs_vnode_param *dvp = &op->file[0];
761 struct afs_vnode_param *vp = &op->file[1];
260a9803 762 const __be32 *bp;
372ee163 763 int ret;
260a9803 764
d001648e 765 _enter("{%u}", call->unmarshall);
260a9803 766
d001648e 767 ret = afs_transfer_reply(call);
372ee163
DH
768 if (ret < 0)
769 return ret;
260a9803
DH
770
771 /* unmarshall the reply once we've received all of it */
772 bp = call->buffer;
e49c7b2f
DH
773 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
774 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);
775 xdr_decode_AFSVolSync(&bp, &op->volsync);
260a9803
DH
776
777 _leave(" = 0 [done]");
778 return 0;
779}
780
781/*
782 * FS.Link operation type
783 */
784static const struct afs_call_type afs_RXFSLink = {
785 .name = "FS.Link",
025db80c 786 .op = afs_FS_Link,
260a9803 787 .deliver = afs_deliver_fs_link,
260a9803
DH
788 .destructor = afs_flat_call_destructor,
789};
790
791/*
792 * make a hard link
793 */
e49c7b2f 794void afs_fs_link(struct afs_operation *op)
260a9803 795{
e49c7b2f
DH
796 const struct qstr *name = &op->dentry->d_name;
797 struct afs_vnode_param *dvp = &op->file[0];
798 struct afs_vnode_param *vp = &op->file[1];
260a9803
DH
799 struct afs_call *call;
800 size_t namesz, reqsz, padsz;
801 __be32 *bp;
802
803 _enter("");
804
e49c7b2f 805 namesz = name->len;
260a9803
DH
806 padsz = (4 - (namesz & 3)) & 3;
807 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
808
e49c7b2f 809 call = afs_alloc_flat_call(op->net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
260a9803 810 if (!call)
e49c7b2f 811 return afs_op_nomem(op);
260a9803
DH
812
813 /* marshall the parameters */
814 bp = call->request;
815 *bp++ = htonl(FSLINK);
e49c7b2f
DH
816 *bp++ = htonl(dvp->fid.vid);
817 *bp++ = htonl(dvp->fid.vnode);
818 *bp++ = htonl(dvp->fid.unique);
260a9803 819 *bp++ = htonl(namesz);
e49c7b2f 820 memcpy(bp, name->name, namesz);
260a9803
DH
821 bp = (void *) bp + namesz;
822 if (padsz > 0) {
823 memset(bp, 0, padsz);
824 bp = (void *) bp + padsz;
825 }
e49c7b2f
DH
826 *bp++ = htonl(vp->fid.vid);
827 *bp++ = htonl(vp->fid.vnode);
828 *bp++ = htonl(vp->fid.unique);
829
abcbd3bf 830 call->fid = vp->fid;
e49c7b2f
DH
831 trace_afs_make_fs_call1(call, &vp->fid, name);
832 afs_make_op_call(op, call, GFP_NOFS);
260a9803
DH
833}
834
835/*
836 * deliver reply data to an FS.Symlink
837 */
d001648e 838static int afs_deliver_fs_symlink(struct afs_call *call)
260a9803 839{
e49c7b2f
DH
840 struct afs_operation *op = call->op;
841 struct afs_vnode_param *dvp = &op->file[0];
842 struct afs_vnode_param *vp = &op->file[1];
260a9803 843 const __be32 *bp;
372ee163 844 int ret;
260a9803 845
d001648e 846 _enter("{%u}", call->unmarshall);
260a9803 847
d001648e 848 ret = afs_transfer_reply(call);
372ee163
DH
849 if (ret < 0)
850 return ret;
260a9803
DH
851
852 /* unmarshall the reply once we've received all of it */
853 bp = call->buffer;
e49c7b2f
DH
854 xdr_decode_AFSFid(&bp, &vp->fid);
855 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
856 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);
857 xdr_decode_AFSVolSync(&bp, &op->volsync);
260a9803
DH
858
859 _leave(" = 0 [done]");
860 return 0;
861}
862
863/*
864 * FS.Symlink operation type
865 */
866static const struct afs_call_type afs_RXFSSymlink = {
867 .name = "FS.Symlink",
025db80c 868 .op = afs_FS_Symlink,
260a9803 869 .deliver = afs_deliver_fs_symlink,
260a9803
DH
870 .destructor = afs_flat_call_destructor,
871};
872
873/*
874 * create a symbolic link
875 */
e49c7b2f 876void afs_fs_symlink(struct afs_operation *op)
260a9803 877{
e49c7b2f
DH
878 const struct qstr *name = &op->dentry->d_name;
879 struct afs_vnode_param *dvp = &op->file[0];
260a9803
DH
880 struct afs_call *call;
881 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
882 __be32 *bp;
883
884 _enter("");
885
e49c7b2f 886 namesz = name->len;
260a9803
DH
887 padsz = (4 - (namesz & 3)) & 3;
888
e49c7b2f 889 c_namesz = strlen(op->create.symlink);
260a9803
DH
890 c_padsz = (4 - (c_namesz & 3)) & 3;
891
892 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
893
e49c7b2f 894 call = afs_alloc_flat_call(op->net, &afs_RXFSSymlink, reqsz,
260a9803
DH
895 (3 + 21 + 21 + 6) * 4);
896 if (!call)
e49c7b2f 897 return afs_op_nomem(op);
260a9803
DH
898
899 /* marshall the parameters */
900 bp = call->request;
901 *bp++ = htonl(FSSYMLINK);
e49c7b2f
DH
902 *bp++ = htonl(dvp->fid.vid);
903 *bp++ = htonl(dvp->fid.vnode);
904 *bp++ = htonl(dvp->fid.unique);
260a9803 905 *bp++ = htonl(namesz);
e49c7b2f 906 memcpy(bp, name->name, namesz);
260a9803
DH
907 bp = (void *) bp + namesz;
908 if (padsz > 0) {
909 memset(bp, 0, padsz);
910 bp = (void *) bp + padsz;
911 }
912 *bp++ = htonl(c_namesz);
e49c7b2f 913 memcpy(bp, op->create.symlink, c_namesz);
260a9803
DH
914 bp = (void *) bp + c_namesz;
915 if (c_padsz > 0) {
916 memset(bp, 0, c_padsz);
917 bp = (void *) bp + c_padsz;
918 }
ab94f5d0 919 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
e49c7b2f 920 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
260a9803
DH
921 *bp++ = 0; /* owner */
922 *bp++ = 0; /* group */
923 *bp++ = htonl(S_IRWXUGO); /* unix mode */
924 *bp++ = 0; /* segment size */
925
abcbd3bf 926 call->fid = dvp->fid;
e49c7b2f
DH
927 trace_afs_make_fs_call1(call, &dvp->fid, name);
928 afs_make_op_call(op, call, GFP_NOFS);
260a9803
DH
929}
930
931/*
932 * deliver reply data to an FS.Rename
933 */
d001648e 934static int afs_deliver_fs_rename(struct afs_call *call)
260a9803 935{
e49c7b2f
DH
936 struct afs_operation *op = call->op;
937 struct afs_vnode_param *orig_dvp = &op->file[0];
938 struct afs_vnode_param *new_dvp = &op->file[1];
260a9803 939 const __be32 *bp;
372ee163 940 int ret;
260a9803 941
d001648e 942 ret = afs_transfer_reply(call);
372ee163
DH
943 if (ret < 0)
944 return ret;
260a9803 945
38355eec 946 bp = call->buffer;
b98f0ec9
DH
947 /* If the two dirs are the same, we have two copies of the same status
948 * report, so we just decode it twice.
949 */
e49c7b2f
DH
950 xdr_decode_AFSFetchStatus(&bp, call, &orig_dvp->scb);
951 xdr_decode_AFSFetchStatus(&bp, call, &new_dvp->scb);
952 xdr_decode_AFSVolSync(&bp, &op->volsync);
260a9803
DH
953
954 _leave(" = 0 [done]");
955 return 0;
956}
957
958/*
959 * FS.Rename operation type
960 */
961static const struct afs_call_type afs_RXFSRename = {
962 .name = "FS.Rename",
025db80c 963 .op = afs_FS_Rename,
260a9803 964 .deliver = afs_deliver_fs_rename,
260a9803
DH
965 .destructor = afs_flat_call_destructor,
966};
967
968/*
a58823ac 969 * Rename/move a file or directory.
260a9803 970 */
e49c7b2f 971void afs_fs_rename(struct afs_operation *op)
260a9803 972{
e49c7b2f
DH
973 struct afs_vnode_param *orig_dvp = &op->file[0];
974 struct afs_vnode_param *new_dvp = &op->file[1];
975 const struct qstr *orig_name = &op->dentry->d_name;
976 const struct qstr *new_name = &op->dentry_2->d_name;
260a9803
DH
977 struct afs_call *call;
978 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
979 __be32 *bp;
980
981 _enter("");
982
e49c7b2f 983 o_namesz = orig_name->len;
260a9803
DH
984 o_padsz = (4 - (o_namesz & 3)) & 3;
985
e49c7b2f 986 n_namesz = new_name->len;
260a9803
DH
987 n_padsz = (4 - (n_namesz & 3)) & 3;
988
989 reqsz = (4 * 4) +
990 4 + o_namesz + o_padsz +
991 (3 * 4) +
992 4 + n_namesz + n_padsz;
993
e49c7b2f 994 call = afs_alloc_flat_call(op->net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
260a9803 995 if (!call)
e49c7b2f 996 return afs_op_nomem(op);
260a9803
DH
997
998 /* marshall the parameters */
999 bp = call->request;
1000 *bp++ = htonl(FSRENAME);
e49c7b2f
DH
1001 *bp++ = htonl(orig_dvp->fid.vid);
1002 *bp++ = htonl(orig_dvp->fid.vnode);
1003 *bp++ = htonl(orig_dvp->fid.unique);
260a9803 1004 *bp++ = htonl(o_namesz);
e49c7b2f 1005 memcpy(bp, orig_name->name, o_namesz);
260a9803
DH
1006 bp = (void *) bp + o_namesz;
1007 if (o_padsz > 0) {
1008 memset(bp, 0, o_padsz);
1009 bp = (void *) bp + o_padsz;
1010 }
1011
e49c7b2f
DH
1012 *bp++ = htonl(new_dvp->fid.vid);
1013 *bp++ = htonl(new_dvp->fid.vnode);
1014 *bp++ = htonl(new_dvp->fid.unique);
260a9803 1015 *bp++ = htonl(n_namesz);
e49c7b2f 1016 memcpy(bp, new_name->name, n_namesz);
260a9803
DH
1017 bp = (void *) bp + n_namesz;
1018 if (n_padsz > 0) {
1019 memset(bp, 0, n_padsz);
1020 bp = (void *) bp + n_padsz;
1021 }
1022
abcbd3bf 1023 call->fid = orig_dvp->fid;
e49c7b2f
DH
1024 trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1025 afs_make_op_call(op, call, GFP_NOFS);
260a9803 1026}
31143d5d
DH
1027
1028/*
e49c7b2f 1029 * Deliver reply data to FS.StoreData or FS.StoreStatus
31143d5d 1030 */
d001648e 1031static int afs_deliver_fs_store_data(struct afs_call *call)
31143d5d 1032{
e49c7b2f
DH
1033 struct afs_operation *op = call->op;
1034 struct afs_vnode_param *vp = &op->file[0];
31143d5d 1035 const __be32 *bp;
372ee163 1036 int ret;
31143d5d 1037
d001648e 1038 _enter("");
31143d5d 1039
d001648e 1040 ret = afs_transfer_reply(call);
372ee163
DH
1041 if (ret < 0)
1042 return ret;
31143d5d
DH
1043
1044 /* unmarshall the reply once we've received all of it */
1045 bp = call->buffer;
e49c7b2f
DH
1046 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
1047 xdr_decode_AFSVolSync(&bp, &op->volsync);
31143d5d 1048
31143d5d
DH
1049 _leave(" = 0 [done]");
1050 return 0;
1051}
1052
1053/*
1054 * FS.StoreData operation type
1055 */
1056static const struct afs_call_type afs_RXFSStoreData = {
1057 .name = "FS.StoreData",
025db80c 1058 .op = afs_FS_StoreData,
31143d5d 1059 .deliver = afs_deliver_fs_store_data,
31143d5d
DH
1060 .destructor = afs_flat_call_destructor,
1061};
1062
b9b1f8d5
DH
1063static const struct afs_call_type afs_RXFSStoreData64 = {
1064 .name = "FS.StoreData64",
025db80c 1065 .op = afs_FS_StoreData64,
b9b1f8d5 1066 .deliver = afs_deliver_fs_store_data,
b9b1f8d5
DH
1067 .destructor = afs_flat_call_destructor,
1068};
1069
1070/*
1071 * store a set of pages to a very large file
1072 */
bd80d8a8 1073static void afs_fs_store_data64(struct afs_operation *op)
b9b1f8d5 1074{
e49c7b2f 1075 struct afs_vnode_param *vp = &op->file[0];
b9b1f8d5
DH
1076 struct afs_call *call;
1077 __be32 *bp;
1078
3b6492df 1079 _enter(",%x,{%llx:%llu},,",
e49c7b2f 1080 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
b9b1f8d5 1081
e49c7b2f 1082 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64,
b9b1f8d5
DH
1083 (4 + 6 + 3 * 2) * 4,
1084 (21 + 6) * 4);
1085 if (!call)
e49c7b2f 1086 return afs_op_nomem(op);
b9b1f8d5 1087
bd80d8a8 1088 call->write_iter = op->store.write_iter;
b9b1f8d5
DH
1089
1090 /* marshall the parameters */
1091 bp = call->request;
1092 *bp++ = htonl(FSSTOREDATA64);
e49c7b2f
DH
1093 *bp++ = htonl(vp->fid.vid);
1094 *bp++ = htonl(vp->fid.vnode);
1095 *bp++ = htonl(vp->fid.unique);
b9b1f8d5 1096
ab94f5d0 1097 *bp++ = htonl(AFS_SET_MTIME); /* mask */
e49c7b2f 1098 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
b9b1f8d5
DH
1099 *bp++ = 0; /* owner */
1100 *bp++ = 0; /* group */
1101 *bp++ = 0; /* unix mode */
1102 *bp++ = 0; /* segment size */
1103
bd80d8a8
DH
1104 *bp++ = htonl(upper_32_bits(op->store.pos));
1105 *bp++ = htonl(lower_32_bits(op->store.pos));
1106 *bp++ = htonl(upper_32_bits(op->store.size));
1107 *bp++ = htonl(lower_32_bits(op->store.size));
1108 *bp++ = htonl(upper_32_bits(op->store.i_size));
1109 *bp++ = htonl(lower_32_bits(op->store.i_size));
e49c7b2f 1110
abcbd3bf 1111 call->fid = vp->fid;
e49c7b2f
DH
1112 trace_afs_make_fs_call(call, &vp->fid);
1113 afs_make_op_call(op, call, GFP_NOFS);
b9b1f8d5
DH
1114}
1115
31143d5d 1116/*
bd80d8a8 1117 * Write data to a file on the server.
31143d5d 1118 */
e49c7b2f 1119void afs_fs_store_data(struct afs_operation *op)
31143d5d 1120{
e49c7b2f 1121 struct afs_vnode_param *vp = &op->file[0];
31143d5d 1122 struct afs_call *call;
31143d5d
DH
1123 __be32 *bp;
1124
3b6492df 1125 _enter(",%x,{%llx:%llu},,",
e49c7b2f 1126 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
31143d5d 1127
31143d5d 1128 _debug("size %llx, at %llx, i_size %llx",
bd80d8a8
DH
1129 (unsigned long long)op->store.size,
1130 (unsigned long long)op->store.pos,
1131 (unsigned long long)op->store.i_size);
31143d5d 1132
b537a3c2 1133 if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))
bd80d8a8 1134 return afs_fs_store_data64(op);
31143d5d 1135
e49c7b2f 1136 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData,
31143d5d
DH
1137 (4 + 6 + 3) * 4,
1138 (21 + 6) * 4);
1139 if (!call)
e49c7b2f 1140 return afs_op_nomem(op);
31143d5d 1141
bd80d8a8 1142 call->write_iter = op->store.write_iter;
31143d5d
DH
1143
1144 /* marshall the parameters */
1145 bp = call->request;
1146 *bp++ = htonl(FSSTOREDATA);
e49c7b2f
DH
1147 *bp++ = htonl(vp->fid.vid);
1148 *bp++ = htonl(vp->fid.vnode);
1149 *bp++ = htonl(vp->fid.unique);
31143d5d 1150
ab94f5d0 1151 *bp++ = htonl(AFS_SET_MTIME); /* mask */
e49c7b2f 1152 *bp++ = htonl(op->mtime.tv_sec); /* mtime */
31143d5d
DH
1153 *bp++ = 0; /* owner */
1154 *bp++ = 0; /* group */
1155 *bp++ = 0; /* unix mode */
1156 *bp++ = 0; /* segment size */
1157
bd80d8a8
DH
1158 *bp++ = htonl(lower_32_bits(op->store.pos));
1159 *bp++ = htonl(lower_32_bits(op->store.size));
1160 *bp++ = htonl(lower_32_bits(op->store.i_size));
31143d5d 1161
abcbd3bf 1162 call->fid = vp->fid;
e49c7b2f
DH
1163 trace_afs_make_fs_call(call, &vp->fid);
1164 afs_make_op_call(op, call, GFP_NOFS);
31143d5d
DH
1165}
1166
1167/*
1168 * FS.StoreStatus operation type
1169 */
1170static const struct afs_call_type afs_RXFSStoreStatus = {
1171 .name = "FS.StoreStatus",
025db80c 1172 .op = afs_FS_StoreStatus,
e49c7b2f 1173 .deliver = afs_deliver_fs_store_data,
31143d5d
DH
1174 .destructor = afs_flat_call_destructor,
1175};
1176
1177static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1178 .name = "FS.StoreData",
025db80c 1179 .op = afs_FS_StoreData,
e49c7b2f 1180 .deliver = afs_deliver_fs_store_data,
31143d5d
DH
1181 .destructor = afs_flat_call_destructor,
1182};
1183
b9b1f8d5
DH
1184static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1185 .name = "FS.StoreData64",
025db80c 1186 .op = afs_FS_StoreData64,
e49c7b2f 1187 .deliver = afs_deliver_fs_store_data,
b9b1f8d5
DH
1188 .destructor = afs_flat_call_destructor,
1189};
1190
1191/*
1192 * set the attributes on a very large file, using FS.StoreData rather than
1193 * FS.StoreStatus so as to alter the file size also
1194 */
e49c7b2f 1195static void afs_fs_setattr_size64(struct afs_operation *op)
b9b1f8d5 1196{
e49c7b2f 1197 struct afs_vnode_param *vp = &op->file[0];
b9b1f8d5 1198 struct afs_call *call;
e49c7b2f 1199 struct iattr *attr = op->setattr.attr;
b9b1f8d5
DH
1200 __be32 *bp;
1201
3b6492df 1202 _enter(",%x,{%llx:%llu},,",
e49c7b2f 1203 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
b9b1f8d5
DH
1204
1205 ASSERT(attr->ia_valid & ATTR_SIZE);
1206
e49c7b2f 1207 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64_as_Status,
b9b1f8d5
DH
1208 (4 + 6 + 3 * 2) * 4,
1209 (21 + 6) * 4);
1210 if (!call)
e49c7b2f 1211 return afs_op_nomem(op);
b9b1f8d5
DH
1212
1213 /* marshall the parameters */
1214 bp = call->request;
1215 *bp++ = htonl(FSSTOREDATA64);
e49c7b2f
DH
1216 *bp++ = htonl(vp->fid.vid);
1217 *bp++ = htonl(vp->fid.vnode);
1218 *bp++ = htonl(vp->fid.unique);
b9b1f8d5
DH
1219
1220 xdr_encode_AFS_StoreStatus(&bp, attr);
1221
e49c7b2f
DH
1222 *bp++ = htonl(upper_32_bits(attr->ia_size)); /* position of start of write */
1223 *bp++ = htonl(lower_32_bits(attr->ia_size));
1224 *bp++ = 0; /* size of write */
b9b1f8d5 1225 *bp++ = 0;
e49c7b2f
DH
1226 *bp++ = htonl(upper_32_bits(attr->ia_size)); /* new file length */
1227 *bp++ = htonl(lower_32_bits(attr->ia_size));
1228
abcbd3bf 1229 call->fid = vp->fid;
e49c7b2f
DH
1230 trace_afs_make_fs_call(call, &vp->fid);
1231 afs_make_op_call(op, call, GFP_NOFS);
b9b1f8d5
DH
1232}
1233
31143d5d
DH
1234/*
1235 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1236 * so as to alter the file size also
1237 */
e49c7b2f 1238static void afs_fs_setattr_size(struct afs_operation *op)
31143d5d 1239{
e49c7b2f 1240 struct afs_vnode_param *vp = &op->file[0];
31143d5d 1241 struct afs_call *call;
e49c7b2f 1242 struct iattr *attr = op->setattr.attr;
31143d5d
DH
1243 __be32 *bp;
1244
3b6492df 1245 _enter(",%x,{%llx:%llu},,",
e49c7b2f 1246 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
31143d5d
DH
1247
1248 ASSERT(attr->ia_valid & ATTR_SIZE);
b537a3c2 1249 if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))
e49c7b2f 1250 return afs_fs_setattr_size64(op);
31143d5d 1251
e49c7b2f 1252 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status,
31143d5d
DH
1253 (4 + 6 + 3) * 4,
1254 (21 + 6) * 4);
1255 if (!call)
e49c7b2f 1256 return afs_op_nomem(op);
31143d5d
DH
1257
1258 /* marshall the parameters */
1259 bp = call->request;
1260 *bp++ = htonl(FSSTOREDATA);
e49c7b2f
DH
1261 *bp++ = htonl(vp->fid.vid);
1262 *bp++ = htonl(vp->fid.vnode);
1263 *bp++ = htonl(vp->fid.unique);
31143d5d
DH
1264
1265 xdr_encode_AFS_StoreStatus(&bp, attr);
1266
8c7ae38d 1267 *bp++ = htonl(attr->ia_size); /* position of start of write */
31143d5d
DH
1268 *bp++ = 0; /* size of write */
1269 *bp++ = htonl(attr->ia_size); /* new file length */
1270
abcbd3bf 1271 call->fid = vp->fid;
e49c7b2f
DH
1272 trace_afs_make_fs_call(call, &vp->fid);
1273 afs_make_op_call(op, call, GFP_NOFS);
31143d5d
DH
1274}
1275
1276/*
1277 * set the attributes on a file, using FS.StoreData if there's a change in file
1278 * size, and FS.StoreStatus otherwise
1279 */
e49c7b2f 1280void afs_fs_setattr(struct afs_operation *op)
31143d5d 1281{
e49c7b2f 1282 struct afs_vnode_param *vp = &op->file[0];
31143d5d 1283 struct afs_call *call;
e49c7b2f 1284 struct iattr *attr = op->setattr.attr;
31143d5d
DH
1285 __be32 *bp;
1286
1287 if (attr->ia_valid & ATTR_SIZE)
e49c7b2f 1288 return afs_fs_setattr_size(op);
31143d5d 1289
3b6492df 1290 _enter(",%x,{%llx:%llu},,",
e49c7b2f 1291 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
31143d5d 1292
e49c7b2f 1293 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreStatus,
31143d5d
DH
1294 (4 + 6) * 4,
1295 (21 + 6) * 4);
1296 if (!call)
e49c7b2f 1297 return afs_op_nomem(op);
31143d5d
DH
1298
1299 /* marshall the parameters */
1300 bp = call->request;
1301 *bp++ = htonl(FSSTORESTATUS);
e49c7b2f
DH
1302 *bp++ = htonl(vp->fid.vid);
1303 *bp++ = htonl(vp->fid.vnode);
1304 *bp++ = htonl(vp->fid.unique);
31143d5d 1305
e49c7b2f 1306 xdr_encode_AFS_StoreStatus(&bp, op->setattr.attr);
31143d5d 1307
abcbd3bf 1308 call->fid = vp->fid;
e49c7b2f
DH
1309 trace_afs_make_fs_call(call, &vp->fid);
1310 afs_make_op_call(op, call, GFP_NOFS);
31143d5d 1311}
45222b9e
DH
1312
1313/*
1314 * deliver reply data to an FS.GetVolumeStatus
1315 */
d001648e 1316static int afs_deliver_fs_get_volume_status(struct afs_call *call)
45222b9e 1317{
e49c7b2f 1318 struct afs_operation *op = call->op;
45222b9e
DH
1319 const __be32 *bp;
1320 char *p;
12bdcf33 1321 u32 size;
45222b9e
DH
1322 int ret;
1323
d001648e 1324 _enter("{%u}", call->unmarshall);
45222b9e
DH
1325
1326 switch (call->unmarshall) {
1327 case 0:
45222b9e 1328 call->unmarshall++;
12bdcf33 1329 afs_extract_to_buf(call, 12 * 4);
df561f66 1330 fallthrough;
45222b9e 1331
29881608 1332 /* extract the returned status record */
45222b9e
DH
1333 case 1:
1334 _debug("extract status");
12bdcf33 1335 ret = afs_extract_data(call, true);
372ee163
DH
1336 if (ret < 0)
1337 return ret;
45222b9e
DH
1338
1339 bp = call->buffer;
e49c7b2f 1340 xdr_decode_AFSFetchVolumeStatus(&bp, &op->volstatus.vs);
45222b9e 1341 call->unmarshall++;
12bdcf33 1342 afs_extract_to_tmp(call);
df561f66 1343 fallthrough;
45222b9e 1344
29881608 1345 /* extract the volume name length */
45222b9e 1346 case 2:
12bdcf33 1347 ret = afs_extract_data(call, true);
372ee163
DH
1348 if (ret < 0)
1349 return ret;
45222b9e
DH
1350
1351 call->count = ntohl(call->tmp);
1352 _debug("volname length: %u", call->count);
1353 if (call->count >= AFSNAMEMAX)
7126ead9 1354 return afs_protocol_error(call, afs_eproto_volname_len);
12bdcf33 1355 size = (call->count + 3) & ~3; /* It's padded */
ffba718e 1356 afs_extract_to_buf(call, size);
45222b9e 1357 call->unmarshall++;
df561f66 1358 fallthrough;
45222b9e 1359
29881608 1360 /* extract the volume name */
45222b9e
DH
1361 case 3:
1362 _debug("extract volname");
12bdcf33
DH
1363 ret = afs_extract_data(call, true);
1364 if (ret < 0)
1365 return ret;
45222b9e 1366
ffba718e 1367 p = call->buffer;
45222b9e
DH
1368 p[call->count] = 0;
1369 _debug("volname '%s'", p);
12bdcf33 1370 afs_extract_to_tmp(call);
45222b9e 1371 call->unmarshall++;
df561f66 1372 fallthrough;
45222b9e 1373
29881608 1374 /* extract the offline message length */
12bdcf33
DH
1375 case 4:
1376 ret = afs_extract_data(call, true);
372ee163
DH
1377 if (ret < 0)
1378 return ret;
45222b9e
DH
1379
1380 call->count = ntohl(call->tmp);
1381 _debug("offline msg length: %u", call->count);
1382 if (call->count >= AFSNAMEMAX)
7126ead9 1383 return afs_protocol_error(call, afs_eproto_offline_msg_len);
12bdcf33 1384 size = (call->count + 3) & ~3; /* It's padded */
ffba718e 1385 afs_extract_to_buf(call, size);
45222b9e 1386 call->unmarshall++;
df561f66 1387 fallthrough;
45222b9e 1388
29881608 1389 /* extract the offline message */
12bdcf33 1390 case 5:
45222b9e 1391 _debug("extract offline");
12bdcf33
DH
1392 ret = afs_extract_data(call, true);
1393 if (ret < 0)
1394 return ret;
45222b9e 1395
ffba718e 1396 p = call->buffer;
45222b9e
DH
1397 p[call->count] = 0;
1398 _debug("offline '%s'", p);
1399
12bdcf33 1400 afs_extract_to_tmp(call);
45222b9e 1401 call->unmarshall++;
df561f66 1402 fallthrough;
45222b9e 1403
29881608 1404 /* extract the message of the day length */
12bdcf33
DH
1405 case 6:
1406 ret = afs_extract_data(call, true);
372ee163
DH
1407 if (ret < 0)
1408 return ret;
45222b9e
DH
1409
1410 call->count = ntohl(call->tmp);
1411 _debug("motd length: %u", call->count);
1412 if (call->count >= AFSNAMEMAX)
7126ead9 1413 return afs_protocol_error(call, afs_eproto_motd_len);
12bdcf33 1414 size = (call->count + 3) & ~3; /* It's padded */
ffba718e 1415 afs_extract_to_buf(call, size);
45222b9e 1416 call->unmarshall++;
df561f66 1417 fallthrough;
45222b9e 1418
29881608 1419 /* extract the message of the day */
12bdcf33 1420 case 7:
45222b9e 1421 _debug("extract motd");
12bdcf33
DH
1422 ret = afs_extract_data(call, false);
1423 if (ret < 0)
1424 return ret;
45222b9e 1425
ffba718e 1426 p = call->buffer;
45222b9e
DH
1427 p[call->count] = 0;
1428 _debug("motd '%s'", p);
1429
45222b9e 1430 call->unmarshall++;
b2db6c35 1431 fallthrough;
45222b9e 1432
12bdcf33 1433 case 8:
45222b9e
DH
1434 break;
1435 }
1436
45222b9e
DH
1437 _leave(" = 0 [done]");
1438 return 0;
1439}
1440
45222b9e
DH
1441/*
1442 * FS.GetVolumeStatus operation type
1443 */
1444static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1445 .name = "FS.GetVolumeStatus",
025db80c 1446 .op = afs_FS_GetVolumeStatus,
45222b9e 1447 .deliver = afs_deliver_fs_get_volume_status,
ffba718e 1448 .destructor = afs_flat_call_destructor,
45222b9e
DH
1449};
1450
1451/*
1452 * fetch the status of a volume
1453 */
e49c7b2f 1454void afs_fs_get_volume_status(struct afs_operation *op)
45222b9e 1455{
e49c7b2f 1456 struct afs_vnode_param *vp = &op->file[0];
45222b9e
DH
1457 struct afs_call *call;
1458 __be32 *bp;
45222b9e
DH
1459
1460 _enter("");
1461
e49c7b2f 1462 call = afs_alloc_flat_call(op->net, &afs_RXFSGetVolumeStatus, 2 * 4,
ffba718e
DH
1463 max(12 * 4, AFSOPAQUEMAX + 1));
1464 if (!call)
e49c7b2f 1465 return afs_op_nomem(op);
45222b9e
DH
1466
1467 /* marshall the parameters */
1468 bp = call->request;
1469 bp[0] = htonl(FSGETVOLUMESTATUS);
e49c7b2f 1470 bp[1] = htonl(vp->fid.vid);
45222b9e 1471
abcbd3bf 1472 call->fid = vp->fid;
e49c7b2f
DH
1473 trace_afs_make_fs_call(call, &vp->fid);
1474 afs_make_op_call(op, call, GFP_NOFS);
45222b9e 1475}
e8d6c554
DH
1476
1477/*
1478 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1479 */
d001648e 1480static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
e8d6c554 1481{
e49c7b2f 1482 struct afs_operation *op = call->op;
e8d6c554 1483 const __be32 *bp;
372ee163 1484 int ret;
e8d6c554 1485
d001648e 1486 _enter("{%u}", call->unmarshall);
e8d6c554 1487
d001648e 1488 ret = afs_transfer_reply(call);
372ee163
DH
1489 if (ret < 0)
1490 return ret;
e8d6c554
DH
1491
1492 /* unmarshall the reply once we've received all of it */
1493 bp = call->buffer;
e49c7b2f 1494 xdr_decode_AFSVolSync(&bp, &op->volsync);
e8d6c554
DH
1495
1496 _leave(" = 0 [done]");
1497 return 0;
1498}
1499
1500/*
1501 * FS.SetLock operation type
1502 */
1503static const struct afs_call_type afs_RXFSSetLock = {
1504 .name = "FS.SetLock",
025db80c 1505 .op = afs_FS_SetLock,
e8d6c554 1506 .deliver = afs_deliver_fs_xxxx_lock,
a690f60a 1507 .done = afs_lock_op_done,
e8d6c554
DH
1508 .destructor = afs_flat_call_destructor,
1509};
1510
1511/*
1512 * FS.ExtendLock operation type
1513 */
1514static const struct afs_call_type afs_RXFSExtendLock = {
1515 .name = "FS.ExtendLock",
025db80c 1516 .op = afs_FS_ExtendLock,
e8d6c554 1517 .deliver = afs_deliver_fs_xxxx_lock,
a690f60a 1518 .done = afs_lock_op_done,
e8d6c554
DH
1519 .destructor = afs_flat_call_destructor,
1520};
1521
1522/*
1523 * FS.ReleaseLock operation type
1524 */
1525static const struct afs_call_type afs_RXFSReleaseLock = {
1526 .name = "FS.ReleaseLock",
025db80c 1527 .op = afs_FS_ReleaseLock,
e8d6c554 1528 .deliver = afs_deliver_fs_xxxx_lock,
e8d6c554
DH
1529 .destructor = afs_flat_call_destructor,
1530};
1531
1532/*
d2ddc776 1533 * Set a lock on a file
e8d6c554 1534 */
e49c7b2f 1535void afs_fs_set_lock(struct afs_operation *op)
e8d6c554 1536{
e49c7b2f 1537 struct afs_vnode_param *vp = &op->file[0];
e8d6c554
DH
1538 struct afs_call *call;
1539 __be32 *bp;
1540
1541 _enter("");
1542
e49c7b2f 1543 call = afs_alloc_flat_call(op->net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
e8d6c554 1544 if (!call)
e49c7b2f 1545 return afs_op_nomem(op);
e8d6c554
DH
1546
1547 /* marshall the parameters */
1548 bp = call->request;
1549 *bp++ = htonl(FSSETLOCK);
e49c7b2f
DH
1550 *bp++ = htonl(vp->fid.vid);
1551 *bp++ = htonl(vp->fid.vnode);
1552 *bp++ = htonl(vp->fid.unique);
1553 *bp++ = htonl(op->lock.type);
1554
abcbd3bf 1555 call->fid = vp->fid;
e49c7b2f
DH
1556 trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);
1557 afs_make_op_call(op, call, GFP_NOFS);
e8d6c554
DH
1558}
1559
1560/*
1561 * extend a lock on a file
1562 */
e49c7b2f 1563void afs_fs_extend_lock(struct afs_operation *op)
e8d6c554 1564{
e49c7b2f 1565 struct afs_vnode_param *vp = &op->file[0];
e8d6c554
DH
1566 struct afs_call *call;
1567 __be32 *bp;
1568
1569 _enter("");
1570
e49c7b2f 1571 call = afs_alloc_flat_call(op->net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
e8d6c554 1572 if (!call)
e49c7b2f 1573 return afs_op_nomem(op);
e8d6c554
DH
1574
1575 /* marshall the parameters */
1576 bp = call->request;
1577 *bp++ = htonl(FSEXTENDLOCK);
e49c7b2f
DH
1578 *bp++ = htonl(vp->fid.vid);
1579 *bp++ = htonl(vp->fid.vnode);
1580 *bp++ = htonl(vp->fid.unique);
1581
abcbd3bf 1582 call->fid = vp->fid;
e49c7b2f
DH
1583 trace_afs_make_fs_call(call, &vp->fid);
1584 afs_make_op_call(op, call, GFP_NOFS);
e8d6c554
DH
1585}
1586
1587/*
1588 * release a lock on a file
1589 */
e49c7b2f 1590void afs_fs_release_lock(struct afs_operation *op)
e8d6c554 1591{
e49c7b2f 1592 struct afs_vnode_param *vp = &op->file[0];
e8d6c554
DH
1593 struct afs_call *call;
1594 __be32 *bp;
1595
1596 _enter("");
1597
e49c7b2f 1598 call = afs_alloc_flat_call(op->net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
e8d6c554 1599 if (!call)
e49c7b2f 1600 return afs_op_nomem(op);
e8d6c554
DH
1601
1602 /* marshall the parameters */
1603 bp = call->request;
1604 *bp++ = htonl(FSRELEASELOCK);
e49c7b2f
DH
1605 *bp++ = htonl(vp->fid.vid);
1606 *bp++ = htonl(vp->fid.vnode);
1607 *bp++ = htonl(vp->fid.unique);
1608
abcbd3bf 1609 call->fid = vp->fid;
e49c7b2f
DH
1610 trace_afs_make_fs_call(call, &vp->fid);
1611 afs_make_op_call(op, call, GFP_NOFS);
c435ee34
DH
1612}
1613
1614/*
1615 * Deliver reply data to an FS.GiveUpAllCallBacks operation.
1616 */
1617static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)
1618{
1619 return afs_transfer_reply(call);
1620}
1621
1622/*
1623 * FS.GiveUpAllCallBacks operation type
1624 */
1625static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
1626 .name = "FS.GiveUpAllCallBacks",
025db80c 1627 .op = afs_FS_GiveUpAllCallBacks,
c435ee34
DH
1628 .deliver = afs_deliver_fs_give_up_all_callbacks,
1629 .destructor = afs_flat_call_destructor,
1630};
1631
1632/*
1633 * Flush all the callbacks we have on a server.
1634 */
98f9fda2
DH
1635int afs_fs_give_up_all_callbacks(struct afs_net *net, struct afs_server *server,
1636 struct afs_address *addr, struct key *key)
c435ee34
DH
1637{
1638 struct afs_call *call;
1639 __be32 *bp;
6f2ff7e8 1640 int ret;
c435ee34
DH
1641
1642 _enter("");
1643
d2ddc776 1644 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);
c435ee34
DH
1645 if (!call)
1646 return -ENOMEM;
1647
e38f299e 1648 call->key = key;
98f9fda2 1649 call->peer = rxrpc_kernel_get_peer(addr->peer);
e38f299e 1650 call->service_id = server->service_id;
c435ee34
DH
1651
1652 /* marshall the parameters */
1653 bp = call->request;
1654 *bp++ = htonl(FSGIVEUPALLCALLBACKS);
1655
4882ba78 1656 call->server = afs_use_server(server, false, afs_server_trace_use_give_up_cb);
98f9fda2
DH
1657 afs_make_call(call, GFP_NOFS);
1658 afs_wait_for_call_to_complete(call);
aa453bec 1659 ret = call->error;
98f9fda2
DH
1660 if (call->responded)
1661 set_bit(AFS_SERVER_FL_RESPONDING, &server->flags);
6f2ff7e8
DH
1662 afs_put_call(call);
1663 return ret;
d2ddc776
DH
1664}
1665
1666/*
1667 * Deliver reply data to an FS.GetCapabilities operation.
1668 */
1669static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1670{
1671 u32 count;
1672 int ret;
1673
fc276122 1674 _enter("{%u,%zu}", call->unmarshall, iov_iter_count(call->iter));
d2ddc776 1675
d2ddc776
DH
1676 switch (call->unmarshall) {
1677 case 0:
12bdcf33 1678 afs_extract_to_tmp(call);
d2ddc776 1679 call->unmarshall++;
df561f66 1680 fallthrough;
d2ddc776 1681
29881608 1682 /* Extract the capabilities word count */
d2ddc776 1683 case 1:
12bdcf33 1684 ret = afs_extract_data(call, true);
d2ddc776
DH
1685 if (ret < 0)
1686 return ret;
1687
1688 count = ntohl(call->tmp);
d2ddc776
DH
1689 call->count = count;
1690 call->count2 = count;
b537a3c2
DH
1691 if (count == 0) {
1692 call->unmarshall = 4;
1693 call->tmp = 0;
1694 break;
1695 }
1696
1697 /* Extract the first word of the capabilities to call->tmp */
1698 afs_extract_to_tmp(call);
d2ddc776 1699 call->unmarshall++;
df561f66 1700 fallthrough;
d2ddc776 1701
d2ddc776 1702 case 2:
12bdcf33 1703 ret = afs_extract_data(call, false);
d2ddc776
DH
1704 if (ret < 0)
1705 return ret;
1706
b537a3c2
DH
1707 afs_extract_discard(call, (count - 1) * sizeof(__be32));
1708 call->unmarshall++;
1709 fallthrough;
1710
1711 /* Extract remaining capabilities words */
1712 case 3:
1713 ret = afs_extract_data(call, false);
1714 if (ret < 0)
1715 return ret;
d2ddc776 1716
d2ddc776
DH
1717 call->unmarshall++;
1718 break;
1719 }
1720
1721 _leave(" = 0 [done]");
1722 return 0;
1723}
1724
98f9fda2
DH
1725static void afs_fs_get_capabilities_destructor(struct afs_call *call)
1726{
f49b594d 1727 afs_put_endpoint_state(call->probe, afs_estate_trace_put_getcaps);
98f9fda2
DH
1728 afs_flat_call_destructor(call);
1729}
1730
d2ddc776
DH
1731/*
1732 * FS.GetCapabilities operation type
1733 */
1734static const struct afs_call_type afs_RXFSGetCapabilities = {
1735 .name = "FS.GetCapabilities",
025db80c 1736 .op = afs_FS_GetCapabilities,
d2ddc776 1737 .deliver = afs_deliver_fs_get_capabilities,
3bf0fb6f 1738 .done = afs_fileserver_probe_result,
eddf51f2 1739 .immediate_cancel = afs_fileserver_probe_result,
98f9fda2 1740 .destructor = afs_fs_get_capabilities_destructor,
d2ddc776
DH
1741};
1742
1743/*
f6cbb368
DH
1744 * Probe a fileserver for the capabilities that it supports. This RPC can
1745 * reply with up to 196 words. The operation is asynchronous and if we managed
1746 * to allocate a call, true is returned the result is delivered through the
1747 * ->done() - otherwise we return false to indicate we didn't even try.
d2ddc776 1748 */
f6cbb368 1749bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server,
f49b594d 1750 struct afs_endpoint_state *estate, unsigned int addr_index,
98f9fda2 1751 struct key *key)
d2ddc776
DH
1752{
1753 struct afs_call *call;
1754 __be32 *bp;
1755
1756 _enter("");
1757
1758 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
1759 if (!call)
f6cbb368 1760 return false;
d2ddc776 1761
e38f299e 1762 call->key = key;
4882ba78 1763 call->server = afs_use_server(server, false, afs_server_trace_use_get_caps);
f49b594d
DH
1764 call->peer = rxrpc_kernel_get_peer(estate->addresses->addrs[addr_index].peer);
1765 call->probe = afs_get_endpoint_state(estate, afs_estate_trace_get_getcaps);
98f9fda2 1766 call->probe_index = addr_index;
e38f299e
DH
1767 call->service_id = server->service_id;
1768 call->upgrade = true;
1769 call->async = true;
94f699c9 1770 call->max_lifespan = AFS_PROBE_MAX_LIFESPAN;
d2ddc776
DH
1771
1772 /* marshall the parameters */
1773 bp = call->request;
1774 *bp++ = htonl(FSGETCAPABILITIES);
1775
025db80c 1776 trace_afs_make_fs_call(call, NULL);
98f9fda2 1777 afs_make_call(call, GFP_NOFS);
f6cbb368
DH
1778 afs_put_call(call);
1779 return true;
e8d6c554 1780}
5cf9dd55 1781
5cf9dd55
DH
1782/*
1783 * Deliver reply data to an FS.InlineBulkStatus call
1784 */
1785static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
1786{
e49c7b2f 1787 struct afs_operation *op = call->op;
87182759 1788 struct afs_status_cb *scb;
5cf9dd55
DH
1789 const __be32 *bp;
1790 u32 tmp;
1791 int ret;
1792
1793 _enter("{%u}", call->unmarshall);
1794
1795 switch (call->unmarshall) {
1796 case 0:
12bdcf33 1797 afs_extract_to_tmp(call);
5cf9dd55 1798 call->unmarshall++;
df561f66 1799 fallthrough;
5cf9dd55
DH
1800
1801 /* Extract the file status count and array in two steps */
1802 case 1:
1803 _debug("extract status count");
12bdcf33 1804 ret = afs_extract_data(call, true);
5cf9dd55
DH
1805 if (ret < 0)
1806 return ret;
1807
1808 tmp = ntohl(call->tmp);
e49c7b2f
DH
1809 _debug("status count: %u/%u", tmp, op->nr_files);
1810 if (tmp != op->nr_files)
7126ead9 1811 return afs_protocol_error(call, afs_eproto_ibulkst_count);
5cf9dd55
DH
1812
1813 call->count = 0;
1814 call->unmarshall++;
1815 more_counts:
12bdcf33 1816 afs_extract_to_buf(call, 21 * sizeof(__be32));
df561f66 1817 fallthrough;
29881608 1818
5cf9dd55
DH
1819 case 2:
1820 _debug("extract status array %u", call->count);
12bdcf33 1821 ret = afs_extract_data(call, true);
5cf9dd55
DH
1822 if (ret < 0)
1823 return ret;
1824
e49c7b2f
DH
1825 switch (call->count) {
1826 case 0:
1827 scb = &op->file[0].scb;
1828 break;
1829 case 1:
1830 scb = &op->file[1].scb;
1831 break;
1832 default:
1833 scb = &op->more_files[call->count - 2].scb;
1834 break;
1835 }
1836
5cf9dd55 1837 bp = call->buffer;
38355eec 1838 xdr_decode_AFSFetchStatus(&bp, call, scb);
e49c7b2f 1839
5cf9dd55 1840 call->count++;
e49c7b2f 1841 if (call->count < op->nr_files)
5cf9dd55
DH
1842 goto more_counts;
1843
1844 call->count = 0;
1845 call->unmarshall++;
12bdcf33 1846 afs_extract_to_tmp(call);
df561f66 1847 fallthrough;
5cf9dd55
DH
1848
1849 /* Extract the callback count and array in two steps */
1850 case 3:
1851 _debug("extract CB count");
12bdcf33 1852 ret = afs_extract_data(call, true);
5cf9dd55
DH
1853 if (ret < 0)
1854 return ret;
1855
1856 tmp = ntohl(call->tmp);
1857 _debug("CB count: %u", tmp);
e49c7b2f 1858 if (tmp != op->nr_files)
7126ead9 1859 return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
5cf9dd55
DH
1860 call->count = 0;
1861 call->unmarshall++;
1862 more_cbs:
12bdcf33 1863 afs_extract_to_buf(call, 3 * sizeof(__be32));
df561f66 1864 fallthrough;
29881608 1865
5cf9dd55
DH
1866 case 4:
1867 _debug("extract CB array");
12bdcf33 1868 ret = afs_extract_data(call, true);
5cf9dd55
DH
1869 if (ret < 0)
1870 return ret;
1871
1872 _debug("unmarshall CB array");
e49c7b2f
DH
1873 switch (call->count) {
1874 case 0:
1875 scb = &op->file[0].scb;
1876 break;
1877 case 1:
1878 scb = &op->file[1].scb;
1879 break;
1880 default:
1881 scb = &op->more_files[call->count - 2].scb;
1882 break;
1883 }
1884
5cf9dd55 1885 bp = call->buffer;
a58823ac 1886 xdr_decode_AFSCallBack(&bp, call, scb);
5cf9dd55 1887 call->count++;
e49c7b2f 1888 if (call->count < op->nr_files)
5cf9dd55
DH
1889 goto more_cbs;
1890
12bdcf33 1891 afs_extract_to_buf(call, 6 * sizeof(__be32));
5cf9dd55 1892 call->unmarshall++;
df561f66 1893 fallthrough;
29881608 1894
5cf9dd55 1895 case 5:
12bdcf33 1896 ret = afs_extract_data(call, false);
5cf9dd55
DH
1897 if (ret < 0)
1898 return ret;
1899
1900 bp = call->buffer;
16069e13
DH
1901 /* Unfortunately, prior to OpenAFS-1.6, volsync here is filled
1902 * with rubbish.
1903 */
1904 xdr_decode_AFSVolSync(&bp, NULL);
5cf9dd55 1905
5cf9dd55 1906 call->unmarshall++;
b2db6c35 1907 fallthrough;
5cf9dd55
DH
1908
1909 case 6:
1910 break;
1911 }
1912
1913 _leave(" = 0 [done]");
1914 return 0;
1915}
1916
e49c7b2f
DH
1917static void afs_done_fs_inline_bulk_status(struct afs_call *call)
1918{
1919 if (call->error == -ECONNABORTED &&
20325960 1920 call->abort_code == RX_INVALID_OPERATION) {
e49c7b2f 1921 set_bit(AFS_SERVER_FL_NO_IBULK, &call->server->flags);
20325960
DH
1922 if (call->op)
1923 set_bit(AFS_VOLUME_MAYBE_NO_IBULK, &call->op->volume->flags);
1924 }
e49c7b2f
DH
1925}
1926
5cf9dd55
DH
1927/*
1928 * FS.InlineBulkStatus operation type
1929 */
1930static const struct afs_call_type afs_RXFSInlineBulkStatus = {
1931 .name = "FS.InlineBulkStatus",
1932 .op = afs_FS_InlineBulkStatus,
1933 .deliver = afs_deliver_fs_inline_bulk_status,
e49c7b2f 1934 .done = afs_done_fs_inline_bulk_status,
5cf9dd55
DH
1935 .destructor = afs_flat_call_destructor,
1936};
1937
1938/*
1939 * Fetch the status information for up to 50 files
1940 */
e49c7b2f 1941void afs_fs_inline_bulk_status(struct afs_operation *op)
5cf9dd55 1942{
e49c7b2f
DH
1943 struct afs_vnode_param *dvp = &op->file[0];
1944 struct afs_vnode_param *vp = &op->file[1];
5cf9dd55
DH
1945 struct afs_call *call;
1946 __be32 *bp;
1947 int i;
1948
20325960 1949 if (test_bit(AFS_SERVER_FL_NO_IBULK, &op->server->flags)) {
2de5599f 1950 afs_op_set_error(op, -ENOTSUPP);
e49c7b2f
DH
1951 return;
1952 }
30062bd1 1953
3b6492df 1954 _enter(",%x,{%llx:%llu},%u",
e49c7b2f 1955 key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);
5cf9dd55 1956
e49c7b2f
DH
1957 call = afs_alloc_flat_call(op->net, &afs_RXFSInlineBulkStatus,
1958 (2 + op->nr_files * 3) * 4,
5cf9dd55 1959 21 * 4);
e49c7b2f
DH
1960 if (!call)
1961 return afs_op_nomem(op);
5cf9dd55
DH
1962
1963 /* marshall the parameters */
1964 bp = call->request;
1965 *bp++ = htonl(FSINLINEBULKSTATUS);
e49c7b2f
DH
1966 *bp++ = htonl(op->nr_files);
1967 *bp++ = htonl(dvp->fid.vid);
1968 *bp++ = htonl(dvp->fid.vnode);
1969 *bp++ = htonl(dvp->fid.unique);
1970 *bp++ = htonl(vp->fid.vid);
1971 *bp++ = htonl(vp->fid.vnode);
1972 *bp++ = htonl(vp->fid.unique);
1973 for (i = 0; i < op->nr_files - 2; i++) {
1974 *bp++ = htonl(op->more_files[i].fid.vid);
1975 *bp++ = htonl(op->more_files[i].fid.vnode);
1976 *bp++ = htonl(op->more_files[i].fid.unique);
5cf9dd55
DH
1977 }
1978
abcbd3bf 1979 call->fid = vp->fid;
e49c7b2f
DH
1980 trace_afs_make_fs_call(call, &vp->fid);
1981 afs_make_op_call(op, call, GFP_NOFS);
5cf9dd55 1982}
260f082b
DH
1983
1984/*
1985 * deliver reply data to an FS.FetchACL
1986 */
1987static int afs_deliver_fs_fetch_acl(struct afs_call *call)
1988{
e49c7b2f
DH
1989 struct afs_operation *op = call->op;
1990 struct afs_vnode_param *vp = &op->file[0];
260f082b
DH
1991 struct afs_acl *acl;
1992 const __be32 *bp;
1993 unsigned int size;
1994 int ret;
1995
1996 _enter("{%u}", call->unmarshall);
1997
1998 switch (call->unmarshall) {
1999 case 0:
2000 afs_extract_to_tmp(call);
2001 call->unmarshall++;
df561f66 2002 fallthrough;
260f082b
DH
2003
2004 /* extract the returned data length */
2005 case 1:
2006 ret = afs_extract_data(call, true);
2007 if (ret < 0)
2008 return ret;
2009
2010 size = call->count2 = ntohl(call->tmp);
2011 size = round_up(size, 4);
2012
2013 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2014 if (!acl)
2015 return -ENOMEM;
e49c7b2f 2016 op->acl = acl;
260f082b
DH
2017 acl->size = call->count2;
2018 afs_extract_begin(call, acl->data, size);
2019 call->unmarshall++;
df561f66 2020 fallthrough;
260f082b
DH
2021
2022 /* extract the returned data */
2023 case 2:
2024 ret = afs_extract_data(call, true);
2025 if (ret < 0)
2026 return ret;
2027
2028 afs_extract_to_buf(call, (21 + 6) * 4);
2029 call->unmarshall++;
df561f66 2030 fallthrough;
260f082b
DH
2031
2032 /* extract the metadata */
2033 case 3:
2034 ret = afs_extract_data(call, false);
2035 if (ret < 0)
2036 return ret;
2037
2038 bp = call->buffer;
e49c7b2f
DH
2039 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);
2040 xdr_decode_AFSVolSync(&bp, &op->volsync);
260f082b
DH
2041
2042 call->unmarshall++;
b2db6c35 2043 fallthrough;
260f082b
DH
2044
2045 case 4:
2046 break;
2047 }
2048
2049 _leave(" = 0 [done]");
2050 return 0;
2051}
2052
260f082b
DH
2053/*
2054 * FS.FetchACL operation type
2055 */
2056static const struct afs_call_type afs_RXFSFetchACL = {
2057 .name = "FS.FetchACL",
2058 .op = afs_FS_FetchACL,
2059 .deliver = afs_deliver_fs_fetch_acl,
260f082b
DH
2060};
2061
2062/*
2063 * Fetch the ACL for a file.
2064 */
e49c7b2f 2065void afs_fs_fetch_acl(struct afs_operation *op)
260f082b 2066{
e49c7b2f 2067 struct afs_vnode_param *vp = &op->file[0];
260f082b 2068 struct afs_call *call;
260f082b
DH
2069 __be32 *bp;
2070
2071 _enter(",%x,{%llx:%llu},,",
e49c7b2f 2072 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
260f082b 2073
e49c7b2f
DH
2074 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchACL, 16, (21 + 6) * 4);
2075 if (!call)
2076 return afs_op_nomem(op);
260f082b
DH
2077
2078 /* marshall the parameters */
2079 bp = call->request;
2080 bp[0] = htonl(FSFETCHACL);
e49c7b2f
DH
2081 bp[1] = htonl(vp->fid.vid);
2082 bp[2] = htonl(vp->fid.vnode);
2083 bp[3] = htonl(vp->fid.unique);
b10494af 2084
abcbd3bf 2085 call->fid = vp->fid;
e49c7b2f
DH
2086 trace_afs_make_fs_call(call, &vp->fid);
2087 afs_make_op_call(op, call, GFP_KERNEL);
ffba718e
DH
2088}
2089
b10494af
JG
2090/*
2091 * FS.StoreACL operation type
2092 */
2093static const struct afs_call_type afs_RXFSStoreACL = {
2094 .name = "FS.StoreACL",
2095 .op = afs_FS_StoreACL,
ffba718e 2096 .deliver = afs_deliver_fs_file_status_and_vol,
b10494af
JG
2097 .destructor = afs_flat_call_destructor,
2098};
2099
2100/*
2101 * Fetch the ACL for a file.
2102 */
e49c7b2f 2103void afs_fs_store_acl(struct afs_operation *op)
b10494af 2104{
e49c7b2f 2105 struct afs_vnode_param *vp = &op->file[0];
b10494af 2106 struct afs_call *call;
e49c7b2f 2107 const struct afs_acl *acl = op->acl;
b10494af
JG
2108 size_t size;
2109 __be32 *bp;
2110
2111 _enter(",%x,{%llx:%llu},,",
e49c7b2f 2112 key_serial(op->key), vp->fid.vid, vp->fid.vnode);
b10494af
JG
2113
2114 size = round_up(acl->size, 4);
e49c7b2f 2115 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreACL,
b10494af 2116 5 * 4 + size, (21 + 6) * 4);
e49c7b2f
DH
2117 if (!call)
2118 return afs_op_nomem(op);
b10494af
JG
2119
2120 /* marshall the parameters */
2121 bp = call->request;
2122 bp[0] = htonl(FSSTOREACL);
e49c7b2f
DH
2123 bp[1] = htonl(vp->fid.vid);
2124 bp[2] = htonl(vp->fid.vnode);
2125 bp[3] = htonl(vp->fid.unique);
b10494af
JG
2126 bp[4] = htonl(acl->size);
2127 memcpy(&bp[5], acl->data, acl->size);
2128 if (acl->size != size)
2129 memset((void *)&bp[5] + acl->size, 0, size - acl->size);
2130
abcbd3bf 2131 call->fid = vp->fid;
e49c7b2f
DH
2132 trace_afs_make_fs_call(call, &vp->fid);
2133 afs_make_op_call(op, call, GFP_KERNEL);
5cf9dd55 2134}