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