]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - fs/afs/fsclient.c
drm/i915: Force 2*96 MHz cdclk on glk/cnl when audio power is enabled
[mirror_ubuntu-bionic-kernel.git] / fs / afs / fsclient.c
CommitLineData
08e0e7c8 1/* AFS File Server client stubs
1da177e4 2 *
08e0e7c8 3 * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
1da177e4
LT
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/init.h>
5a0e3ad6 13#include <linux/slab.h>
1da177e4 14#include <linux/sched.h>
08e0e7c8 15#include <linux/circ_buf.h>
1da177e4 16#include "internal.h"
08e0e7c8 17#include "afs_fs.h"
1da177e4 18
025db80c
DH
19static const struct afs_fid afs_zero_fid;
20
6db3ac3c
DH
21/*
22 * We need somewhere to discard into in case the server helpfully returns more
23 * than we asked for in FS.FetchData{,64}.
24 */
25static u8 afs_discard_buffer[64];
26
d2ddc776 27static inline void afs_use_fs_server(struct afs_call *call, struct afs_cb_interest *cbi)
c435ee34 28{
d2ddc776 29 call->cbi = afs_get_cb_interest(cbi);
c435ee34
DH
30}
31
260a9803
DH
32/*
33 * decode an AFSFid block
34 */
35static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)
36{
37 const __be32 *bp = *_bp;
38
39 fid->vid = ntohl(*bp++);
40 fid->vnode = ntohl(*bp++);
41 fid->unique = ntohl(*bp++);
42 *_bp = bp;
43}
44
1da177e4 45/*
08e0e7c8 46 * decode an AFSFetchStatus block
1da177e4 47 */
08e0e7c8 48static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
260a9803 49 struct afs_file_status *status,
31143d5d
DH
50 struct afs_vnode *vnode,
51 afs_dataversion_t *store_version)
1da177e4 52{
31143d5d 53 afs_dataversion_t expected_version;
08e0e7c8
DH
54 const __be32 *bp = *_bp;
55 umode_t mode;
260a9803 56 u64 data_version, size;
c435ee34 57 bool changed = false;
a0a5386a
EB
58 kuid_t owner;
59 kgid_t group;
08e0e7c8 60
d2ddc776
DH
61 if (vnode)
62 write_seqlock(&vnode->cb_lock);
c435ee34 63
08e0e7c8
DH
64#define EXTRACT(DST) \
65 do { \
66 u32 x = ntohl(*bp++); \
c435ee34
DH
67 if (DST != x) \
68 changed |= true; \
08e0e7c8
DH
69 DST = x; \
70 } while (0)
71
260a9803
DH
72 status->if_version = ntohl(*bp++);
73 EXTRACT(status->type);
74 EXTRACT(status->nlink);
75 size = ntohl(*bp++);
08e0e7c8 76 data_version = ntohl(*bp++);
260a9803 77 EXTRACT(status->author);
a0a5386a
EB
78 owner = make_kuid(&init_user_ns, ntohl(*bp++));
79 changed |= !uid_eq(owner, status->owner);
80 status->owner = owner;
260a9803
DH
81 EXTRACT(status->caller_access); /* call ticket dependent */
82 EXTRACT(status->anon_access);
83 EXTRACT(status->mode);
be080a6f
DH
84 bp++; /* parent.vnode */
85 bp++; /* parent.unique */
08e0e7c8 86 bp++; /* seg size */
260a9803
DH
87 status->mtime_client = ntohl(*bp++);
88 status->mtime_server = ntohl(*bp++);
a0a5386a
EB
89 group = make_kgid(&init_user_ns, ntohl(*bp++));
90 changed |= !gid_eq(group, status->group);
91 status->group = group;
08e0e7c8
DH
92 bp++; /* sync counter */
93 data_version |= (u64) ntohl(*bp++) << 32;
e8d6c554 94 EXTRACT(status->lock_count);
260a9803
DH
95 size |= (u64) ntohl(*bp++) << 32;
96 bp++; /* spare 4 */
08e0e7c8
DH
97 *_bp = bp;
98
260a9803
DH
99 if (size != status->size) {
100 status->size = size;
101 changed |= true;
08e0e7c8 102 }
260a9803 103 status->mode &= S_IALLUGO;
08e0e7c8
DH
104
105 _debug("vnode time %lx, %lx",
260a9803
DH
106 status->mtime_client, status->mtime_server);
107
108 if (vnode) {
260a9803
DH
109 if (changed && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
110 _debug("vnode changed");
111 i_size_write(&vnode->vfs_inode, size);
112 vnode->vfs_inode.i_uid = status->owner;
113 vnode->vfs_inode.i_gid = status->group;
d6e43f75 114 vnode->vfs_inode.i_generation = vnode->fid.unique;
bfe86848 115 set_nlink(&vnode->vfs_inode, status->nlink);
260a9803
DH
116
117 mode = vnode->vfs_inode.i_mode;
118 mode &= ~S_IALLUGO;
119 mode |= status->mode;
120 barrier();
121 vnode->vfs_inode.i_mode = mode;
122 }
123
ab94f5d0 124 vnode->vfs_inode.i_ctime.tv_sec = status->mtime_client;
260a9803
DH
125 vnode->vfs_inode.i_mtime = vnode->vfs_inode.i_ctime;
126 vnode->vfs_inode.i_atime = vnode->vfs_inode.i_ctime;
d6e43f75 127 vnode->vfs_inode.i_version = data_version;
260a9803
DH
128 }
129
31143d5d
DH
130 expected_version = status->data_version;
131 if (store_version)
132 expected_version = *store_version;
133
134 if (expected_version != data_version) {
260a9803
DH
135 status->data_version = data_version;
136 if (vnode && !test_bit(AFS_VNODE_UNSET, &vnode->flags)) {
137 _debug("vnode modified %llx on {%x:%u}",
ba3e0e1a
DM
138 (unsigned long long) data_version,
139 vnode->fid.vid, vnode->fid.vnode);
c435ee34 140 set_bit(AFS_VNODE_DIR_MODIFIED, &vnode->flags);
260a9803
DH
141 set_bit(AFS_VNODE_ZAP_DATA, &vnode->flags);
142 }
31143d5d
DH
143 } else if (store_version) {
144 status->data_version = data_version;
1da177e4 145 }
c435ee34 146
d2ddc776
DH
147 if (vnode)
148 write_sequnlock(&vnode->cb_lock);
ec26815a 149}
1da177e4 150
1da177e4 151/*
08e0e7c8 152 * decode an AFSCallBack block
1da177e4 153 */
c435ee34
DH
154static void xdr_decode_AFSCallBack(struct afs_call *call,
155 struct afs_vnode *vnode,
156 const __be32 **_bp)
1da177e4 157{
d2ddc776 158 struct afs_cb_interest *old, *cbi = call->cbi;
08e0e7c8 159 const __be32 *bp = *_bp;
c435ee34
DH
160 u32 cb_expiry;
161
162 write_seqlock(&vnode->cb_lock);
163
d2ddc776 164 if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) {
c435ee34
DH
165 vnode->cb_version = ntohl(*bp++);
166 cb_expiry = ntohl(*bp++);
167 vnode->cb_type = ntohl(*bp++);
168 vnode->cb_expires_at = cb_expiry + ktime_get_real_seconds();
d2ddc776
DH
169 old = vnode->cb_interest;
170 if (old != call->cbi) {
171 vnode->cb_interest = cbi;
172 cbi = old;
173 }
c435ee34
DH
174 set_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
175 } else {
176 bp += 3;
177 }
1da177e4 178
c435ee34 179 write_sequnlock(&vnode->cb_lock);
d2ddc776 180 call->cbi = cbi;
08e0e7c8 181 *_bp = bp;
ec26815a 182}
1da177e4 183
260a9803
DH
184static void xdr_decode_AFSCallBack_raw(const __be32 **_bp,
185 struct afs_callback *cb)
186{
187 const __be32 *bp = *_bp;
188
189 cb->version = ntohl(*bp++);
190 cb->expiry = ntohl(*bp++);
191 cb->type = ntohl(*bp++);
192 *_bp = bp;
193}
194
1da177e4 195/*
08e0e7c8 196 * decode an AFSVolSync block
1da177e4 197 */
08e0e7c8
DH
198static void xdr_decode_AFSVolSync(const __be32 **_bp,
199 struct afs_volsync *volsync)
1da177e4 200{
08e0e7c8 201 const __be32 *bp = *_bp;
1da177e4 202
08e0e7c8
DH
203 volsync->creation = ntohl(*bp++);
204 bp++; /* spare2 */
205 bp++; /* spare3 */
206 bp++; /* spare4 */
207 bp++; /* spare5 */
208 bp++; /* spare6 */
209 *_bp = bp;
210}
1da177e4 211
31143d5d
DH
212/*
213 * encode the requested attributes into an AFSStoreStatus block
214 */
215static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)
216{
217 __be32 *bp = *_bp;
218 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;
219
220 mask = 0;
221 if (attr->ia_valid & ATTR_MTIME) {
222 mask |= AFS_SET_MTIME;
223 mtime = attr->ia_mtime.tv_sec;
224 }
225
226 if (attr->ia_valid & ATTR_UID) {
227 mask |= AFS_SET_OWNER;
a0a5386a 228 owner = from_kuid(&init_user_ns, attr->ia_uid);
31143d5d
DH
229 }
230
231 if (attr->ia_valid & ATTR_GID) {
232 mask |= AFS_SET_GROUP;
a0a5386a 233 group = from_kgid(&init_user_ns, attr->ia_gid);
31143d5d
DH
234 }
235
236 if (attr->ia_valid & ATTR_MODE) {
237 mask |= AFS_SET_MODE;
238 mode = attr->ia_mode & S_IALLUGO;
239 }
240
241 *bp++ = htonl(mask);
242 *bp++ = htonl(mtime);
243 *bp++ = htonl(owner);
244 *bp++ = htonl(group);
245 *bp++ = htonl(mode);
246 *bp++ = 0; /* segment size */
247 *_bp = bp;
248}
249
45222b9e
DH
250/*
251 * decode an AFSFetchVolumeStatus block
252 */
253static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,
254 struct afs_volume_status *vs)
255{
256 const __be32 *bp = *_bp;
257
258 vs->vid = ntohl(*bp++);
259 vs->parent_id = ntohl(*bp++);
260 vs->online = ntohl(*bp++);
261 vs->in_service = ntohl(*bp++);
262 vs->blessed = ntohl(*bp++);
263 vs->needs_salvage = ntohl(*bp++);
264 vs->type = ntohl(*bp++);
265 vs->min_quota = ntohl(*bp++);
266 vs->max_quota = ntohl(*bp++);
267 vs->blocks_in_use = ntohl(*bp++);
268 vs->part_blocks_avail = ntohl(*bp++);
269 vs->part_max_blocks = ntohl(*bp++);
270 *_bp = bp;
271}
272
08e0e7c8
DH
273/*
274 * deliver reply data to an FS.FetchStatus
275 */
d001648e 276static int afs_deliver_fs_fetch_status(struct afs_call *call)
08e0e7c8 277{
97e3043a 278 struct afs_vnode *vnode = call->reply[0];
08e0e7c8 279 const __be32 *bp;
372ee163 280 int ret;
1da177e4 281
d001648e 282 ret = afs_transfer_reply(call);
372ee163
DH
283 if (ret < 0)
284 return ret;
1da177e4 285
c435ee34
DH
286 _enter("{%x:%u}", vnode->fid.vid, vnode->fid.vnode);
287
08e0e7c8
DH
288 /* unmarshall the reply once we've received all of it */
289 bp = call->buffer;
31143d5d 290 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
c435ee34 291 xdr_decode_AFSCallBack(call, vnode, &bp);
97e3043a
DH
292 if (call->reply[1])
293 xdr_decode_AFSVolSync(&bp, call->reply[1]);
1da177e4 294
08e0e7c8
DH
295 _leave(" = 0 [done]");
296 return 0;
ec26815a 297}
08e0e7c8
DH
298
299/*
300 * FS.FetchStatus operation type
301 */
302static const struct afs_call_type afs_RXFSFetchStatus = {
00d3b7a4 303 .name = "FS.FetchStatus",
025db80c 304 .op = afs_FS_FetchStatus,
08e0e7c8 305 .deliver = afs_deliver_fs_fetch_status,
08e0e7c8
DH
306 .destructor = afs_flat_call_destructor,
307};
1da177e4 308
1da177e4
LT
309/*
310 * fetch the status information for a file
311 */
d2ddc776 312int afs_fs_fetch_file_status(struct afs_fs_cursor *fc, struct afs_volsync *volsync)
1da177e4 313{
d2ddc776 314 struct afs_vnode *vnode = fc->vnode;
08e0e7c8 315 struct afs_call *call;
f044c884 316 struct afs_net *net = afs_v2net(vnode);
1da177e4
LT
317 __be32 *bp;
318
416351f2 319 _enter(",%x,{%x:%u},,",
d2ddc776 320 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
1da177e4 321
f044c884 322 call = afs_alloc_flat_call(net, &afs_RXFSFetchStatus, 16, (21 + 3 + 6) * 4);
d2ddc776
DH
323 if (!call) {
324 fc->ac.error = -ENOMEM;
08e0e7c8 325 return -ENOMEM;
d2ddc776 326 }
1da177e4 327
d2ddc776 328 call->key = fc->key;
97e3043a
DH
329 call->reply[0] = vnode;
330 call->reply[1] = volsync;
1da177e4
LT
331
332 /* marshall the parameters */
08e0e7c8 333 bp = call->request;
1da177e4
LT
334 bp[0] = htonl(FSFETCHSTATUS);
335 bp[1] = htonl(vnode->fid.vid);
336 bp[2] = htonl(vnode->fid.vnode);
337 bp[3] = htonl(vnode->fid.unique);
338
d2ddc776
DH
339 call->cb_break = fc->cb_break;
340 afs_use_fs_server(call, fc->cbi);
025db80c 341 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 342 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
ec26815a 343}
1da177e4 344
1da177e4 345/*
08e0e7c8 346 * deliver reply data to an FS.FetchData
1da177e4 347 */
d001648e 348static int afs_deliver_fs_fetch_data(struct afs_call *call)
1da177e4 349{
97e3043a
DH
350 struct afs_vnode *vnode = call->reply[0];
351 struct afs_read *req = call->reply[2];
08e0e7c8 352 const __be32 *bp;
196ee9cd 353 unsigned int size;
08e0e7c8 354 void *buffer;
1da177e4 355 int ret;
1da177e4 356
6a0e3999 357 _enter("{%u,%zu/%u;%llu/%llu}",
196ee9cd
DH
358 call->unmarshall, call->offset, call->count,
359 req->remain, req->actual_len);
08e0e7c8
DH
360
361 switch (call->unmarshall) {
362 case 0:
196ee9cd 363 req->actual_len = 0;
08e0e7c8
DH
364 call->offset = 0;
365 call->unmarshall++;
b9b1f8d5
DH
366 if (call->operation_ID != FSFETCHDATA64) {
367 call->unmarshall++;
368 goto no_msw;
369 }
08e0e7c8 370
b9b1f8d5
DH
371 /* extract the upper part of the returned data length of an
372 * FSFETCHDATA64 op (which should always be 0 using this
373 * client) */
08e0e7c8 374 case 1:
b9b1f8d5 375 _debug("extract data length (MSW)");
d001648e 376 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
377 if (ret < 0)
378 return ret;
b9b1f8d5 379
196ee9cd
DH
380 req->actual_len = ntohl(call->tmp);
381 req->actual_len <<= 32;
b9b1f8d5
DH
382 call->offset = 0;
383 call->unmarshall++;
384
385 no_msw:
386 /* extract the returned data length */
387 case 2:
08e0e7c8 388 _debug("extract data length");
d001648e 389 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
390 if (ret < 0)
391 return ret;
1da177e4 392
196ee9cd
DH
393 req->actual_len |= ntohl(call->tmp);
394 _debug("DATA length: %llu", req->actual_len);
196ee9cd
DH
395
396 req->remain = req->actual_len;
397 call->offset = req->pos & (PAGE_SIZE - 1);
398 req->index = 0;
399 if (req->actual_len == 0)
400 goto no_more_data;
08e0e7c8
DH
401 call->unmarshall++;
402
196ee9cd 403 begin_page:
6db3ac3c 404 ASSERTCMP(req->index, <, req->nr_pages);
196ee9cd
DH
405 if (req->remain > PAGE_SIZE - call->offset)
406 size = PAGE_SIZE - call->offset;
407 else
408 size = req->remain;
409 call->count = call->offset + size;
410 ASSERTCMP(call->count, <=, PAGE_SIZE);
411 req->remain -= size;
412
08e0e7c8 413 /* extract the returned data */
b9b1f8d5 414 case 3:
6a0e3999 415 _debug("extract data %llu/%llu %zu/%u",
196ee9cd
DH
416 req->remain, req->actual_len, call->offset, call->count);
417
418 buffer = kmap(req->pages[req->index]);
419 ret = afs_extract_data(call, buffer, call->count, true);
420 kunmap(req->pages[req->index]);
421 if (ret < 0)
422 return ret;
423 if (call->offset == PAGE_SIZE) {
424 if (req->page_done)
425 req->page_done(call, req);
29f06985 426 req->index++;
196ee9cd 427 if (req->remain > 0) {
196ee9cd 428 call->offset = 0;
e8e581a8
DH
429 if (req->index >= req->nr_pages) {
430 call->unmarshall = 4;
6db3ac3c 431 goto begin_discard;
e8e581a8 432 }
196ee9cd
DH
433 goto begin_page;
434 }
08e0e7c8 435 }
6db3ac3c
DH
436 goto no_more_data;
437
438 /* Discard any excess data the server gave us */
439 begin_discard:
440 case 4:
6a0e3999 441 size = min_t(loff_t, sizeof(afs_discard_buffer), req->remain);
6db3ac3c 442 call->count = size;
6a0e3999 443 _debug("extract discard %llu/%llu %zu/%u",
6db3ac3c
DH
444 req->remain, req->actual_len, call->offset, call->count);
445
446 call->offset = 0;
447 ret = afs_extract_data(call, afs_discard_buffer, call->count, true);
448 req->remain -= call->offset;
449 if (ret < 0)
450 return ret;
451 if (req->remain > 0)
452 goto begin_discard;
1da177e4 453
196ee9cd 454 no_more_data:
08e0e7c8 455 call->offset = 0;
6db3ac3c 456 call->unmarshall = 5;
1da177e4 457
08e0e7c8 458 /* extract the metadata */
6db3ac3c 459 case 5:
d001648e
DH
460 ret = afs_extract_data(call, call->buffer,
461 (21 + 3 + 6) * 4, false);
372ee163
DH
462 if (ret < 0)
463 return ret;
08e0e7c8
DH
464
465 bp = call->buffer;
31143d5d 466 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
c435ee34 467 xdr_decode_AFSCallBack(call, vnode, &bp);
97e3043a
DH
468 if (call->reply[1])
469 xdr_decode_AFSVolSync(&bp, call->reply[1]);
08e0e7c8
DH
470
471 call->offset = 0;
472 call->unmarshall++;
1da177e4 473
6db3ac3c 474 case 6:
08e0e7c8 475 break;
1da177e4
LT
476 }
477
6db3ac3c
DH
478 for (; req->index < req->nr_pages; req->index++) {
479 if (call->count < PAGE_SIZE)
480 zero_user_segment(req->pages[req->index],
481 call->count, PAGE_SIZE);
196ee9cd
DH
482 if (req->page_done)
483 req->page_done(call, req);
6db3ac3c 484 call->count = 0;
416351f2
DH
485 }
486
08e0e7c8
DH
487 _leave(" = 0 [done]");
488 return 0;
ec26815a 489}
1da177e4 490
196ee9cd
DH
491static void afs_fetch_data_destructor(struct afs_call *call)
492{
97e3043a 493 struct afs_read *req = call->reply[2];
196ee9cd
DH
494
495 afs_put_read(req);
496 afs_flat_call_destructor(call);
497}
498
1da177e4 499/*
08e0e7c8 500 * FS.FetchData operation type
1da177e4 501 */
08e0e7c8 502static const struct afs_call_type afs_RXFSFetchData = {
00d3b7a4 503 .name = "FS.FetchData",
025db80c 504 .op = afs_FS_FetchData,
08e0e7c8 505 .deliver = afs_deliver_fs_fetch_data,
196ee9cd 506 .destructor = afs_fetch_data_destructor,
08e0e7c8
DH
507};
508
b9b1f8d5
DH
509static const struct afs_call_type afs_RXFSFetchData64 = {
510 .name = "FS.FetchData64",
025db80c 511 .op = afs_FS_FetchData64,
b9b1f8d5 512 .deliver = afs_deliver_fs_fetch_data,
196ee9cd 513 .destructor = afs_fetch_data_destructor,
b9b1f8d5
DH
514};
515
516/*
517 * fetch data from a very large file
518 */
d2ddc776 519static int afs_fs_fetch_data64(struct afs_fs_cursor *fc, struct afs_read *req)
b9b1f8d5 520{
d2ddc776 521 struct afs_vnode *vnode = fc->vnode;
b9b1f8d5 522 struct afs_call *call;
f044c884 523 struct afs_net *net = afs_v2net(vnode);
b9b1f8d5
DH
524 __be32 *bp;
525
526 _enter("");
527
f044c884 528 call = afs_alloc_flat_call(net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);
b9b1f8d5
DH
529 if (!call)
530 return -ENOMEM;
531
d2ddc776 532 call->key = fc->key;
97e3043a
DH
533 call->reply[0] = vnode;
534 call->reply[1] = NULL; /* volsync */
535 call->reply[2] = req;
b9b1f8d5
DH
536
537 /* marshall the parameters */
538 bp = call->request;
539 bp[0] = htonl(FSFETCHDATA64);
540 bp[1] = htonl(vnode->fid.vid);
541 bp[2] = htonl(vnode->fid.vnode);
542 bp[3] = htonl(vnode->fid.unique);
196ee9cd
DH
543 bp[4] = htonl(upper_32_bits(req->pos));
544 bp[5] = htonl(lower_32_bits(req->pos));
b9b1f8d5 545 bp[6] = 0;
196ee9cd 546 bp[7] = htonl(lower_32_bits(req->len));
b9b1f8d5 547
196ee9cd 548 atomic_inc(&req->usage);
d2ddc776
DH
549 call->cb_break = fc->cb_break;
550 afs_use_fs_server(call, fc->cbi);
025db80c 551 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 552 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
b9b1f8d5
DH
553}
554
08e0e7c8
DH
555/*
556 * fetch data from a file
557 */
d2ddc776 558int afs_fs_fetch_data(struct afs_fs_cursor *fc, struct afs_read *req)
1da177e4 559{
d2ddc776 560 struct afs_vnode *vnode = fc->vnode;
08e0e7c8 561 struct afs_call *call;
f044c884 562 struct afs_net *net = afs_v2net(vnode);
1da177e4
LT
563 __be32 *bp;
564
196ee9cd
DH
565 if (upper_32_bits(req->pos) ||
566 upper_32_bits(req->len) ||
567 upper_32_bits(req->pos + req->len))
d2ddc776 568 return afs_fs_fetch_data64(fc, req);
b9b1f8d5 569
08e0e7c8 570 _enter("");
1da177e4 571
f044c884 572 call = afs_alloc_flat_call(net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);
08e0e7c8
DH
573 if (!call)
574 return -ENOMEM;
1da177e4 575
d2ddc776 576 call->key = fc->key;
97e3043a
DH
577 call->reply[0] = vnode;
578 call->reply[1] = NULL; /* volsync */
579 call->reply[2] = req;
1da177e4
LT
580
581 /* marshall the parameters */
08e0e7c8
DH
582 bp = call->request;
583 bp[0] = htonl(FSFETCHDATA);
584 bp[1] = htonl(vnode->fid.vid);
585 bp[2] = htonl(vnode->fid.vnode);
586 bp[3] = htonl(vnode->fid.unique);
196ee9cd
DH
587 bp[4] = htonl(lower_32_bits(req->pos));
588 bp[5] = htonl(lower_32_bits(req->len));
1da177e4 589
196ee9cd 590 atomic_inc(&req->usage);
d2ddc776
DH
591 call->cb_break = fc->cb_break;
592 afs_use_fs_server(call, fc->cbi);
025db80c 593 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 594 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
ec26815a 595}
260a9803
DH
596
597/*
598 * deliver reply data to an FS.CreateFile or an FS.MakeDir
599 */
d001648e 600static int afs_deliver_fs_create_vnode(struct afs_call *call)
260a9803 601{
97e3043a 602 struct afs_vnode *vnode = call->reply[0];
260a9803 603 const __be32 *bp;
372ee163 604 int ret;
260a9803 605
d001648e 606 _enter("{%u}", call->unmarshall);
260a9803 607
d001648e 608 ret = afs_transfer_reply(call);
372ee163
DH
609 if (ret < 0)
610 return ret;
260a9803
DH
611
612 /* unmarshall the reply once we've received all of it */
613 bp = call->buffer;
97e3043a
DH
614 xdr_decode_AFSFid(&bp, call->reply[1]);
615 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
31143d5d 616 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
97e3043a
DH
617 xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
618 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
619
620 _leave(" = 0 [done]");
621 return 0;
622}
623
624/*
625 * FS.CreateFile and FS.MakeDir operation type
626 */
025db80c
DH
627static const struct afs_call_type afs_RXFSCreateFile = {
628 .name = "FS.CreateFile",
629 .op = afs_FS_CreateFile,
630 .deliver = afs_deliver_fs_create_vnode,
631 .destructor = afs_flat_call_destructor,
632};
633
634static const struct afs_call_type afs_RXFSMakeDir = {
635 .name = "FS.MakeDir",
636 .op = afs_FS_MakeDir,
260a9803 637 .deliver = afs_deliver_fs_create_vnode,
260a9803
DH
638 .destructor = afs_flat_call_destructor,
639};
640
641/*
642 * create a file or make a directory
643 */
8b2a464c 644int afs_fs_create(struct afs_fs_cursor *fc,
260a9803
DH
645 const char *name,
646 umode_t mode,
647 struct afs_fid *newfid,
648 struct afs_file_status *newstatus,
d2ddc776 649 struct afs_callback *newcb)
260a9803 650{
d2ddc776 651 struct afs_vnode *vnode = fc->vnode;
260a9803 652 struct afs_call *call;
f044c884 653 struct afs_net *net = afs_v2net(vnode);
260a9803
DH
654 size_t namesz, reqsz, padsz;
655 __be32 *bp;
656
657 _enter("");
658
659 namesz = strlen(name);
660 padsz = (4 - (namesz & 3)) & 3;
661 reqsz = (5 * 4) + namesz + padsz + (6 * 4);
662
025db80c
DH
663 call = afs_alloc_flat_call(
664 net, S_ISDIR(mode) ? &afs_RXFSMakeDir : &afs_RXFSCreateFile,
665 reqsz, (3 + 21 + 21 + 3 + 6) * 4);
260a9803
DH
666 if (!call)
667 return -ENOMEM;
668
d2ddc776 669 call->key = fc->key;
97e3043a
DH
670 call->reply[0] = vnode;
671 call->reply[1] = newfid;
672 call->reply[2] = newstatus;
673 call->reply[3] = newcb;
260a9803
DH
674
675 /* marshall the parameters */
676 bp = call->request;
677 *bp++ = htonl(S_ISDIR(mode) ? FSMAKEDIR : FSCREATEFILE);
678 *bp++ = htonl(vnode->fid.vid);
679 *bp++ = htonl(vnode->fid.vnode);
680 *bp++ = htonl(vnode->fid.unique);
681 *bp++ = htonl(namesz);
682 memcpy(bp, name, namesz);
683 bp = (void *) bp + namesz;
684 if (padsz > 0) {
685 memset(bp, 0, padsz);
686 bp = (void *) bp + padsz;
687 }
ab94f5d0
MD
688 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
689 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
260a9803
DH
690 *bp++ = 0; /* owner */
691 *bp++ = 0; /* group */
692 *bp++ = htonl(mode & S_IALLUGO); /* unix mode */
693 *bp++ = 0; /* segment size */
694
d2ddc776 695 afs_use_fs_server(call, fc->cbi);
025db80c 696 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 697 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
260a9803
DH
698}
699
700/*
701 * deliver reply data to an FS.RemoveFile or FS.RemoveDir
702 */
d001648e 703static int afs_deliver_fs_remove(struct afs_call *call)
260a9803 704{
97e3043a 705 struct afs_vnode *vnode = call->reply[0];
260a9803 706 const __be32 *bp;
372ee163 707 int ret;
260a9803 708
d001648e 709 _enter("{%u}", call->unmarshall);
260a9803 710
d001648e 711 ret = afs_transfer_reply(call);
372ee163
DH
712 if (ret < 0)
713 return ret;
260a9803
DH
714
715 /* unmarshall the reply once we've received all of it */
716 bp = call->buffer;
31143d5d 717 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
97e3043a 718 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
719
720 _leave(" = 0 [done]");
721 return 0;
722}
723
724/*
725 * FS.RemoveDir/FS.RemoveFile operation type
726 */
025db80c
DH
727static const struct afs_call_type afs_RXFSRemoveFile = {
728 .name = "FS.RemoveFile",
729 .op = afs_FS_RemoveFile,
730 .deliver = afs_deliver_fs_remove,
731 .destructor = afs_flat_call_destructor,
732};
733
734static const struct afs_call_type afs_RXFSRemoveDir = {
735 .name = "FS.RemoveDir",
736 .op = afs_FS_RemoveDir,
260a9803 737 .deliver = afs_deliver_fs_remove,
260a9803
DH
738 .destructor = afs_flat_call_destructor,
739};
740
741/*
742 * remove a file or directory
743 */
d2ddc776 744int afs_fs_remove(struct afs_fs_cursor *fc, const char *name, bool isdir)
260a9803 745{
d2ddc776 746 struct afs_vnode *vnode = fc->vnode;
260a9803 747 struct afs_call *call;
f044c884 748 struct afs_net *net = afs_v2net(vnode);
260a9803
DH
749 size_t namesz, reqsz, padsz;
750 __be32 *bp;
751
752 _enter("");
753
754 namesz = strlen(name);
755 padsz = (4 - (namesz & 3)) & 3;
756 reqsz = (5 * 4) + namesz + padsz;
757
025db80c
DH
758 call = afs_alloc_flat_call(
759 net, isdir ? &afs_RXFSRemoveDir : &afs_RXFSRemoveFile,
760 reqsz, (21 + 6) * 4);
260a9803
DH
761 if (!call)
762 return -ENOMEM;
763
d2ddc776 764 call->key = fc->key;
97e3043a 765 call->reply[0] = vnode;
260a9803
DH
766
767 /* marshall the parameters */
768 bp = call->request;
769 *bp++ = htonl(isdir ? FSREMOVEDIR : FSREMOVEFILE);
770 *bp++ = htonl(vnode->fid.vid);
771 *bp++ = htonl(vnode->fid.vnode);
772 *bp++ = htonl(vnode->fid.unique);
773 *bp++ = htonl(namesz);
774 memcpy(bp, name, namesz);
775 bp = (void *) bp + namesz;
776 if (padsz > 0) {
777 memset(bp, 0, padsz);
778 bp = (void *) bp + padsz;
779 }
780
d2ddc776 781 afs_use_fs_server(call, fc->cbi);
025db80c 782 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 783 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
260a9803
DH
784}
785
786/*
787 * deliver reply data to an FS.Link
788 */
d001648e 789static int afs_deliver_fs_link(struct afs_call *call)
260a9803 790{
97e3043a 791 struct afs_vnode *dvnode = call->reply[0], *vnode = call->reply[1];
260a9803 792 const __be32 *bp;
372ee163 793 int ret;
260a9803 794
d001648e 795 _enter("{%u}", call->unmarshall);
260a9803 796
d001648e 797 ret = afs_transfer_reply(call);
372ee163
DH
798 if (ret < 0)
799 return ret;
260a9803
DH
800
801 /* unmarshall the reply once we've received all of it */
802 bp = call->buffer;
31143d5d
DH
803 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
804 xdr_decode_AFSFetchStatus(&bp, &dvnode->status, dvnode, NULL);
97e3043a 805 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
806
807 _leave(" = 0 [done]");
808 return 0;
809}
810
811/*
812 * FS.Link operation type
813 */
814static const struct afs_call_type afs_RXFSLink = {
815 .name = "FS.Link",
025db80c 816 .op = afs_FS_Link,
260a9803 817 .deliver = afs_deliver_fs_link,
260a9803
DH
818 .destructor = afs_flat_call_destructor,
819};
820
821/*
822 * make a hard link
823 */
d2ddc776
DH
824int afs_fs_link(struct afs_fs_cursor *fc, struct afs_vnode *vnode,
825 const char *name)
260a9803 826{
d2ddc776 827 struct afs_vnode *dvnode = fc->vnode;
260a9803 828 struct afs_call *call;
f044c884 829 struct afs_net *net = afs_v2net(vnode);
260a9803
DH
830 size_t namesz, reqsz, padsz;
831 __be32 *bp;
832
833 _enter("");
834
835 namesz = strlen(name);
836 padsz = (4 - (namesz & 3)) & 3;
837 reqsz = (5 * 4) + namesz + padsz + (3 * 4);
838
f044c884 839 call = afs_alloc_flat_call(net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);
260a9803
DH
840 if (!call)
841 return -ENOMEM;
842
d2ddc776 843 call->key = fc->key;
97e3043a
DH
844 call->reply[0] = dvnode;
845 call->reply[1] = vnode;
260a9803
DH
846
847 /* marshall the parameters */
848 bp = call->request;
849 *bp++ = htonl(FSLINK);
850 *bp++ = htonl(dvnode->fid.vid);
851 *bp++ = htonl(dvnode->fid.vnode);
852 *bp++ = htonl(dvnode->fid.unique);
853 *bp++ = htonl(namesz);
854 memcpy(bp, name, namesz);
855 bp = (void *) bp + namesz;
856 if (padsz > 0) {
857 memset(bp, 0, padsz);
858 bp = (void *) bp + padsz;
859 }
860 *bp++ = htonl(vnode->fid.vid);
861 *bp++ = htonl(vnode->fid.vnode);
862 *bp++ = htonl(vnode->fid.unique);
863
d2ddc776 864 afs_use_fs_server(call, fc->cbi);
025db80c 865 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 866 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
260a9803
DH
867}
868
869/*
870 * deliver reply data to an FS.Symlink
871 */
d001648e 872static int afs_deliver_fs_symlink(struct afs_call *call)
260a9803 873{
97e3043a 874 struct afs_vnode *vnode = call->reply[0];
260a9803 875 const __be32 *bp;
372ee163 876 int ret;
260a9803 877
d001648e 878 _enter("{%u}", call->unmarshall);
260a9803 879
d001648e 880 ret = afs_transfer_reply(call);
372ee163
DH
881 if (ret < 0)
882 return ret;
260a9803
DH
883
884 /* unmarshall the reply once we've received all of it */
885 bp = call->buffer;
97e3043a
DH
886 xdr_decode_AFSFid(&bp, call->reply[1]);
887 xdr_decode_AFSFetchStatus(&bp, call->reply[2], NULL, NULL);
31143d5d 888 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, NULL);
97e3043a 889 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
890
891 _leave(" = 0 [done]");
892 return 0;
893}
894
895/*
896 * FS.Symlink operation type
897 */
898static const struct afs_call_type afs_RXFSSymlink = {
899 .name = "FS.Symlink",
025db80c 900 .op = afs_FS_Symlink,
260a9803 901 .deliver = afs_deliver_fs_symlink,
260a9803
DH
902 .destructor = afs_flat_call_destructor,
903};
904
905/*
906 * create a symbolic link
907 */
8b2a464c 908int afs_fs_symlink(struct afs_fs_cursor *fc,
260a9803
DH
909 const char *name,
910 const char *contents,
911 struct afs_fid *newfid,
d2ddc776 912 struct afs_file_status *newstatus)
260a9803 913{
d2ddc776 914 struct afs_vnode *vnode = fc->vnode;
260a9803 915 struct afs_call *call;
f044c884 916 struct afs_net *net = afs_v2net(vnode);
260a9803
DH
917 size_t namesz, reqsz, padsz, c_namesz, c_padsz;
918 __be32 *bp;
919
920 _enter("");
921
922 namesz = strlen(name);
923 padsz = (4 - (namesz & 3)) & 3;
924
925 c_namesz = strlen(contents);
926 c_padsz = (4 - (c_namesz & 3)) & 3;
927
928 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);
929
f044c884 930 call = afs_alloc_flat_call(net, &afs_RXFSSymlink, reqsz,
260a9803
DH
931 (3 + 21 + 21 + 6) * 4);
932 if (!call)
933 return -ENOMEM;
934
d2ddc776 935 call->key = fc->key;
97e3043a
DH
936 call->reply[0] = vnode;
937 call->reply[1] = newfid;
938 call->reply[2] = newstatus;
260a9803
DH
939
940 /* marshall the parameters */
941 bp = call->request;
942 *bp++ = htonl(FSSYMLINK);
943 *bp++ = htonl(vnode->fid.vid);
944 *bp++ = htonl(vnode->fid.vnode);
945 *bp++ = htonl(vnode->fid.unique);
946 *bp++ = htonl(namesz);
947 memcpy(bp, name, namesz);
948 bp = (void *) bp + namesz;
949 if (padsz > 0) {
950 memset(bp, 0, padsz);
951 bp = (void *) bp + padsz;
952 }
953 *bp++ = htonl(c_namesz);
954 memcpy(bp, contents, c_namesz);
955 bp = (void *) bp + c_namesz;
956 if (c_padsz > 0) {
957 memset(bp, 0, c_padsz);
958 bp = (void *) bp + c_padsz;
959 }
ab94f5d0
MD
960 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);
961 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
260a9803
DH
962 *bp++ = 0; /* owner */
963 *bp++ = 0; /* group */
964 *bp++ = htonl(S_IRWXUGO); /* unix mode */
965 *bp++ = 0; /* segment size */
966
d2ddc776 967 afs_use_fs_server(call, fc->cbi);
025db80c 968 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 969 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
260a9803
DH
970}
971
972/*
973 * deliver reply data to an FS.Rename
974 */
d001648e 975static int afs_deliver_fs_rename(struct afs_call *call)
260a9803 976{
97e3043a 977 struct afs_vnode *orig_dvnode = call->reply[0], *new_dvnode = call->reply[1];
260a9803 978 const __be32 *bp;
372ee163 979 int ret;
260a9803 980
d001648e 981 _enter("{%u}", call->unmarshall);
260a9803 982
d001648e 983 ret = afs_transfer_reply(call);
372ee163
DH
984 if (ret < 0)
985 return ret;
260a9803
DH
986
987 /* unmarshall the reply once we've received all of it */
988 bp = call->buffer;
31143d5d 989 xdr_decode_AFSFetchStatus(&bp, &orig_dvnode->status, orig_dvnode, NULL);
260a9803 990 if (new_dvnode != orig_dvnode)
31143d5d
DH
991 xdr_decode_AFSFetchStatus(&bp, &new_dvnode->status, new_dvnode,
992 NULL);
97e3043a 993 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
260a9803
DH
994
995 _leave(" = 0 [done]");
996 return 0;
997}
998
999/*
1000 * FS.Rename operation type
1001 */
1002static const struct afs_call_type afs_RXFSRename = {
1003 .name = "FS.Rename",
025db80c 1004 .op = afs_FS_Rename,
260a9803 1005 .deliver = afs_deliver_fs_rename,
260a9803
DH
1006 .destructor = afs_flat_call_destructor,
1007};
1008
1009/*
1010 * create a symbolic link
1011 */
8b2a464c 1012int afs_fs_rename(struct afs_fs_cursor *fc,
260a9803
DH
1013 const char *orig_name,
1014 struct afs_vnode *new_dvnode,
d2ddc776 1015 const char *new_name)
260a9803 1016{
d2ddc776 1017 struct afs_vnode *orig_dvnode = fc->vnode;
260a9803 1018 struct afs_call *call;
f044c884 1019 struct afs_net *net = afs_v2net(orig_dvnode);
260a9803
DH
1020 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;
1021 __be32 *bp;
1022
1023 _enter("");
1024
1025 o_namesz = strlen(orig_name);
1026 o_padsz = (4 - (o_namesz & 3)) & 3;
1027
1028 n_namesz = strlen(new_name);
1029 n_padsz = (4 - (n_namesz & 3)) & 3;
1030
1031 reqsz = (4 * 4) +
1032 4 + o_namesz + o_padsz +
1033 (3 * 4) +
1034 4 + n_namesz + n_padsz;
1035
f044c884 1036 call = afs_alloc_flat_call(net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);
260a9803
DH
1037 if (!call)
1038 return -ENOMEM;
1039
d2ddc776 1040 call->key = fc->key;
97e3043a
DH
1041 call->reply[0] = orig_dvnode;
1042 call->reply[1] = new_dvnode;
260a9803
DH
1043
1044 /* marshall the parameters */
1045 bp = call->request;
1046 *bp++ = htonl(FSRENAME);
1047 *bp++ = htonl(orig_dvnode->fid.vid);
1048 *bp++ = htonl(orig_dvnode->fid.vnode);
1049 *bp++ = htonl(orig_dvnode->fid.unique);
1050 *bp++ = htonl(o_namesz);
1051 memcpy(bp, orig_name, o_namesz);
1052 bp = (void *) bp + o_namesz;
1053 if (o_padsz > 0) {
1054 memset(bp, 0, o_padsz);
1055 bp = (void *) bp + o_padsz;
1056 }
1057
1058 *bp++ = htonl(new_dvnode->fid.vid);
1059 *bp++ = htonl(new_dvnode->fid.vnode);
1060 *bp++ = htonl(new_dvnode->fid.unique);
1061 *bp++ = htonl(n_namesz);
1062 memcpy(bp, new_name, n_namesz);
1063 bp = (void *) bp + n_namesz;
1064 if (n_padsz > 0) {
1065 memset(bp, 0, n_padsz);
1066 bp = (void *) bp + n_padsz;
1067 }
1068
d2ddc776 1069 afs_use_fs_server(call, fc->cbi);
025db80c 1070 trace_afs_make_fs_call(call, &orig_dvnode->fid);
d2ddc776 1071 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
260a9803 1072}
31143d5d
DH
1073
1074/*
1075 * deliver reply data to an FS.StoreData
1076 */
d001648e 1077static int afs_deliver_fs_store_data(struct afs_call *call)
31143d5d 1078{
97e3043a 1079 struct afs_vnode *vnode = call->reply[0];
31143d5d 1080 const __be32 *bp;
372ee163 1081 int ret;
31143d5d 1082
d001648e 1083 _enter("");
31143d5d 1084
d001648e 1085 ret = afs_transfer_reply(call);
372ee163
DH
1086 if (ret < 0)
1087 return ret;
31143d5d
DH
1088
1089 /* unmarshall the reply once we've received all of it */
1090 bp = call->buffer;
1091 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode,
1092 &call->store_version);
97e3043a 1093 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
31143d5d
DH
1094
1095 afs_pages_written_back(vnode, call);
1096
1097 _leave(" = 0 [done]");
1098 return 0;
1099}
1100
1101/*
1102 * FS.StoreData operation type
1103 */
1104static const struct afs_call_type afs_RXFSStoreData = {
1105 .name = "FS.StoreData",
025db80c 1106 .op = afs_FS_StoreData,
31143d5d 1107 .deliver = afs_deliver_fs_store_data,
31143d5d
DH
1108 .destructor = afs_flat_call_destructor,
1109};
1110
b9b1f8d5
DH
1111static const struct afs_call_type afs_RXFSStoreData64 = {
1112 .name = "FS.StoreData64",
025db80c 1113 .op = afs_FS_StoreData64,
b9b1f8d5 1114 .deliver = afs_deliver_fs_store_data,
b9b1f8d5
DH
1115 .destructor = afs_flat_call_destructor,
1116};
1117
1118/*
1119 * store a set of pages to a very large file
1120 */
8b2a464c 1121static int afs_fs_store_data64(struct afs_fs_cursor *fc,
4343d008 1122 struct address_space *mapping,
b9b1f8d5
DH
1123 pgoff_t first, pgoff_t last,
1124 unsigned offset, unsigned to,
d2ddc776 1125 loff_t size, loff_t pos, loff_t i_size)
b9b1f8d5 1126{
4343d008 1127 struct afs_vnode *vnode = fc->vnode;
b9b1f8d5 1128 struct afs_call *call;
f044c884 1129 struct afs_net *net = afs_v2net(vnode);
b9b1f8d5
DH
1130 __be32 *bp;
1131
1132 _enter(",%x,{%x:%u},,",
4343d008 1133 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
b9b1f8d5 1134
f044c884 1135 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64,
b9b1f8d5
DH
1136 (4 + 6 + 3 * 2) * 4,
1137 (21 + 6) * 4);
1138 if (!call)
1139 return -ENOMEM;
1140
4343d008
DH
1141 call->key = fc->key;
1142 call->mapping = mapping;
97e3043a 1143 call->reply[0] = vnode;
b9b1f8d5
DH
1144 call->first = first;
1145 call->last = last;
1146 call->first_offset = offset;
1147 call->last_to = to;
1148 call->send_pages = true;
1149 call->store_version = vnode->status.data_version + 1;
1150
1151 /* marshall the parameters */
1152 bp = call->request;
1153 *bp++ = htonl(FSSTOREDATA64);
1154 *bp++ = htonl(vnode->fid.vid);
1155 *bp++ = htonl(vnode->fid.vnode);
1156 *bp++ = htonl(vnode->fid.unique);
1157
ab94f5d0
MD
1158 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1159 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
b9b1f8d5
DH
1160 *bp++ = 0; /* owner */
1161 *bp++ = 0; /* group */
1162 *bp++ = 0; /* unix mode */
1163 *bp++ = 0; /* segment size */
1164
1165 *bp++ = htonl(pos >> 32);
1166 *bp++ = htonl((u32) pos);
1167 *bp++ = htonl(size >> 32);
1168 *bp++ = htonl((u32) size);
1169 *bp++ = htonl(i_size >> 32);
1170 *bp++ = htonl((u32) i_size);
1171
025db80c 1172 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1173 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
b9b1f8d5
DH
1174}
1175
31143d5d
DH
1176/*
1177 * store a set of pages
1178 */
4343d008 1179int afs_fs_store_data(struct afs_fs_cursor *fc, struct address_space *mapping,
31143d5d 1180 pgoff_t first, pgoff_t last,
d2ddc776 1181 unsigned offset, unsigned to)
31143d5d 1182{
4343d008 1183 struct afs_vnode *vnode = fc->vnode;
31143d5d 1184 struct afs_call *call;
f044c884 1185 struct afs_net *net = afs_v2net(vnode);
31143d5d
DH
1186 loff_t size, pos, i_size;
1187 __be32 *bp;
1188
1189 _enter(",%x,{%x:%u},,",
4343d008 1190 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
31143d5d 1191
146a1192 1192 size = (loff_t)to - (loff_t)offset;
31143d5d
DH
1193 if (first != last)
1194 size += (loff_t)(last - first) << PAGE_SHIFT;
1195 pos = (loff_t)first << PAGE_SHIFT;
1196 pos += offset;
1197
1198 i_size = i_size_read(&vnode->vfs_inode);
1199 if (pos + size > i_size)
1200 i_size = size + pos;
1201
1202 _debug("size %llx, at %llx, i_size %llx",
1203 (unsigned long long) size, (unsigned long long) pos,
1204 (unsigned long long) i_size);
1205
b9b1f8d5 1206 if (pos >> 32 || i_size >> 32 || size >> 32 || (pos + size) >> 32)
4343d008 1207 return afs_fs_store_data64(fc, mapping, first, last, offset, to,
d2ddc776 1208 size, pos, i_size);
31143d5d 1209
f044c884 1210 call = afs_alloc_flat_call(net, &afs_RXFSStoreData,
31143d5d
DH
1211 (4 + 6 + 3) * 4,
1212 (21 + 6) * 4);
1213 if (!call)
1214 return -ENOMEM;
1215
4343d008
DH
1216 call->key = fc->key;
1217 call->mapping = mapping;
97e3043a 1218 call->reply[0] = vnode;
31143d5d
DH
1219 call->first = first;
1220 call->last = last;
1221 call->first_offset = offset;
1222 call->last_to = to;
1223 call->send_pages = true;
1224 call->store_version = vnode->status.data_version + 1;
1225
1226 /* marshall the parameters */
1227 bp = call->request;
1228 *bp++ = htonl(FSSTOREDATA);
1229 *bp++ = htonl(vnode->fid.vid);
1230 *bp++ = htonl(vnode->fid.vnode);
1231 *bp++ = htonl(vnode->fid.unique);
1232
ab94f5d0
MD
1233 *bp++ = htonl(AFS_SET_MTIME); /* mask */
1234 *bp++ = htonl(vnode->vfs_inode.i_mtime.tv_sec); /* mtime */
31143d5d
DH
1235 *bp++ = 0; /* owner */
1236 *bp++ = 0; /* group */
1237 *bp++ = 0; /* unix mode */
1238 *bp++ = 0; /* segment size */
1239
1240 *bp++ = htonl(pos);
1241 *bp++ = htonl(size);
1242 *bp++ = htonl(i_size);
1243
d2ddc776 1244 afs_use_fs_server(call, fc->cbi);
025db80c 1245 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1246 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
31143d5d
DH
1247}
1248
1249/*
1250 * deliver reply data to an FS.StoreStatus
1251 */
d001648e 1252static int afs_deliver_fs_store_status(struct afs_call *call)
31143d5d
DH
1253{
1254 afs_dataversion_t *store_version;
97e3043a 1255 struct afs_vnode *vnode = call->reply[0];
31143d5d 1256 const __be32 *bp;
372ee163 1257 int ret;
31143d5d 1258
d001648e 1259 _enter("");
31143d5d 1260
d001648e 1261 ret = afs_transfer_reply(call);
372ee163
DH
1262 if (ret < 0)
1263 return ret;
31143d5d
DH
1264
1265 /* unmarshall the reply once we've received all of it */
1266 store_version = NULL;
1267 if (call->operation_ID == FSSTOREDATA)
1268 store_version = &call->store_version;
1269
1270 bp = call->buffer;
1271 xdr_decode_AFSFetchStatus(&bp, &vnode->status, vnode, store_version);
97e3043a 1272 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
31143d5d
DH
1273
1274 _leave(" = 0 [done]");
1275 return 0;
1276}
1277
1278/*
1279 * FS.StoreStatus operation type
1280 */
1281static const struct afs_call_type afs_RXFSStoreStatus = {
1282 .name = "FS.StoreStatus",
025db80c 1283 .op = afs_FS_StoreStatus,
31143d5d 1284 .deliver = afs_deliver_fs_store_status,
31143d5d
DH
1285 .destructor = afs_flat_call_destructor,
1286};
1287
1288static const struct afs_call_type afs_RXFSStoreData_as_Status = {
1289 .name = "FS.StoreData",
025db80c 1290 .op = afs_FS_StoreData,
31143d5d 1291 .deliver = afs_deliver_fs_store_status,
31143d5d
DH
1292 .destructor = afs_flat_call_destructor,
1293};
1294
b9b1f8d5
DH
1295static const struct afs_call_type afs_RXFSStoreData64_as_Status = {
1296 .name = "FS.StoreData64",
025db80c 1297 .op = afs_FS_StoreData64,
b9b1f8d5 1298 .deliver = afs_deliver_fs_store_status,
b9b1f8d5
DH
1299 .destructor = afs_flat_call_destructor,
1300};
1301
1302/*
1303 * set the attributes on a very large file, using FS.StoreData rather than
1304 * FS.StoreStatus so as to alter the file size also
1305 */
d2ddc776 1306static int afs_fs_setattr_size64(struct afs_fs_cursor *fc, struct iattr *attr)
b9b1f8d5 1307{
d2ddc776 1308 struct afs_vnode *vnode = fc->vnode;
b9b1f8d5 1309 struct afs_call *call;
f044c884 1310 struct afs_net *net = afs_v2net(vnode);
b9b1f8d5
DH
1311 __be32 *bp;
1312
1313 _enter(",%x,{%x:%u},,",
d2ddc776 1314 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
b9b1f8d5
DH
1315
1316 ASSERT(attr->ia_valid & ATTR_SIZE);
1317
f044c884 1318 call = afs_alloc_flat_call(net, &afs_RXFSStoreData64_as_Status,
b9b1f8d5
DH
1319 (4 + 6 + 3 * 2) * 4,
1320 (21 + 6) * 4);
1321 if (!call)
1322 return -ENOMEM;
1323
d2ddc776 1324 call->key = fc->key;
97e3043a 1325 call->reply[0] = vnode;
b9b1f8d5 1326 call->store_version = vnode->status.data_version + 1;
b9b1f8d5
DH
1327
1328 /* marshall the parameters */
1329 bp = call->request;
1330 *bp++ = htonl(FSSTOREDATA64);
1331 *bp++ = htonl(vnode->fid.vid);
1332 *bp++ = htonl(vnode->fid.vnode);
1333 *bp++ = htonl(vnode->fid.unique);
1334
1335 xdr_encode_AFS_StoreStatus(&bp, attr);
1336
1337 *bp++ = 0; /* position of start of write */
1338 *bp++ = 0;
1339 *bp++ = 0; /* size of write */
1340 *bp++ = 0;
1341 *bp++ = htonl(attr->ia_size >> 32); /* new file length */
1342 *bp++ = htonl((u32) attr->ia_size);
1343
d2ddc776 1344 afs_use_fs_server(call, fc->cbi);
025db80c 1345 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1346 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
b9b1f8d5
DH
1347}
1348
31143d5d
DH
1349/*
1350 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus
1351 * so as to alter the file size also
1352 */
d2ddc776 1353static int afs_fs_setattr_size(struct afs_fs_cursor *fc, struct iattr *attr)
31143d5d 1354{
d2ddc776 1355 struct afs_vnode *vnode = fc->vnode;
31143d5d 1356 struct afs_call *call;
f044c884 1357 struct afs_net *net = afs_v2net(vnode);
31143d5d
DH
1358 __be32 *bp;
1359
1360 _enter(",%x,{%x:%u},,",
d2ddc776 1361 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
31143d5d
DH
1362
1363 ASSERT(attr->ia_valid & ATTR_SIZE);
b9b1f8d5 1364 if (attr->ia_size >> 32)
d2ddc776 1365 return afs_fs_setattr_size64(fc, attr);
31143d5d 1366
f044c884 1367 call = afs_alloc_flat_call(net, &afs_RXFSStoreData_as_Status,
31143d5d
DH
1368 (4 + 6 + 3) * 4,
1369 (21 + 6) * 4);
1370 if (!call)
1371 return -ENOMEM;
1372
d2ddc776 1373 call->key = fc->key;
97e3043a 1374 call->reply[0] = vnode;
31143d5d 1375 call->store_version = vnode->status.data_version + 1;
31143d5d
DH
1376
1377 /* marshall the parameters */
1378 bp = call->request;
1379 *bp++ = htonl(FSSTOREDATA);
1380 *bp++ = htonl(vnode->fid.vid);
1381 *bp++ = htonl(vnode->fid.vnode);
1382 *bp++ = htonl(vnode->fid.unique);
1383
1384 xdr_encode_AFS_StoreStatus(&bp, attr);
1385
1386 *bp++ = 0; /* position of start of write */
1387 *bp++ = 0; /* size of write */
1388 *bp++ = htonl(attr->ia_size); /* new file length */
1389
d2ddc776 1390 afs_use_fs_server(call, fc->cbi);
025db80c 1391 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1392 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
31143d5d
DH
1393}
1394
1395/*
1396 * set the attributes on a file, using FS.StoreData if there's a change in file
1397 * size, and FS.StoreStatus otherwise
1398 */
d2ddc776 1399int afs_fs_setattr(struct afs_fs_cursor *fc, struct iattr *attr)
31143d5d 1400{
d2ddc776 1401 struct afs_vnode *vnode = fc->vnode;
31143d5d 1402 struct afs_call *call;
f044c884 1403 struct afs_net *net = afs_v2net(vnode);
31143d5d
DH
1404 __be32 *bp;
1405
1406 if (attr->ia_valid & ATTR_SIZE)
d2ddc776 1407 return afs_fs_setattr_size(fc, attr);
31143d5d
DH
1408
1409 _enter(",%x,{%x:%u},,",
d2ddc776 1410 key_serial(fc->key), vnode->fid.vid, vnode->fid.vnode);
31143d5d 1411
f044c884 1412 call = afs_alloc_flat_call(net, &afs_RXFSStoreStatus,
31143d5d
DH
1413 (4 + 6) * 4,
1414 (21 + 6) * 4);
1415 if (!call)
1416 return -ENOMEM;
1417
d2ddc776 1418 call->key = fc->key;
97e3043a 1419 call->reply[0] = vnode;
31143d5d
DH
1420
1421 /* marshall the parameters */
1422 bp = call->request;
1423 *bp++ = htonl(FSSTORESTATUS);
1424 *bp++ = htonl(vnode->fid.vid);
1425 *bp++ = htonl(vnode->fid.vnode);
1426 *bp++ = htonl(vnode->fid.unique);
1427
1428 xdr_encode_AFS_StoreStatus(&bp, attr);
1429
d2ddc776 1430 afs_use_fs_server(call, fc->cbi);
025db80c 1431 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1432 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
31143d5d 1433}
45222b9e
DH
1434
1435/*
1436 * deliver reply data to an FS.GetVolumeStatus
1437 */
d001648e 1438static int afs_deliver_fs_get_volume_status(struct afs_call *call)
45222b9e
DH
1439{
1440 const __be32 *bp;
1441 char *p;
1442 int ret;
1443
d001648e 1444 _enter("{%u}", call->unmarshall);
45222b9e
DH
1445
1446 switch (call->unmarshall) {
1447 case 0:
1448 call->offset = 0;
1449 call->unmarshall++;
1450
1451 /* extract the returned status record */
1452 case 1:
1453 _debug("extract status");
d001648e
DH
1454 ret = afs_extract_data(call, call->buffer,
1455 12 * 4, true);
372ee163
DH
1456 if (ret < 0)
1457 return ret;
45222b9e
DH
1458
1459 bp = call->buffer;
97e3043a 1460 xdr_decode_AFSFetchVolumeStatus(&bp, call->reply[1]);
45222b9e
DH
1461 call->offset = 0;
1462 call->unmarshall++;
1463
1464 /* extract the volume name length */
1465 case 2:
d001648e 1466 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
1467 if (ret < 0)
1468 return ret;
45222b9e
DH
1469
1470 call->count = ntohl(call->tmp);
1471 _debug("volname length: %u", call->count);
1472 if (call->count >= AFSNAMEMAX)
1473 return -EBADMSG;
1474 call->offset = 0;
1475 call->unmarshall++;
1476
1477 /* extract the volume name */
1478 case 3:
1479 _debug("extract volname");
1480 if (call->count > 0) {
97e3043a 1481 ret = afs_extract_data(call, call->reply[2],
d001648e 1482 call->count, true);
372ee163
DH
1483 if (ret < 0)
1484 return ret;
45222b9e
DH
1485 }
1486
97e3043a 1487 p = call->reply[2];
45222b9e
DH
1488 p[call->count] = 0;
1489 _debug("volname '%s'", p);
1490
1491 call->offset = 0;
1492 call->unmarshall++;
1493
1494 /* extract the volume name padding */
1495 if ((call->count & 3) == 0) {
1496 call->unmarshall++;
1497 goto no_volname_padding;
1498 }
1499 call->count = 4 - (call->count & 3);
1500
1501 case 4:
d001648e
DH
1502 ret = afs_extract_data(call, call->buffer,
1503 call->count, true);
372ee163
DH
1504 if (ret < 0)
1505 return ret;
45222b9e
DH
1506
1507 call->offset = 0;
1508 call->unmarshall++;
1509 no_volname_padding:
1510
1511 /* extract the offline message length */
1512 case 5:
d001648e 1513 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
1514 if (ret < 0)
1515 return ret;
45222b9e
DH
1516
1517 call->count = ntohl(call->tmp);
1518 _debug("offline msg length: %u", call->count);
1519 if (call->count >= AFSNAMEMAX)
1520 return -EBADMSG;
1521 call->offset = 0;
1522 call->unmarshall++;
1523
1524 /* extract the offline message */
1525 case 6:
1526 _debug("extract offline");
1527 if (call->count > 0) {
97e3043a 1528 ret = afs_extract_data(call, call->reply[2],
d001648e 1529 call->count, true);
372ee163
DH
1530 if (ret < 0)
1531 return ret;
45222b9e
DH
1532 }
1533
97e3043a 1534 p = call->reply[2];
45222b9e
DH
1535 p[call->count] = 0;
1536 _debug("offline '%s'", p);
1537
1538 call->offset = 0;
1539 call->unmarshall++;
1540
1541 /* extract the offline message padding */
1542 if ((call->count & 3) == 0) {
1543 call->unmarshall++;
1544 goto no_offline_padding;
1545 }
1546 call->count = 4 - (call->count & 3);
1547
1548 case 7:
d001648e
DH
1549 ret = afs_extract_data(call, call->buffer,
1550 call->count, true);
372ee163
DH
1551 if (ret < 0)
1552 return ret;
45222b9e
DH
1553
1554 call->offset = 0;
1555 call->unmarshall++;
1556 no_offline_padding:
1557
1558 /* extract the message of the day length */
1559 case 8:
d001648e 1560 ret = afs_extract_data(call, &call->tmp, 4, true);
372ee163
DH
1561 if (ret < 0)
1562 return ret;
45222b9e
DH
1563
1564 call->count = ntohl(call->tmp);
1565 _debug("motd length: %u", call->count);
1566 if (call->count >= AFSNAMEMAX)
1567 return -EBADMSG;
1568 call->offset = 0;
1569 call->unmarshall++;
1570
1571 /* extract the message of the day */
1572 case 9:
1573 _debug("extract motd");
1574 if (call->count > 0) {
97e3043a 1575 ret = afs_extract_data(call, call->reply[2],
d001648e 1576 call->count, true);
372ee163
DH
1577 if (ret < 0)
1578 return ret;
45222b9e
DH
1579 }
1580
97e3043a 1581 p = call->reply[2];
45222b9e
DH
1582 p[call->count] = 0;
1583 _debug("motd '%s'", p);
1584
1585 call->offset = 0;
1586 call->unmarshall++;
1587
1588 /* extract the message of the day padding */
d001648e 1589 call->count = (4 - (call->count & 3)) & 3;
45222b9e
DH
1590
1591 case 10:
d001648e
DH
1592 ret = afs_extract_data(call, call->buffer,
1593 call->count, false);
372ee163
DH
1594 if (ret < 0)
1595 return ret;
45222b9e
DH
1596
1597 call->offset = 0;
1598 call->unmarshall++;
45222b9e 1599 case 11:
45222b9e
DH
1600 break;
1601 }
1602
45222b9e
DH
1603 _leave(" = 0 [done]");
1604 return 0;
1605}
1606
1607/*
1608 * destroy an FS.GetVolumeStatus call
1609 */
1610static void afs_get_volume_status_call_destructor(struct afs_call *call)
1611{
97e3043a
DH
1612 kfree(call->reply[2]);
1613 call->reply[2] = NULL;
45222b9e
DH
1614 afs_flat_call_destructor(call);
1615}
1616
1617/*
1618 * FS.GetVolumeStatus operation type
1619 */
1620static const struct afs_call_type afs_RXFSGetVolumeStatus = {
1621 .name = "FS.GetVolumeStatus",
025db80c 1622 .op = afs_FS_GetVolumeStatus,
45222b9e 1623 .deliver = afs_deliver_fs_get_volume_status,
45222b9e
DH
1624 .destructor = afs_get_volume_status_call_destructor,
1625};
1626
1627/*
1628 * fetch the status of a volume
1629 */
8b2a464c 1630int afs_fs_get_volume_status(struct afs_fs_cursor *fc,
d2ddc776 1631 struct afs_volume_status *vs)
45222b9e 1632{
d2ddc776 1633 struct afs_vnode *vnode = fc->vnode;
45222b9e 1634 struct afs_call *call;
f044c884 1635 struct afs_net *net = afs_v2net(vnode);
45222b9e
DH
1636 __be32 *bp;
1637 void *tmpbuf;
1638
1639 _enter("");
1640
1641 tmpbuf = kmalloc(AFSOPAQUEMAX, GFP_KERNEL);
1642 if (!tmpbuf)
1643 return -ENOMEM;
1644
f044c884 1645 call = afs_alloc_flat_call(net, &afs_RXFSGetVolumeStatus, 2 * 4, 12 * 4);
45222b9e
DH
1646 if (!call) {
1647 kfree(tmpbuf);
1648 return -ENOMEM;
1649 }
1650
d2ddc776 1651 call->key = fc->key;
97e3043a
DH
1652 call->reply[0] = vnode;
1653 call->reply[1] = vs;
1654 call->reply[2] = tmpbuf;
45222b9e
DH
1655
1656 /* marshall the parameters */
1657 bp = call->request;
1658 bp[0] = htonl(FSGETVOLUMESTATUS);
1659 bp[1] = htonl(vnode->fid.vid);
1660
d2ddc776 1661 afs_use_fs_server(call, fc->cbi);
025db80c 1662 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1663 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
45222b9e 1664}
e8d6c554
DH
1665
1666/*
1667 * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock
1668 */
d001648e 1669static int afs_deliver_fs_xxxx_lock(struct afs_call *call)
e8d6c554
DH
1670{
1671 const __be32 *bp;
372ee163 1672 int ret;
e8d6c554 1673
d001648e 1674 _enter("{%u}", call->unmarshall);
e8d6c554 1675
d001648e 1676 ret = afs_transfer_reply(call);
372ee163
DH
1677 if (ret < 0)
1678 return ret;
e8d6c554
DH
1679
1680 /* unmarshall the reply once we've received all of it */
1681 bp = call->buffer;
97e3043a 1682 /* xdr_decode_AFSVolSync(&bp, call->reply[X]); */
e8d6c554
DH
1683
1684 _leave(" = 0 [done]");
1685 return 0;
1686}
1687
1688/*
1689 * FS.SetLock operation type
1690 */
1691static const struct afs_call_type afs_RXFSSetLock = {
1692 .name = "FS.SetLock",
025db80c 1693 .op = afs_FS_SetLock,
e8d6c554 1694 .deliver = afs_deliver_fs_xxxx_lock,
e8d6c554
DH
1695 .destructor = afs_flat_call_destructor,
1696};
1697
1698/*
1699 * FS.ExtendLock operation type
1700 */
1701static const struct afs_call_type afs_RXFSExtendLock = {
1702 .name = "FS.ExtendLock",
025db80c 1703 .op = afs_FS_ExtendLock,
e8d6c554 1704 .deliver = afs_deliver_fs_xxxx_lock,
e8d6c554
DH
1705 .destructor = afs_flat_call_destructor,
1706};
1707
1708/*
1709 * FS.ReleaseLock operation type
1710 */
1711static const struct afs_call_type afs_RXFSReleaseLock = {
1712 .name = "FS.ReleaseLock",
025db80c 1713 .op = afs_FS_ReleaseLock,
e8d6c554 1714 .deliver = afs_deliver_fs_xxxx_lock,
e8d6c554
DH
1715 .destructor = afs_flat_call_destructor,
1716};
1717
1718/*
d2ddc776 1719 * Set a lock on a file
e8d6c554 1720 */
d2ddc776 1721int afs_fs_set_lock(struct afs_fs_cursor *fc, afs_lock_type_t type)
e8d6c554 1722{
d2ddc776 1723 struct afs_vnode *vnode = fc->vnode;
e8d6c554 1724 struct afs_call *call;
f044c884 1725 struct afs_net *net = afs_v2net(vnode);
e8d6c554
DH
1726 __be32 *bp;
1727
1728 _enter("");
1729
f044c884 1730 call = afs_alloc_flat_call(net, &afs_RXFSSetLock, 5 * 4, 6 * 4);
e8d6c554
DH
1731 if (!call)
1732 return -ENOMEM;
1733
d2ddc776 1734 call->key = fc->key;
97e3043a 1735 call->reply[0] = vnode;
e8d6c554
DH
1736
1737 /* marshall the parameters */
1738 bp = call->request;
1739 *bp++ = htonl(FSSETLOCK);
1740 *bp++ = htonl(vnode->fid.vid);
1741 *bp++ = htonl(vnode->fid.vnode);
1742 *bp++ = htonl(vnode->fid.unique);
1743 *bp++ = htonl(type);
1744
d2ddc776 1745 afs_use_fs_server(call, fc->cbi);
025db80c 1746 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1747 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
e8d6c554
DH
1748}
1749
1750/*
1751 * extend a lock on a file
1752 */
d2ddc776 1753int afs_fs_extend_lock(struct afs_fs_cursor *fc)
e8d6c554 1754{
d2ddc776 1755 struct afs_vnode *vnode = fc->vnode;
e8d6c554 1756 struct afs_call *call;
f044c884 1757 struct afs_net *net = afs_v2net(vnode);
e8d6c554
DH
1758 __be32 *bp;
1759
1760 _enter("");
1761
f044c884 1762 call = afs_alloc_flat_call(net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);
e8d6c554
DH
1763 if (!call)
1764 return -ENOMEM;
1765
d2ddc776 1766 call->key = fc->key;
97e3043a 1767 call->reply[0] = vnode;
e8d6c554
DH
1768
1769 /* marshall the parameters */
1770 bp = call->request;
1771 *bp++ = htonl(FSEXTENDLOCK);
1772 *bp++ = htonl(vnode->fid.vid);
1773 *bp++ = htonl(vnode->fid.vnode);
1774 *bp++ = htonl(vnode->fid.unique);
1775
d2ddc776 1776 afs_use_fs_server(call, fc->cbi);
025db80c 1777 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1778 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
e8d6c554
DH
1779}
1780
1781/*
1782 * release a lock on a file
1783 */
d2ddc776 1784int afs_fs_release_lock(struct afs_fs_cursor *fc)
e8d6c554 1785{
d2ddc776 1786 struct afs_vnode *vnode = fc->vnode;
e8d6c554 1787 struct afs_call *call;
f044c884 1788 struct afs_net *net = afs_v2net(vnode);
e8d6c554
DH
1789 __be32 *bp;
1790
1791 _enter("");
1792
f044c884 1793 call = afs_alloc_flat_call(net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);
e8d6c554
DH
1794 if (!call)
1795 return -ENOMEM;
1796
d2ddc776 1797 call->key = fc->key;
97e3043a 1798 call->reply[0] = vnode;
e8d6c554
DH
1799
1800 /* marshall the parameters */
1801 bp = call->request;
1802 *bp++ = htonl(FSRELEASELOCK);
1803 *bp++ = htonl(vnode->fid.vid);
1804 *bp++ = htonl(vnode->fid.vnode);
1805 *bp++ = htonl(vnode->fid.unique);
1806
d2ddc776 1807 afs_use_fs_server(call, fc->cbi);
025db80c 1808 trace_afs_make_fs_call(call, &vnode->fid);
d2ddc776 1809 return afs_make_call(&fc->ac, call, GFP_NOFS, false);
c435ee34
DH
1810}
1811
1812/*
1813 * Deliver reply data to an FS.GiveUpAllCallBacks operation.
1814 */
1815static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)
1816{
1817 return afs_transfer_reply(call);
1818}
1819
1820/*
1821 * FS.GiveUpAllCallBacks operation type
1822 */
1823static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {
1824 .name = "FS.GiveUpAllCallBacks",
025db80c 1825 .op = afs_FS_GiveUpAllCallBacks,
c435ee34
DH
1826 .deliver = afs_deliver_fs_give_up_all_callbacks,
1827 .destructor = afs_flat_call_destructor,
1828};
1829
1830/*
1831 * Flush all the callbacks we have on a server.
1832 */
d2ddc776
DH
1833int afs_fs_give_up_all_callbacks(struct afs_net *net,
1834 struct afs_server *server,
8b2a464c 1835 struct afs_addr_cursor *ac,
d2ddc776 1836 struct key *key)
c435ee34
DH
1837{
1838 struct afs_call *call;
1839 __be32 *bp;
1840
1841 _enter("");
1842
d2ddc776 1843 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);
c435ee34
DH
1844 if (!call)
1845 return -ENOMEM;
1846
1847 call->key = key;
1848
1849 /* marshall the parameters */
1850 bp = call->request;
1851 *bp++ = htonl(FSGIVEUPALLCALLBACKS);
1852
1853 /* Can't take a ref on server */
d2ddc776
DH
1854 return afs_make_call(ac, call, GFP_NOFS, false);
1855}
1856
1857/*
1858 * Deliver reply data to an FS.GetCapabilities operation.
1859 */
1860static int afs_deliver_fs_get_capabilities(struct afs_call *call)
1861{
1862 u32 count;
1863 int ret;
1864
1865 _enter("{%u,%zu/%u}", call->unmarshall, call->offset, call->count);
1866
1867again:
1868 switch (call->unmarshall) {
1869 case 0:
1870 call->offset = 0;
1871 call->unmarshall++;
1872
1873 /* Extract the capabilities word count */
1874 case 1:
1875 ret = afs_extract_data(call, &call->tmp,
1876 1 * sizeof(__be32),
1877 true);
1878 if (ret < 0)
1879 return ret;
1880
1881 count = ntohl(call->tmp);
1882
1883 call->count = count;
1884 call->count2 = count;
1885 call->offset = 0;
1886 call->unmarshall++;
1887
1888 /* Extract capabilities words */
1889 case 2:
1890 count = min(call->count, 16U);
1891 ret = afs_extract_data(call, call->buffer,
1892 count * sizeof(__be32),
1893 call->count > 16);
1894 if (ret < 0)
1895 return ret;
1896
1897 /* TODO: Examine capabilities */
1898
1899 call->count -= count;
1900 if (call->count > 0)
1901 goto again;
1902 call->offset = 0;
1903 call->unmarshall++;
1904 break;
1905 }
1906
1907 _leave(" = 0 [done]");
1908 return 0;
1909}
1910
1911/*
1912 * FS.GetCapabilities operation type
1913 */
1914static const struct afs_call_type afs_RXFSGetCapabilities = {
1915 .name = "FS.GetCapabilities",
025db80c 1916 .op = afs_FS_GetCapabilities,
d2ddc776
DH
1917 .deliver = afs_deliver_fs_get_capabilities,
1918 .destructor = afs_flat_call_destructor,
1919};
1920
1921/*
1922 * Probe a fileserver for the capabilities that it supports. This can
1923 * return up to 196 words.
1924 */
1925int afs_fs_get_capabilities(struct afs_net *net,
1926 struct afs_server *server,
1927 struct afs_addr_cursor *ac,
1928 struct key *key)
1929{
1930 struct afs_call *call;
1931 __be32 *bp;
1932
1933 _enter("");
1934
1935 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);
1936 if (!call)
1937 return -ENOMEM;
1938
1939 call->key = key;
1940
1941 /* marshall the parameters */
1942 bp = call->request;
1943 *bp++ = htonl(FSGETCAPABILITIES);
1944
1945 /* Can't take a ref on server */
025db80c 1946 trace_afs_make_fs_call(call, NULL);
d2ddc776 1947 return afs_make_call(ac, call, GFP_NOFS, false);
e8d6c554 1948}