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