Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/fs/afs/yfsclient.c
29265 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* YFS File Server client stubs
3
*
4
* Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
5
* Written by David Howells ([email protected])
6
*/
7
8
#include <linux/init.h>
9
#include <linux/slab.h>
10
#include <linux/sched.h>
11
#include <linux/circ_buf.h>
12
#include <linux/iversion.h>
13
#include "internal.h"
14
#include "afs_fs.h"
15
#include "xdr_fs.h"
16
#include "protocol_yfs.h"
17
18
#define xdr_size(x) (sizeof(*x) / sizeof(__be32))
19
20
static void xdr_decode_YFSFid(const __be32 **_bp, struct afs_fid *fid)
21
{
22
const struct yfs_xdr_YFSFid *x = (const void *)*_bp;
23
24
fid->vid = xdr_to_u64(x->volume);
25
fid->vnode = xdr_to_u64(x->vnode.lo);
26
fid->vnode_hi = ntohl(x->vnode.hi);
27
fid->unique = ntohl(x->vnode.unique);
28
*_bp += xdr_size(x);
29
}
30
31
static __be32 *xdr_encode_u32(__be32 *bp, u32 n)
32
{
33
*bp++ = htonl(n);
34
return bp;
35
}
36
37
static __be32 *xdr_encode_u64(__be32 *bp, u64 n)
38
{
39
struct yfs_xdr_u64 *x = (void *)bp;
40
41
*x = u64_to_xdr(n);
42
return bp + xdr_size(x);
43
}
44
45
static __be32 *xdr_encode_YFSFid(__be32 *bp, struct afs_fid *fid)
46
{
47
struct yfs_xdr_YFSFid *x = (void *)bp;
48
49
x->volume = u64_to_xdr(fid->vid);
50
x->vnode.lo = u64_to_xdr(fid->vnode);
51
x->vnode.hi = htonl(fid->vnode_hi);
52
x->vnode.unique = htonl(fid->unique);
53
return bp + xdr_size(x);
54
}
55
56
static size_t xdr_strlen(unsigned int len)
57
{
58
return sizeof(__be32) + round_up(len, sizeof(__be32));
59
}
60
61
static __be32 *xdr_encode_string(__be32 *bp, const char *p, unsigned int len)
62
{
63
bp = xdr_encode_u32(bp, len);
64
bp = memcpy(bp, p, len);
65
if (len & 3) {
66
unsigned int pad = 4 - (len & 3);
67
68
memset((u8 *)bp + len, 0, pad);
69
len += pad;
70
}
71
72
return bp + len / sizeof(__be32);
73
}
74
75
static __be32 *xdr_encode_name(__be32 *bp, const struct qstr *p)
76
{
77
return xdr_encode_string(bp, p->name, p->len);
78
}
79
80
static s64 linux_to_yfs_time(const struct timespec64 *t)
81
{
82
/* Convert to 100ns intervals. */
83
return (u64)t->tv_sec * 10000000 + t->tv_nsec/100;
84
}
85
86
static __be32 *xdr_encode_YFSStoreStatus(__be32 *bp, mode_t *mode,
87
const struct timespec64 *t)
88
{
89
struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
90
mode_t masked_mode = mode ? *mode & S_IALLUGO : 0;
91
s64 mtime = linux_to_yfs_time(t);
92
u32 mask = AFS_SET_MTIME;
93
94
mask |= mode ? AFS_SET_MODE : 0;
95
96
x->mask = htonl(mask);
97
x->mode = htonl(masked_mode);
98
x->mtime_client = u64_to_xdr(mtime);
99
x->owner = u64_to_xdr(0);
100
x->group = u64_to_xdr(0);
101
return bp + xdr_size(x);
102
}
103
104
/*
105
* Convert a signed 100ns-resolution 64-bit time into a timespec.
106
*/
107
static struct timespec64 yfs_time_to_linux(s64 t)
108
{
109
struct timespec64 ts;
110
u64 abs_t;
111
112
/*
113
* Unfortunately can not use normal 64 bit division on 32 bit arch, but
114
* the alternative, do_div, does not work with negative numbers so have
115
* to special case them
116
*/
117
if (t < 0) {
118
abs_t = -t;
119
ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100);
120
ts.tv_nsec = -ts.tv_nsec;
121
ts.tv_sec = -abs_t;
122
} else {
123
abs_t = t;
124
ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100;
125
ts.tv_sec = abs_t;
126
}
127
128
return ts;
129
}
130
131
static struct timespec64 xdr_to_time(const struct yfs_xdr_u64 xdr)
132
{
133
s64 t = xdr_to_u64(xdr);
134
135
return yfs_time_to_linux(t);
136
}
137
138
static void yfs_check_req(struct afs_call *call, __be32 *bp)
139
{
140
size_t len = (void *)bp - call->request;
141
142
if (len > call->request_size)
143
pr_err("kAFS: %s: Request buffer overflow (%zu>%u)\n",
144
call->type->name, len, call->request_size);
145
else if (len < call->request_size)
146
pr_warn("kAFS: %s: Request buffer underflow (%zu<%u)\n",
147
call->type->name, len, call->request_size);
148
}
149
150
/*
151
* Dump a bad file status record.
152
*/
153
static void xdr_dump_bad(const __be32 *bp)
154
{
155
__be32 x[4];
156
int i;
157
158
pr_notice("YFS XDR: Bad status record\n");
159
for (i = 0; i < 6 * 4 * 4; i += 16) {
160
memcpy(x, bp, 16);
161
bp += 4;
162
pr_notice("%03x: %08x %08x %08x %08x\n",
163
i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));
164
}
165
166
memcpy(x, bp, 8);
167
pr_notice("0x60: %08x %08x\n", ntohl(x[0]), ntohl(x[1]));
168
}
169
170
/*
171
* Decode a YFSFetchStatus block
172
*/
173
static void xdr_decode_YFSFetchStatus(const __be32 **_bp,
174
struct afs_call *call,
175
struct afs_status_cb *scb)
176
{
177
const struct yfs_xdr_YFSFetchStatus *xdr = (const void *)*_bp;
178
struct afs_file_status *status = &scb->status;
179
u32 type;
180
181
status->abort_code = ntohl(xdr->abort_code);
182
if (status->abort_code != 0) {
183
if (status->abort_code == VNOVNODE)
184
status->nlink = 0;
185
scb->have_error = true;
186
goto advance;
187
}
188
189
type = ntohl(xdr->type);
190
switch (type) {
191
case AFS_FTYPE_FILE:
192
case AFS_FTYPE_DIR:
193
case AFS_FTYPE_SYMLINK:
194
status->type = type;
195
break;
196
default:
197
goto bad;
198
}
199
200
status->nlink = ntohl(xdr->nlink);
201
status->author = xdr_to_u64(xdr->author);
202
status->owner = xdr_to_u64(xdr->owner);
203
status->caller_access = ntohl(xdr->caller_access); /* Ticket dependent */
204
status->anon_access = ntohl(xdr->anon_access);
205
status->mode = ntohl(xdr->mode) & S_IALLUGO;
206
status->group = xdr_to_u64(xdr->group);
207
status->lock_count = ntohl(xdr->lock_count);
208
209
status->mtime_client = xdr_to_time(xdr->mtime_client);
210
status->mtime_server = xdr_to_time(xdr->mtime_server);
211
status->size = xdr_to_u64(xdr->size);
212
status->data_version = xdr_to_u64(xdr->data_version);
213
scb->have_status = true;
214
advance:
215
*_bp += xdr_size(xdr);
216
return;
217
218
bad:
219
xdr_dump_bad(*_bp);
220
afs_protocol_error(call, afs_eproto_bad_status);
221
goto advance;
222
}
223
224
/*
225
* Decode a YFSCallBack block
226
*/
227
static void xdr_decode_YFSCallBack(const __be32 **_bp,
228
struct afs_call *call,
229
struct afs_status_cb *scb)
230
{
231
struct yfs_xdr_YFSCallBack *x = (void *)*_bp;
232
struct afs_callback *cb = &scb->callback;
233
ktime_t cb_expiry;
234
235
cb_expiry = ktime_add(call->issue_time, xdr_to_u64(x->expiration_time) * 100);
236
cb->expires_at = ktime_divns(cb_expiry, NSEC_PER_SEC);
237
scb->have_cb = true;
238
*_bp += xdr_size(x);
239
}
240
241
/*
242
* Decode a YFSVolSync block
243
*/
244
static void xdr_decode_YFSVolSync(const __be32 **_bp,
245
struct afs_volsync *volsync)
246
{
247
struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
248
u64 creation, update;
249
250
if (volsync) {
251
creation = xdr_to_u64(x->vol_creation_date);
252
do_div(creation, 10 * 1000 * 1000);
253
volsync->creation = creation;
254
update = xdr_to_u64(x->vol_update_date);
255
do_div(update, 10 * 1000 * 1000);
256
volsync->update = update;
257
}
258
259
*_bp += xdr_size(x);
260
}
261
262
/*
263
* Encode the requested attributes into a YFSStoreStatus block
264
*/
265
static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
266
{
267
struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
268
s64 mtime = 0, owner = 0, group = 0;
269
u32 mask = 0, mode = 0;
270
271
mask = 0;
272
if (attr->ia_valid & ATTR_MTIME) {
273
mask |= AFS_SET_MTIME;
274
mtime = linux_to_yfs_time(&attr->ia_mtime);
275
}
276
277
if (attr->ia_valid & ATTR_UID) {
278
mask |= AFS_SET_OWNER;
279
owner = from_kuid(&init_user_ns, attr->ia_uid);
280
}
281
282
if (attr->ia_valid & ATTR_GID) {
283
mask |= AFS_SET_GROUP;
284
group = from_kgid(&init_user_ns, attr->ia_gid);
285
}
286
287
if (attr->ia_valid & ATTR_MODE) {
288
mask |= AFS_SET_MODE;
289
mode = attr->ia_mode & S_IALLUGO;
290
}
291
292
x->mask = htonl(mask);
293
x->mode = htonl(mode);
294
x->mtime_client = u64_to_xdr(mtime);
295
x->owner = u64_to_xdr(owner);
296
x->group = u64_to_xdr(group);
297
return bp + xdr_size(x);
298
}
299
300
/*
301
* Decode a YFSFetchVolumeStatus block.
302
*/
303
static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
304
struct afs_volume_status *vs)
305
{
306
const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
307
u32 flags;
308
309
vs->vid = xdr_to_u64(x->vid);
310
vs->parent_id = xdr_to_u64(x->parent_id);
311
flags = ntohl(x->flags);
312
vs->online = flags & yfs_FVSOnline;
313
vs->in_service = flags & yfs_FVSInservice;
314
vs->blessed = flags & yfs_FVSBlessed;
315
vs->needs_salvage = flags & yfs_FVSNeedsSalvage;
316
vs->type = ntohl(x->type);
317
vs->min_quota = 0;
318
vs->max_quota = xdr_to_u64(x->max_quota);
319
vs->blocks_in_use = xdr_to_u64(x->blocks_in_use);
320
vs->part_blocks_avail = xdr_to_u64(x->part_blocks_avail);
321
vs->part_max_blocks = xdr_to_u64(x->part_max_blocks);
322
vs->vol_copy_date = xdr_to_u64(x->vol_copy_date);
323
vs->vol_backup_date = xdr_to_u64(x->vol_backup_date);
324
*_bp += sizeof(*x) / sizeof(__be32);
325
}
326
327
/*
328
* Deliver reply data to operations that just return a file status and a volume
329
* sync record.
330
*/
331
static int yfs_deliver_status_and_volsync(struct afs_call *call)
332
{
333
struct afs_operation *op = call->op;
334
const __be32 *bp;
335
int ret;
336
337
ret = afs_transfer_reply(call);
338
if (ret < 0)
339
return ret;
340
341
bp = call->buffer;
342
xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb);
343
xdr_decode_YFSVolSync(&bp, &op->volsync);
344
345
_leave(" = 0 [done]");
346
return 0;
347
}
348
349
/*
350
* Deliver reply data to an YFS.FetchData64.
351
*/
352
static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
353
{
354
struct afs_operation *op = call->op;
355
struct netfs_io_subrequest *subreq = op->fetch.subreq;
356
struct afs_vnode_param *vp = &op->file[0];
357
const __be32 *bp;
358
size_t count_before;
359
int ret;
360
361
_enter("{%u,%zu, %zu/%llu}",
362
call->unmarshall, call->iov_len, iov_iter_count(call->iter),
363
call->remaining);
364
365
switch (call->unmarshall) {
366
case 0:
367
call->remaining = 0;
368
afs_extract_to_tmp64(call);
369
call->unmarshall++;
370
fallthrough;
371
372
/* Extract the returned data length into ->actual_len. This
373
* may indicate more or less data than was requested will be
374
* returned.
375
*/
376
case 1:
377
_debug("extract data length");
378
ret = afs_extract_data(call, true);
379
if (ret < 0)
380
return ret;
381
382
call->remaining = be64_to_cpu(call->tmp64);
383
_debug("DATA length: %llu", call->remaining);
384
385
if (call->remaining == 0)
386
goto no_more_data;
387
388
call->iter = &subreq->io_iter;
389
call->iov_len = min(call->remaining, subreq->len - subreq->transferred);
390
call->unmarshall++;
391
fallthrough;
392
393
/* extract the returned data */
394
case 2:
395
count_before = call->iov_len;
396
_debug("extract data %zu/%llu", count_before, call->remaining);
397
398
ret = afs_extract_data(call, true);
399
subreq->transferred += count_before - call->iov_len;
400
if (ret < 0)
401
return ret;
402
403
call->iter = &call->def_iter;
404
if (call->remaining)
405
goto no_more_data;
406
407
/* Discard any excess data the server gave us */
408
afs_extract_discard(call, call->remaining);
409
call->unmarshall = 3;
410
fallthrough;
411
412
case 3:
413
_debug("extract discard %zu/%llu",
414
iov_iter_count(call->iter), call->remaining);
415
416
ret = afs_extract_data(call, true);
417
if (ret < 0)
418
return ret;
419
420
no_more_data:
421
call->unmarshall = 4;
422
afs_extract_to_buf(call,
423
sizeof(struct yfs_xdr_YFSFetchStatus) +
424
sizeof(struct yfs_xdr_YFSCallBack) +
425
sizeof(struct yfs_xdr_YFSVolSync));
426
fallthrough;
427
428
/* extract the metadata */
429
case 4:
430
ret = afs_extract_data(call, false);
431
if (ret < 0)
432
return ret;
433
434
bp = call->buffer;
435
xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
436
xdr_decode_YFSCallBack(&bp, call, &vp->scb);
437
xdr_decode_YFSVolSync(&bp, &op->volsync);
438
439
if (subreq->start + subreq->transferred >= vp->scb.status.size)
440
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
441
442
call->unmarshall++;
443
fallthrough;
444
445
case 5:
446
break;
447
}
448
449
_leave(" = 0 [done]");
450
return 0;
451
}
452
453
/*
454
* YFS.FetchData64 operation type
455
*/
456
static const struct afs_call_type yfs_RXYFSFetchData64 = {
457
.name = "YFS.FetchData64",
458
.op = yfs_FS_FetchData64,
459
.async_rx = afs_fetch_data_async_rx,
460
.deliver = yfs_deliver_fs_fetch_data64,
461
.immediate_cancel = afs_fetch_data_immediate_cancel,
462
.destructor = afs_flat_call_destructor,
463
};
464
465
/*
466
* Fetch data from a file.
467
*/
468
void yfs_fs_fetch_data(struct afs_operation *op)
469
{
470
struct netfs_io_subrequest *subreq = op->fetch.subreq;
471
struct afs_vnode_param *vp = &op->file[0];
472
struct afs_call *call;
473
__be32 *bp;
474
475
_enter(",%x,{%llx:%llu},%llx,%zx",
476
key_serial(op->key), vp->fid.vid, vp->fid.vnode,
477
subreq->start + subreq->transferred,
478
subreq->len - subreq->transferred);
479
480
call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchData64,
481
sizeof(__be32) * 2 +
482
sizeof(struct yfs_xdr_YFSFid) +
483
sizeof(struct yfs_xdr_u64) * 2,
484
sizeof(struct yfs_xdr_YFSFetchStatus) +
485
sizeof(struct yfs_xdr_YFSCallBack) +
486
sizeof(struct yfs_xdr_YFSVolSync));
487
if (!call)
488
return afs_op_nomem(op);
489
490
if (op->flags & AFS_OPERATION_ASYNC)
491
call->async = true;
492
493
/* marshall the parameters */
494
bp = call->request;
495
bp = xdr_encode_u32(bp, YFSFETCHDATA64);
496
bp = xdr_encode_u32(bp, 0); /* RPC flags */
497
bp = xdr_encode_YFSFid(bp, &vp->fid);
498
bp = xdr_encode_u64(bp, subreq->start + subreq->transferred);
499
bp = xdr_encode_u64(bp, subreq->len - subreq->transferred);
500
yfs_check_req(call, bp);
501
502
call->fid = vp->fid;
503
trace_afs_make_fs_call(call, &vp->fid);
504
afs_make_op_call(op, call, GFP_NOFS);
505
}
506
507
/*
508
* Deliver reply data for YFS.CreateFile or YFS.MakeDir.
509
*/
510
static int yfs_deliver_fs_create_vnode(struct afs_call *call)
511
{
512
struct afs_operation *op = call->op;
513
struct afs_vnode_param *dvp = &op->file[0];
514
struct afs_vnode_param *vp = &op->file[1];
515
const __be32 *bp;
516
int ret;
517
518
_enter("{%u}", call->unmarshall);
519
520
ret = afs_transfer_reply(call);
521
if (ret < 0)
522
return ret;
523
524
/* unmarshall the reply once we've received all of it */
525
bp = call->buffer;
526
xdr_decode_YFSFid(&bp, &op->file[1].fid);
527
xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
528
xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
529
xdr_decode_YFSCallBack(&bp, call, &vp->scb);
530
xdr_decode_YFSVolSync(&bp, &op->volsync);
531
532
_leave(" = 0 [done]");
533
return 0;
534
}
535
536
/*
537
* FS.CreateFile and FS.MakeDir operation type
538
*/
539
static const struct afs_call_type afs_RXFSCreateFile = {
540
.name = "YFS.CreateFile",
541
.op = yfs_FS_CreateFile,
542
.deliver = yfs_deliver_fs_create_vnode,
543
.destructor = afs_flat_call_destructor,
544
};
545
546
/*
547
* Create a file.
548
*/
549
void yfs_fs_create_file(struct afs_operation *op)
550
{
551
const struct qstr *name = &op->dentry->d_name;
552
struct afs_vnode_param *dvp = &op->file[0];
553
struct afs_call *call;
554
size_t reqsz, rplsz;
555
__be32 *bp;
556
557
_enter("");
558
559
reqsz = (sizeof(__be32) +
560
sizeof(__be32) +
561
sizeof(struct yfs_xdr_YFSFid) +
562
xdr_strlen(name->len) +
563
sizeof(struct yfs_xdr_YFSStoreStatus) +
564
sizeof(__be32));
565
rplsz = (sizeof(struct yfs_xdr_YFSFid) +
566
sizeof(struct yfs_xdr_YFSFetchStatus) +
567
sizeof(struct yfs_xdr_YFSFetchStatus) +
568
sizeof(struct yfs_xdr_YFSCallBack) +
569
sizeof(struct yfs_xdr_YFSVolSync));
570
571
call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, reqsz, rplsz);
572
if (!call)
573
return afs_op_nomem(op);
574
575
/* marshall the parameters */
576
bp = call->request;
577
bp = xdr_encode_u32(bp, YFSCREATEFILE);
578
bp = xdr_encode_u32(bp, 0); /* RPC flags */
579
bp = xdr_encode_YFSFid(bp, &dvp->fid);
580
bp = xdr_encode_name(bp, name);
581
bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
582
bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
583
yfs_check_req(call, bp);
584
585
call->fid = dvp->fid;
586
trace_afs_make_fs_call1(call, &dvp->fid, name);
587
afs_make_op_call(op, call, GFP_NOFS);
588
}
589
590
static const struct afs_call_type yfs_RXFSMakeDir = {
591
.name = "YFS.MakeDir",
592
.op = yfs_FS_MakeDir,
593
.deliver = yfs_deliver_fs_create_vnode,
594
.destructor = afs_flat_call_destructor,
595
};
596
597
/*
598
* Make a directory.
599
*/
600
void yfs_fs_make_dir(struct afs_operation *op)
601
{
602
const struct qstr *name = &op->dentry->d_name;
603
struct afs_vnode_param *dvp = &op->file[0];
604
struct afs_call *call;
605
size_t reqsz, rplsz;
606
__be32 *bp;
607
608
_enter("");
609
610
reqsz = (sizeof(__be32) +
611
sizeof(struct yfs_xdr_RPCFlags) +
612
sizeof(struct yfs_xdr_YFSFid) +
613
xdr_strlen(name->len) +
614
sizeof(struct yfs_xdr_YFSStoreStatus));
615
rplsz = (sizeof(struct yfs_xdr_YFSFid) +
616
sizeof(struct yfs_xdr_YFSFetchStatus) +
617
sizeof(struct yfs_xdr_YFSFetchStatus) +
618
sizeof(struct yfs_xdr_YFSCallBack) +
619
sizeof(struct yfs_xdr_YFSVolSync));
620
621
call = afs_alloc_flat_call(op->net, &yfs_RXFSMakeDir, reqsz, rplsz);
622
if (!call)
623
return afs_op_nomem(op);
624
625
/* marshall the parameters */
626
bp = call->request;
627
bp = xdr_encode_u32(bp, YFSMAKEDIR);
628
bp = xdr_encode_u32(bp, 0); /* RPC flags */
629
bp = xdr_encode_YFSFid(bp, &dvp->fid);
630
bp = xdr_encode_name(bp, name);
631
bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
632
yfs_check_req(call, bp);
633
634
call->fid = dvp->fid;
635
trace_afs_make_fs_call1(call, &dvp->fid, name);
636
afs_make_op_call(op, call, GFP_NOFS);
637
}
638
639
/*
640
* Deliver reply data to a YFS.RemoveFile2 operation.
641
*/
642
static int yfs_deliver_fs_remove_file2(struct afs_call *call)
643
{
644
struct afs_operation *op = call->op;
645
struct afs_vnode_param *dvp = &op->file[0];
646
struct afs_vnode_param *vp = &op->file[1];
647
struct afs_fid fid;
648
const __be32 *bp;
649
int ret;
650
651
_enter("{%u}", call->unmarshall);
652
653
ret = afs_transfer_reply(call);
654
if (ret < 0)
655
return ret;
656
657
bp = call->buffer;
658
xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
659
xdr_decode_YFSFid(&bp, &fid);
660
xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
661
/* Was deleted if vnode->status.abort_code == VNOVNODE. */
662
663
xdr_decode_YFSVolSync(&bp, &op->volsync);
664
return 0;
665
}
666
667
static void yfs_done_fs_remove_file2(struct afs_call *call)
668
{
669
if (call->error == -ECONNABORTED &&
670
(call->abort_code == RX_INVALID_OPERATION ||
671
call->abort_code == RXGEN_OPCODE)) {
672
set_bit(AFS_SERVER_FL_NO_RM2, &call->op->server->flags);
673
call->op->flags |= AFS_OPERATION_DOWNGRADE;
674
}
675
}
676
677
/*
678
* YFS.RemoveFile2 operation type.
679
*/
680
static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
681
.name = "YFS.RemoveFile2",
682
.op = yfs_FS_RemoveFile2,
683
.deliver = yfs_deliver_fs_remove_file2,
684
.done = yfs_done_fs_remove_file2,
685
.destructor = afs_flat_call_destructor,
686
};
687
688
/*
689
* Remove a file and retrieve new file status.
690
*/
691
void yfs_fs_remove_file2(struct afs_operation *op)
692
{
693
struct afs_vnode_param *dvp = &op->file[0];
694
const struct qstr *name = &op->dentry->d_name;
695
struct afs_call *call;
696
__be32 *bp;
697
698
_enter("");
699
700
call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile2,
701
sizeof(__be32) +
702
sizeof(struct yfs_xdr_RPCFlags) +
703
sizeof(struct yfs_xdr_YFSFid) +
704
xdr_strlen(name->len),
705
sizeof(struct yfs_xdr_YFSFetchStatus) +
706
sizeof(struct yfs_xdr_YFSFid) +
707
sizeof(struct yfs_xdr_YFSFetchStatus) +
708
sizeof(struct yfs_xdr_YFSVolSync));
709
if (!call)
710
return afs_op_nomem(op);
711
712
/* marshall the parameters */
713
bp = call->request;
714
bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
715
bp = xdr_encode_u32(bp, 0); /* RPC flags */
716
bp = xdr_encode_YFSFid(bp, &dvp->fid);
717
bp = xdr_encode_name(bp, name);
718
yfs_check_req(call, bp);
719
720
call->fid = dvp->fid;
721
trace_afs_make_fs_call1(call, &dvp->fid, name);
722
afs_make_op_call(op, call, GFP_NOFS);
723
}
724
725
/*
726
* Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
727
*/
728
static int yfs_deliver_fs_remove(struct afs_call *call)
729
{
730
struct afs_operation *op = call->op;
731
struct afs_vnode_param *dvp = &op->file[0];
732
const __be32 *bp;
733
int ret;
734
735
_enter("{%u}", call->unmarshall);
736
737
ret = afs_transfer_reply(call);
738
if (ret < 0)
739
return ret;
740
741
bp = call->buffer;
742
xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
743
xdr_decode_YFSVolSync(&bp, &op->volsync);
744
return 0;
745
}
746
747
/*
748
* FS.RemoveDir and FS.RemoveFile operation types.
749
*/
750
static const struct afs_call_type yfs_RXYFSRemoveFile = {
751
.name = "YFS.RemoveFile",
752
.op = yfs_FS_RemoveFile,
753
.deliver = yfs_deliver_fs_remove,
754
.destructor = afs_flat_call_destructor,
755
};
756
757
/*
758
* Remove a file.
759
*/
760
void yfs_fs_remove_file(struct afs_operation *op)
761
{
762
const struct qstr *name = &op->dentry->d_name;
763
struct afs_vnode_param *dvp = &op->file[0];
764
struct afs_call *call;
765
__be32 *bp;
766
767
_enter("");
768
769
if (!test_bit(AFS_SERVER_FL_NO_RM2, &op->server->flags))
770
return yfs_fs_remove_file2(op);
771
772
call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile,
773
sizeof(__be32) +
774
sizeof(struct yfs_xdr_RPCFlags) +
775
sizeof(struct yfs_xdr_YFSFid) +
776
xdr_strlen(name->len),
777
sizeof(struct yfs_xdr_YFSFetchStatus) +
778
sizeof(struct yfs_xdr_YFSVolSync));
779
if (!call)
780
return afs_op_nomem(op);
781
782
/* marshall the parameters */
783
bp = call->request;
784
bp = xdr_encode_u32(bp, YFSREMOVEFILE);
785
bp = xdr_encode_u32(bp, 0); /* RPC flags */
786
bp = xdr_encode_YFSFid(bp, &dvp->fid);
787
bp = xdr_encode_name(bp, name);
788
yfs_check_req(call, bp);
789
790
call->fid = dvp->fid;
791
trace_afs_make_fs_call1(call, &dvp->fid, name);
792
afs_make_op_call(op, call, GFP_NOFS);
793
}
794
795
static const struct afs_call_type yfs_RXYFSRemoveDir = {
796
.name = "YFS.RemoveDir",
797
.op = yfs_FS_RemoveDir,
798
.deliver = yfs_deliver_fs_remove,
799
.destructor = afs_flat_call_destructor,
800
};
801
802
/*
803
* Remove a directory.
804
*/
805
void yfs_fs_remove_dir(struct afs_operation *op)
806
{
807
const struct qstr *name = &op->dentry->d_name;
808
struct afs_vnode_param *dvp = &op->file[0];
809
struct afs_call *call;
810
__be32 *bp;
811
812
_enter("");
813
814
call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveDir,
815
sizeof(__be32) +
816
sizeof(struct yfs_xdr_RPCFlags) +
817
sizeof(struct yfs_xdr_YFSFid) +
818
xdr_strlen(name->len),
819
sizeof(struct yfs_xdr_YFSFetchStatus) +
820
sizeof(struct yfs_xdr_YFSVolSync));
821
if (!call)
822
return afs_op_nomem(op);
823
824
/* marshall the parameters */
825
bp = call->request;
826
bp = xdr_encode_u32(bp, YFSREMOVEDIR);
827
bp = xdr_encode_u32(bp, 0); /* RPC flags */
828
bp = xdr_encode_YFSFid(bp, &dvp->fid);
829
bp = xdr_encode_name(bp, name);
830
yfs_check_req(call, bp);
831
832
call->fid = dvp->fid;
833
trace_afs_make_fs_call1(call, &dvp->fid, name);
834
afs_make_op_call(op, call, GFP_NOFS);
835
}
836
837
/*
838
* Deliver reply data to a YFS.Link operation.
839
*/
840
static int yfs_deliver_fs_link(struct afs_call *call)
841
{
842
struct afs_operation *op = call->op;
843
struct afs_vnode_param *dvp = &op->file[0];
844
struct afs_vnode_param *vp = &op->file[1];
845
const __be32 *bp;
846
int ret;
847
848
_enter("{%u}", call->unmarshall);
849
850
ret = afs_transfer_reply(call);
851
if (ret < 0)
852
return ret;
853
854
bp = call->buffer;
855
xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
856
xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
857
xdr_decode_YFSVolSync(&bp, &op->volsync);
858
_leave(" = 0 [done]");
859
return 0;
860
}
861
862
/*
863
* YFS.Link operation type.
864
*/
865
static const struct afs_call_type yfs_RXYFSLink = {
866
.name = "YFS.Link",
867
.op = yfs_FS_Link,
868
.deliver = yfs_deliver_fs_link,
869
.destructor = afs_flat_call_destructor,
870
};
871
872
/*
873
* Make a hard link.
874
*/
875
void yfs_fs_link(struct afs_operation *op)
876
{
877
const struct qstr *name = &op->dentry->d_name;
878
struct afs_vnode_param *dvp = &op->file[0];
879
struct afs_vnode_param *vp = &op->file[1];
880
struct afs_call *call;
881
__be32 *bp;
882
883
_enter("");
884
885
call = afs_alloc_flat_call(op->net, &yfs_RXYFSLink,
886
sizeof(__be32) +
887
sizeof(struct yfs_xdr_RPCFlags) +
888
sizeof(struct yfs_xdr_YFSFid) +
889
xdr_strlen(name->len) +
890
sizeof(struct yfs_xdr_YFSFid),
891
sizeof(struct yfs_xdr_YFSFetchStatus) +
892
sizeof(struct yfs_xdr_YFSFetchStatus) +
893
sizeof(struct yfs_xdr_YFSVolSync));
894
if (!call)
895
return afs_op_nomem(op);
896
897
/* marshall the parameters */
898
bp = call->request;
899
bp = xdr_encode_u32(bp, YFSLINK);
900
bp = xdr_encode_u32(bp, 0); /* RPC flags */
901
bp = xdr_encode_YFSFid(bp, &dvp->fid);
902
bp = xdr_encode_name(bp, name);
903
bp = xdr_encode_YFSFid(bp, &vp->fid);
904
yfs_check_req(call, bp);
905
906
call->fid = vp->fid;
907
trace_afs_make_fs_call1(call, &vp->fid, name);
908
afs_make_op_call(op, call, GFP_NOFS);
909
}
910
911
/*
912
* Deliver reply data to a YFS.Symlink operation.
913
*/
914
static int yfs_deliver_fs_symlink(struct afs_call *call)
915
{
916
struct afs_operation *op = call->op;
917
struct afs_vnode_param *dvp = &op->file[0];
918
struct afs_vnode_param *vp = &op->file[1];
919
const __be32 *bp;
920
int ret;
921
922
_enter("{%u}", call->unmarshall);
923
924
ret = afs_transfer_reply(call);
925
if (ret < 0)
926
return ret;
927
928
/* unmarshall the reply once we've received all of it */
929
bp = call->buffer;
930
xdr_decode_YFSFid(&bp, &vp->fid);
931
xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
932
xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
933
xdr_decode_YFSVolSync(&bp, &op->volsync);
934
935
_leave(" = 0 [done]");
936
return 0;
937
}
938
939
/*
940
* YFS.Symlink operation type
941
*/
942
static const struct afs_call_type yfs_RXYFSSymlink = {
943
.name = "YFS.Symlink",
944
.op = yfs_FS_Symlink,
945
.deliver = yfs_deliver_fs_symlink,
946
.destructor = afs_flat_call_destructor,
947
};
948
949
/*
950
* Create a symbolic link.
951
*/
952
void yfs_fs_symlink(struct afs_operation *op)
953
{
954
const struct qstr *name = &op->dentry->d_name;
955
struct afs_vnode_param *dvp = &op->file[0];
956
struct afs_call *call;
957
size_t contents_sz;
958
mode_t mode = 0777;
959
__be32 *bp;
960
961
_enter("");
962
963
contents_sz = strlen(op->create.symlink);
964
call = afs_alloc_flat_call(op->net, &yfs_RXYFSSymlink,
965
sizeof(__be32) +
966
sizeof(struct yfs_xdr_RPCFlags) +
967
sizeof(struct yfs_xdr_YFSFid) +
968
xdr_strlen(name->len) +
969
xdr_strlen(contents_sz) +
970
sizeof(struct yfs_xdr_YFSStoreStatus),
971
sizeof(struct yfs_xdr_YFSFid) +
972
sizeof(struct yfs_xdr_YFSFetchStatus) +
973
sizeof(struct yfs_xdr_YFSFetchStatus) +
974
sizeof(struct yfs_xdr_YFSVolSync));
975
if (!call)
976
return afs_op_nomem(op);
977
978
/* marshall the parameters */
979
bp = call->request;
980
bp = xdr_encode_u32(bp, YFSSYMLINK);
981
bp = xdr_encode_u32(bp, 0); /* RPC flags */
982
bp = xdr_encode_YFSFid(bp, &dvp->fid);
983
bp = xdr_encode_name(bp, name);
984
bp = xdr_encode_string(bp, op->create.symlink, contents_sz);
985
bp = xdr_encode_YFSStoreStatus(bp, &mode, &op->mtime);
986
yfs_check_req(call, bp);
987
988
call->fid = dvp->fid;
989
trace_afs_make_fs_call1(call, &dvp->fid, name);
990
afs_make_op_call(op, call, GFP_NOFS);
991
}
992
993
/*
994
* Deliver reply data to a YFS.Rename operation.
995
*/
996
static int yfs_deliver_fs_rename(struct afs_call *call)
997
{
998
struct afs_operation *op = call->op;
999
struct afs_vnode_param *orig_dvp = &op->file[0];
1000
struct afs_vnode_param *new_dvp = &op->file[1];
1001
const __be32 *bp;
1002
int ret;
1003
1004
_enter("{%u}", call->unmarshall);
1005
1006
ret = afs_transfer_reply(call);
1007
if (ret < 0)
1008
return ret;
1009
1010
bp = call->buffer;
1011
/* If the two dirs are the same, we have two copies of the same status
1012
* report, so we just decode it twice.
1013
*/
1014
xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1015
xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1016
xdr_decode_YFSVolSync(&bp, &op->volsync);
1017
_leave(" = 0 [done]");
1018
return 0;
1019
}
1020
1021
/*
1022
* YFS.Rename operation type
1023
*/
1024
static const struct afs_call_type yfs_RXYFSRename = {
1025
.name = "FS.Rename",
1026
.op = yfs_FS_Rename,
1027
.deliver = yfs_deliver_fs_rename,
1028
.destructor = afs_flat_call_destructor,
1029
};
1030
1031
/*
1032
* Rename a file or directory.
1033
*/
1034
void yfs_fs_rename(struct afs_operation *op)
1035
{
1036
struct afs_vnode_param *orig_dvp = &op->file[0];
1037
struct afs_vnode_param *new_dvp = &op->file[1];
1038
const struct qstr *orig_name = &op->dentry->d_name;
1039
const struct qstr *new_name = &op->dentry_2->d_name;
1040
struct afs_call *call;
1041
__be32 *bp;
1042
1043
_enter("");
1044
1045
if (!test_bit(AFS_SERVER_FL_NO_RENAME2, &op->server->flags))
1046
return yfs_fs_rename_replace(op);
1047
1048
call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename,
1049
sizeof(__be32) +
1050
sizeof(struct yfs_xdr_RPCFlags) +
1051
sizeof(struct yfs_xdr_YFSFid) +
1052
xdr_strlen(orig_name->len) +
1053
sizeof(struct yfs_xdr_YFSFid) +
1054
xdr_strlen(new_name->len),
1055
sizeof(struct yfs_xdr_YFSFetchStatus) +
1056
sizeof(struct yfs_xdr_YFSFetchStatus) +
1057
sizeof(struct yfs_xdr_YFSVolSync));
1058
if (!call)
1059
return afs_op_nomem(op);
1060
1061
/* marshall the parameters */
1062
bp = call->request;
1063
bp = xdr_encode_u32(bp, YFSRENAME);
1064
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1065
bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1066
bp = xdr_encode_name(bp, orig_name);
1067
bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1068
bp = xdr_encode_name(bp, new_name);
1069
yfs_check_req(call, bp);
1070
1071
call->fid = orig_dvp->fid;
1072
trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1073
afs_make_op_call(op, call, GFP_NOFS);
1074
}
1075
1076
/*
1077
* Deliver reply data to a YFS.Rename_NoReplace operation. This does not
1078
* return the status of a displaced target inode as there cannot be one.
1079
*/
1080
static int yfs_deliver_fs_rename_1(struct afs_call *call)
1081
{
1082
struct afs_operation *op = call->op;
1083
struct afs_vnode_param *orig_dvp = &op->file[0];
1084
struct afs_vnode_param *new_dvp = &op->file[1];
1085
struct afs_vnode_param *old_vp = &op->more_files[0];
1086
const __be32 *bp;
1087
int ret;
1088
1089
_enter("{%u}", call->unmarshall);
1090
1091
ret = afs_transfer_reply(call);
1092
if (ret < 0)
1093
return ret;
1094
1095
bp = call->buffer;
1096
/* If the two dirs are the same, we have two copies of the same status
1097
* report, so we just decode it twice.
1098
*/
1099
xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1100
xdr_decode_YFSFid(&bp, &old_vp->fid);
1101
xdr_decode_YFSFetchStatus(&bp, call, &old_vp->scb);
1102
xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1103
xdr_decode_YFSVolSync(&bp, &op->volsync);
1104
_leave(" = 0 [done]");
1105
return 0;
1106
}
1107
1108
/*
1109
* Deliver reply data to a YFS.Rename_Replace or a YFS.Rename_Exchange
1110
* operation. These return the status of the displaced target inode if there
1111
* was one.
1112
*/
1113
static int yfs_deliver_fs_rename_2(struct afs_call *call)
1114
{
1115
struct afs_operation *op = call->op;
1116
struct afs_vnode_param *orig_dvp = &op->file[0];
1117
struct afs_vnode_param *new_dvp = &op->file[1];
1118
struct afs_vnode_param *old_vp = &op->more_files[0];
1119
struct afs_vnode_param *new_vp = &op->more_files[1];
1120
const __be32 *bp;
1121
int ret;
1122
1123
_enter("{%u}", call->unmarshall);
1124
1125
ret = afs_transfer_reply(call);
1126
if (ret < 0)
1127
return ret;
1128
1129
bp = call->buffer;
1130
/* If the two dirs are the same, we have two copies of the same status
1131
* report, so we just decode it twice.
1132
*/
1133
xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1134
xdr_decode_YFSFid(&bp, &old_vp->fid);
1135
xdr_decode_YFSFetchStatus(&bp, call, &old_vp->scb);
1136
xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1137
xdr_decode_YFSFid(&bp, &new_vp->fid);
1138
xdr_decode_YFSFetchStatus(&bp, call, &new_vp->scb);
1139
xdr_decode_YFSVolSync(&bp, &op->volsync);
1140
_leave(" = 0 [done]");
1141
return 0;
1142
}
1143
1144
static void yfs_done_fs_rename_replace(struct afs_call *call)
1145
{
1146
if (call->error == -ECONNABORTED &&
1147
(call->abort_code == RX_INVALID_OPERATION ||
1148
call->abort_code == RXGEN_OPCODE)) {
1149
set_bit(AFS_SERVER_FL_NO_RENAME2, &call->op->server->flags);
1150
call->op->flags |= AFS_OPERATION_DOWNGRADE;
1151
}
1152
}
1153
1154
/*
1155
* YFS.Rename_Replace operation type
1156
*/
1157
static const struct afs_call_type yfs_RXYFSRename_Replace = {
1158
.name = "FS.Rename_Replace",
1159
.op = yfs_FS_Rename_Replace,
1160
.deliver = yfs_deliver_fs_rename_2,
1161
.done = yfs_done_fs_rename_replace,
1162
.destructor = afs_flat_call_destructor,
1163
};
1164
1165
/*
1166
* YFS.Rename_NoReplace operation type
1167
*/
1168
static const struct afs_call_type yfs_RXYFSRename_NoReplace = {
1169
.name = "FS.Rename_NoReplace",
1170
.op = yfs_FS_Rename_NoReplace,
1171
.deliver = yfs_deliver_fs_rename_1,
1172
.destructor = afs_flat_call_destructor,
1173
};
1174
1175
/*
1176
* YFS.Rename_Exchange operation type
1177
*/
1178
static const struct afs_call_type yfs_RXYFSRename_Exchange = {
1179
.name = "FS.Rename_Exchange",
1180
.op = yfs_FS_Rename_Exchange,
1181
.deliver = yfs_deliver_fs_rename_2,
1182
.destructor = afs_flat_call_destructor,
1183
};
1184
1185
/*
1186
* Rename a file or directory, replacing the target if it exists. The status
1187
* of a displaced target is returned.
1188
*/
1189
void yfs_fs_rename_replace(struct afs_operation *op)
1190
{
1191
struct afs_vnode_param *orig_dvp = &op->file[0];
1192
struct afs_vnode_param *new_dvp = &op->file[1];
1193
const struct qstr *orig_name = &op->dentry->d_name;
1194
const struct qstr *new_name = &op->dentry_2->d_name;
1195
struct afs_call *call;
1196
__be32 *bp;
1197
1198
_enter("");
1199
1200
call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename_Replace,
1201
sizeof(__be32) +
1202
sizeof(struct yfs_xdr_RPCFlags) +
1203
sizeof(struct yfs_xdr_YFSFid) +
1204
xdr_strlen(orig_name->len) +
1205
sizeof(struct yfs_xdr_YFSFid) +
1206
xdr_strlen(new_name->len),
1207
sizeof(struct yfs_xdr_YFSFetchStatus) +
1208
sizeof(struct yfs_xdr_YFSFid) +
1209
sizeof(struct yfs_xdr_YFSFetchStatus) +
1210
sizeof(struct yfs_xdr_YFSFetchStatus) +
1211
sizeof(struct yfs_xdr_YFSFid) +
1212
sizeof(struct yfs_xdr_YFSFetchStatus) +
1213
sizeof(struct yfs_xdr_YFSVolSync));
1214
if (!call)
1215
return afs_op_nomem(op);
1216
1217
/* Marshall the parameters. */
1218
bp = call->request;
1219
bp = xdr_encode_u32(bp, YFSRENAME_REPLACE);
1220
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1221
bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1222
bp = xdr_encode_name(bp, orig_name);
1223
bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1224
bp = xdr_encode_name(bp, new_name);
1225
yfs_check_req(call, bp);
1226
1227
call->fid = orig_dvp->fid;
1228
trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1229
afs_make_op_call(op, call, GFP_NOFS);
1230
}
1231
1232
/*
1233
* Rename a file or directory, failing if the target dirent exists.
1234
*/
1235
void yfs_fs_rename_noreplace(struct afs_operation *op)
1236
{
1237
struct afs_vnode_param *orig_dvp = &op->file[0];
1238
struct afs_vnode_param *new_dvp = &op->file[1];
1239
const struct qstr *orig_name = &op->dentry->d_name;
1240
const struct qstr *new_name = &op->dentry_2->d_name;
1241
struct afs_call *call;
1242
__be32 *bp;
1243
1244
_enter("");
1245
1246
call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename_NoReplace,
1247
sizeof(__be32) +
1248
sizeof(struct yfs_xdr_RPCFlags) +
1249
sizeof(struct yfs_xdr_YFSFid) +
1250
xdr_strlen(orig_name->len) +
1251
sizeof(struct yfs_xdr_YFSFid) +
1252
xdr_strlen(new_name->len),
1253
sizeof(struct yfs_xdr_YFSFetchStatus) +
1254
sizeof(struct yfs_xdr_YFSFid) +
1255
sizeof(struct yfs_xdr_YFSFetchStatus) +
1256
sizeof(struct yfs_xdr_YFSFetchStatus) +
1257
sizeof(struct yfs_xdr_YFSVolSync));
1258
if (!call)
1259
return afs_op_nomem(op);
1260
1261
/* Marshall the parameters. */
1262
bp = call->request;
1263
bp = xdr_encode_u32(bp, YFSRENAME_NOREPLACE);
1264
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1265
bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1266
bp = xdr_encode_name(bp, orig_name);
1267
bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1268
bp = xdr_encode_name(bp, new_name);
1269
yfs_check_req(call, bp);
1270
1271
call->fid = orig_dvp->fid;
1272
trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1273
afs_make_op_call(op, call, GFP_NOFS);
1274
}
1275
1276
/*
1277
* Exchange a pair of files directories.
1278
*/
1279
void yfs_fs_rename_exchange(struct afs_operation *op)
1280
{
1281
struct afs_vnode_param *orig_dvp = &op->file[0];
1282
struct afs_vnode_param *new_dvp = &op->file[1];
1283
const struct qstr *orig_name = &op->dentry->d_name;
1284
const struct qstr *new_name = &op->dentry_2->d_name;
1285
struct afs_call *call;
1286
__be32 *bp;
1287
1288
_enter("");
1289
1290
call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename_Exchange,
1291
sizeof(__be32) +
1292
sizeof(struct yfs_xdr_RPCFlags) +
1293
sizeof(struct yfs_xdr_YFSFid) +
1294
xdr_strlen(orig_name->len) +
1295
sizeof(struct yfs_xdr_YFSFid) +
1296
xdr_strlen(new_name->len),
1297
sizeof(struct yfs_xdr_YFSFetchStatus) +
1298
sizeof(struct yfs_xdr_YFSFid) +
1299
sizeof(struct yfs_xdr_YFSFetchStatus) +
1300
sizeof(struct yfs_xdr_YFSFetchStatus) +
1301
sizeof(struct yfs_xdr_YFSFid) +
1302
sizeof(struct yfs_xdr_YFSFetchStatus) +
1303
sizeof(struct yfs_xdr_YFSVolSync));
1304
if (!call)
1305
return afs_op_nomem(op);
1306
1307
/* Marshall the parameters. */
1308
bp = call->request;
1309
bp = xdr_encode_u32(bp, YFSRENAME_EXCHANGE);
1310
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1311
bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1312
bp = xdr_encode_name(bp, orig_name);
1313
bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1314
bp = xdr_encode_name(bp, new_name);
1315
yfs_check_req(call, bp);
1316
1317
call->fid = orig_dvp->fid;
1318
trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1319
afs_make_op_call(op, call, GFP_NOFS);
1320
}
1321
1322
/*
1323
* YFS.StoreData64 operation type.
1324
*/
1325
static const struct afs_call_type yfs_RXYFSStoreData64 = {
1326
.name = "YFS.StoreData64",
1327
.op = yfs_FS_StoreData64,
1328
.deliver = yfs_deliver_status_and_volsync,
1329
.destructor = afs_flat_call_destructor,
1330
};
1331
1332
/*
1333
* Store a set of pages to a large file.
1334
*/
1335
void yfs_fs_store_data(struct afs_operation *op)
1336
{
1337
struct afs_vnode_param *vp = &op->file[0];
1338
struct afs_call *call;
1339
__be32 *bp;
1340
1341
_enter(",%x,{%llx:%llu},,",
1342
key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1343
1344
_debug("size %llx, at %llx, i_size %llx",
1345
(unsigned long long)op->store.size,
1346
(unsigned long long)op->store.pos,
1347
(unsigned long long)op->store.i_size);
1348
1349
call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64,
1350
sizeof(__be32) +
1351
sizeof(__be32) +
1352
sizeof(struct yfs_xdr_YFSFid) +
1353
sizeof(struct yfs_xdr_YFSStoreStatus) +
1354
sizeof(struct yfs_xdr_u64) * 3,
1355
sizeof(struct yfs_xdr_YFSFetchStatus) +
1356
sizeof(struct yfs_xdr_YFSVolSync));
1357
if (!call)
1358
return afs_op_nomem(op);
1359
1360
call->write_iter = op->store.write_iter;
1361
1362
/* marshall the parameters */
1363
bp = call->request;
1364
bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1365
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1366
bp = xdr_encode_YFSFid(bp, &vp->fid);
1367
bp = xdr_encode_YFSStoreStatus(bp, NULL, &op->mtime);
1368
bp = xdr_encode_u64(bp, op->store.pos);
1369
bp = xdr_encode_u64(bp, op->store.size);
1370
bp = xdr_encode_u64(bp, op->store.i_size);
1371
yfs_check_req(call, bp);
1372
1373
call->fid = vp->fid;
1374
trace_afs_make_fs_call(call, &vp->fid);
1375
afs_make_op_call(op, call, GFP_NOFS);
1376
}
1377
1378
/*
1379
* YFS.StoreStatus operation type
1380
*/
1381
static const struct afs_call_type yfs_RXYFSStoreStatus = {
1382
.name = "YFS.StoreStatus",
1383
.op = yfs_FS_StoreStatus,
1384
.deliver = yfs_deliver_status_and_volsync,
1385
.destructor = afs_flat_call_destructor,
1386
};
1387
1388
static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1389
.name = "YFS.StoreData64",
1390
.op = yfs_FS_StoreData64,
1391
.deliver = yfs_deliver_status_and_volsync,
1392
.destructor = afs_flat_call_destructor,
1393
};
1394
1395
/*
1396
* Set the attributes on a file, using YFS.StoreData64 rather than
1397
* YFS.StoreStatus so as to alter the file size also.
1398
*/
1399
static void yfs_fs_setattr_size(struct afs_operation *op)
1400
{
1401
struct afs_vnode_param *vp = &op->file[0];
1402
struct afs_call *call;
1403
struct iattr *attr = op->setattr.attr;
1404
__be32 *bp;
1405
1406
_enter(",%x,{%llx:%llu},,",
1407
key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1408
1409
call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64_as_Status,
1410
sizeof(__be32) * 2 +
1411
sizeof(struct yfs_xdr_YFSFid) +
1412
sizeof(struct yfs_xdr_YFSStoreStatus) +
1413
sizeof(struct yfs_xdr_u64) * 3,
1414
sizeof(struct yfs_xdr_YFSFetchStatus) +
1415
sizeof(struct yfs_xdr_YFSVolSync));
1416
if (!call)
1417
return afs_op_nomem(op);
1418
1419
/* marshall the parameters */
1420
bp = call->request;
1421
bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1422
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1423
bp = xdr_encode_YFSFid(bp, &vp->fid);
1424
bp = xdr_encode_YFS_StoreStatus(bp, attr);
1425
bp = xdr_encode_u64(bp, attr->ia_size); /* position of start of write */
1426
bp = xdr_encode_u64(bp, 0); /* size of write */
1427
bp = xdr_encode_u64(bp, attr->ia_size); /* new file length */
1428
yfs_check_req(call, bp);
1429
1430
call->fid = vp->fid;
1431
trace_afs_make_fs_call(call, &vp->fid);
1432
afs_make_op_call(op, call, GFP_NOFS);
1433
}
1434
1435
/*
1436
* Set the attributes on a file, using YFS.StoreData64 if there's a change in
1437
* file size, and YFS.StoreStatus otherwise.
1438
*/
1439
void yfs_fs_setattr(struct afs_operation *op)
1440
{
1441
struct afs_vnode_param *vp = &op->file[0];
1442
struct afs_call *call;
1443
struct iattr *attr = op->setattr.attr;
1444
__be32 *bp;
1445
1446
if (attr->ia_valid & ATTR_SIZE)
1447
return yfs_fs_setattr_size(op);
1448
1449
_enter(",%x,{%llx:%llu},,",
1450
key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1451
1452
call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreStatus,
1453
sizeof(__be32) * 2 +
1454
sizeof(struct yfs_xdr_YFSFid) +
1455
sizeof(struct yfs_xdr_YFSStoreStatus),
1456
sizeof(struct yfs_xdr_YFSFetchStatus) +
1457
sizeof(struct yfs_xdr_YFSVolSync));
1458
if (!call)
1459
return afs_op_nomem(op);
1460
1461
/* marshall the parameters */
1462
bp = call->request;
1463
bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1464
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1465
bp = xdr_encode_YFSFid(bp, &vp->fid);
1466
bp = xdr_encode_YFS_StoreStatus(bp, attr);
1467
yfs_check_req(call, bp);
1468
1469
call->fid = vp->fid;
1470
trace_afs_make_fs_call(call, &vp->fid);
1471
afs_make_op_call(op, call, GFP_NOFS);
1472
}
1473
1474
/*
1475
* Deliver reply data to a YFS.GetVolumeStatus operation.
1476
*/
1477
static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1478
{
1479
struct afs_operation *op = call->op;
1480
const __be32 *bp;
1481
char *p;
1482
u32 size;
1483
int ret;
1484
1485
_enter("{%u}", call->unmarshall);
1486
1487
switch (call->unmarshall) {
1488
case 0:
1489
call->unmarshall++;
1490
afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1491
fallthrough;
1492
1493
/* extract the returned status record */
1494
case 1:
1495
_debug("extract status");
1496
ret = afs_extract_data(call, true);
1497
if (ret < 0)
1498
return ret;
1499
1500
bp = call->buffer;
1501
xdr_decode_YFSFetchVolumeStatus(&bp, &op->volstatus.vs);
1502
call->unmarshall++;
1503
afs_extract_to_tmp(call);
1504
fallthrough;
1505
1506
/* extract the volume name length */
1507
case 2:
1508
ret = afs_extract_data(call, true);
1509
if (ret < 0)
1510
return ret;
1511
1512
call->count = ntohl(call->tmp);
1513
_debug("volname length: %u", call->count);
1514
if (call->count >= AFSNAMEMAX)
1515
return afs_protocol_error(call, afs_eproto_volname_len);
1516
size = (call->count + 3) & ~3; /* It's padded */
1517
afs_extract_to_buf(call, size);
1518
call->unmarshall++;
1519
fallthrough;
1520
1521
/* extract the volume name */
1522
case 3:
1523
_debug("extract volname");
1524
ret = afs_extract_data(call, true);
1525
if (ret < 0)
1526
return ret;
1527
1528
p = call->buffer;
1529
p[call->count] = 0;
1530
_debug("volname '%s'", p);
1531
afs_extract_to_tmp(call);
1532
call->unmarshall++;
1533
fallthrough;
1534
1535
/* extract the offline message length */
1536
case 4:
1537
ret = afs_extract_data(call, true);
1538
if (ret < 0)
1539
return ret;
1540
1541
call->count = ntohl(call->tmp);
1542
_debug("offline msg length: %u", call->count);
1543
if (call->count >= AFSNAMEMAX)
1544
return afs_protocol_error(call, afs_eproto_offline_msg_len);
1545
size = (call->count + 3) & ~3; /* It's padded */
1546
afs_extract_to_buf(call, size);
1547
call->unmarshall++;
1548
fallthrough;
1549
1550
/* extract the offline message */
1551
case 5:
1552
_debug("extract offline");
1553
ret = afs_extract_data(call, true);
1554
if (ret < 0)
1555
return ret;
1556
1557
p = call->buffer;
1558
p[call->count] = 0;
1559
_debug("offline '%s'", p);
1560
1561
afs_extract_to_tmp(call);
1562
call->unmarshall++;
1563
fallthrough;
1564
1565
/* extract the message of the day length */
1566
case 6:
1567
ret = afs_extract_data(call, true);
1568
if (ret < 0)
1569
return ret;
1570
1571
call->count = ntohl(call->tmp);
1572
_debug("motd length: %u", call->count);
1573
if (call->count >= AFSNAMEMAX)
1574
return afs_protocol_error(call, afs_eproto_motd_len);
1575
size = (call->count + 3) & ~3; /* It's padded */
1576
afs_extract_to_buf(call, size);
1577
call->unmarshall++;
1578
fallthrough;
1579
1580
/* extract the message of the day */
1581
case 7:
1582
_debug("extract motd");
1583
ret = afs_extract_data(call, false);
1584
if (ret < 0)
1585
return ret;
1586
1587
p = call->buffer;
1588
p[call->count] = 0;
1589
_debug("motd '%s'", p);
1590
1591
call->unmarshall++;
1592
fallthrough;
1593
1594
case 8:
1595
break;
1596
}
1597
1598
_leave(" = 0 [done]");
1599
return 0;
1600
}
1601
1602
/*
1603
* YFS.GetVolumeStatus operation type
1604
*/
1605
static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1606
.name = "YFS.GetVolumeStatus",
1607
.op = yfs_FS_GetVolumeStatus,
1608
.deliver = yfs_deliver_fs_get_volume_status,
1609
.destructor = afs_flat_call_destructor,
1610
};
1611
1612
/*
1613
* fetch the status of a volume
1614
*/
1615
void yfs_fs_get_volume_status(struct afs_operation *op)
1616
{
1617
struct afs_vnode_param *vp = &op->file[0];
1618
struct afs_call *call;
1619
__be32 *bp;
1620
1621
_enter("");
1622
1623
call = afs_alloc_flat_call(op->net, &yfs_RXYFSGetVolumeStatus,
1624
sizeof(__be32) * 2 +
1625
sizeof(struct yfs_xdr_u64),
1626
max_t(size_t,
1627
sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1628
sizeof(__be32),
1629
AFSOPAQUEMAX + 1));
1630
if (!call)
1631
return afs_op_nomem(op);
1632
1633
/* marshall the parameters */
1634
bp = call->request;
1635
bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1636
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1637
bp = xdr_encode_u64(bp, vp->fid.vid);
1638
yfs_check_req(call, bp);
1639
1640
call->fid = vp->fid;
1641
trace_afs_make_fs_call(call, &vp->fid);
1642
afs_make_op_call(op, call, GFP_NOFS);
1643
}
1644
1645
/*
1646
* YFS.SetLock operation type
1647
*/
1648
static const struct afs_call_type yfs_RXYFSSetLock = {
1649
.name = "YFS.SetLock",
1650
.op = yfs_FS_SetLock,
1651
.deliver = yfs_deliver_status_and_volsync,
1652
.done = afs_lock_op_done,
1653
.destructor = afs_flat_call_destructor,
1654
};
1655
1656
/*
1657
* YFS.ExtendLock operation type
1658
*/
1659
static const struct afs_call_type yfs_RXYFSExtendLock = {
1660
.name = "YFS.ExtendLock",
1661
.op = yfs_FS_ExtendLock,
1662
.deliver = yfs_deliver_status_and_volsync,
1663
.done = afs_lock_op_done,
1664
.destructor = afs_flat_call_destructor,
1665
};
1666
1667
/*
1668
* YFS.ReleaseLock operation type
1669
*/
1670
static const struct afs_call_type yfs_RXYFSReleaseLock = {
1671
.name = "YFS.ReleaseLock",
1672
.op = yfs_FS_ReleaseLock,
1673
.deliver = yfs_deliver_status_and_volsync,
1674
.destructor = afs_flat_call_destructor,
1675
};
1676
1677
/*
1678
* Set a lock on a file
1679
*/
1680
void yfs_fs_set_lock(struct afs_operation *op)
1681
{
1682
struct afs_vnode_param *vp = &op->file[0];
1683
struct afs_call *call;
1684
__be32 *bp;
1685
1686
_enter("");
1687
1688
call = afs_alloc_flat_call(op->net, &yfs_RXYFSSetLock,
1689
sizeof(__be32) * 2 +
1690
sizeof(struct yfs_xdr_YFSFid) +
1691
sizeof(__be32),
1692
sizeof(struct yfs_xdr_YFSFetchStatus) +
1693
sizeof(struct yfs_xdr_YFSVolSync));
1694
if (!call)
1695
return afs_op_nomem(op);
1696
1697
/* marshall the parameters */
1698
bp = call->request;
1699
bp = xdr_encode_u32(bp, YFSSETLOCK);
1700
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1701
bp = xdr_encode_YFSFid(bp, &vp->fid);
1702
bp = xdr_encode_u32(bp, op->lock.type);
1703
yfs_check_req(call, bp);
1704
1705
call->fid = vp->fid;
1706
trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);
1707
afs_make_op_call(op, call, GFP_NOFS);
1708
}
1709
1710
/*
1711
* extend a lock on a file
1712
*/
1713
void yfs_fs_extend_lock(struct afs_operation *op)
1714
{
1715
struct afs_vnode_param *vp = &op->file[0];
1716
struct afs_call *call;
1717
__be32 *bp;
1718
1719
_enter("");
1720
1721
call = afs_alloc_flat_call(op->net, &yfs_RXYFSExtendLock,
1722
sizeof(__be32) * 2 +
1723
sizeof(struct yfs_xdr_YFSFid),
1724
sizeof(struct yfs_xdr_YFSFetchStatus) +
1725
sizeof(struct yfs_xdr_YFSVolSync));
1726
if (!call)
1727
return afs_op_nomem(op);
1728
1729
/* marshall the parameters */
1730
bp = call->request;
1731
bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1732
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1733
bp = xdr_encode_YFSFid(bp, &vp->fid);
1734
yfs_check_req(call, bp);
1735
1736
call->fid = vp->fid;
1737
trace_afs_make_fs_call(call, &vp->fid);
1738
afs_make_op_call(op, call, GFP_NOFS);
1739
}
1740
1741
/*
1742
* release a lock on a file
1743
*/
1744
void yfs_fs_release_lock(struct afs_operation *op)
1745
{
1746
struct afs_vnode_param *vp = &op->file[0];
1747
struct afs_call *call;
1748
__be32 *bp;
1749
1750
_enter("");
1751
1752
call = afs_alloc_flat_call(op->net, &yfs_RXYFSReleaseLock,
1753
sizeof(__be32) * 2 +
1754
sizeof(struct yfs_xdr_YFSFid),
1755
sizeof(struct yfs_xdr_YFSFetchStatus) +
1756
sizeof(struct yfs_xdr_YFSVolSync));
1757
if (!call)
1758
return afs_op_nomem(op);
1759
1760
/* marshall the parameters */
1761
bp = call->request;
1762
bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1763
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1764
bp = xdr_encode_YFSFid(bp, &vp->fid);
1765
yfs_check_req(call, bp);
1766
1767
call->fid = vp->fid;
1768
trace_afs_make_fs_call(call, &vp->fid);
1769
afs_make_op_call(op, call, GFP_NOFS);
1770
}
1771
1772
/*
1773
* Deliver a reply to YFS.FetchStatus
1774
*/
1775
static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1776
{
1777
struct afs_operation *op = call->op;
1778
struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1779
const __be32 *bp;
1780
int ret;
1781
1782
ret = afs_transfer_reply(call);
1783
if (ret < 0)
1784
return ret;
1785
1786
/* unmarshall the reply once we've received all of it */
1787
bp = call->buffer;
1788
xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
1789
xdr_decode_YFSCallBack(&bp, call, &vp->scb);
1790
xdr_decode_YFSVolSync(&bp, &op->volsync);
1791
1792
_leave(" = 0 [done]");
1793
return 0;
1794
}
1795
1796
/*
1797
* YFS.FetchStatus operation type
1798
*/
1799
static const struct afs_call_type yfs_RXYFSFetchStatus = {
1800
.name = "YFS.FetchStatus",
1801
.op = yfs_FS_FetchStatus,
1802
.deliver = yfs_deliver_fs_fetch_status,
1803
.destructor = afs_flat_call_destructor,
1804
};
1805
1806
/*
1807
* Fetch the status information for a fid without needing a vnode handle.
1808
*/
1809
void yfs_fs_fetch_status(struct afs_operation *op)
1810
{
1811
struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1812
struct afs_call *call;
1813
__be32 *bp;
1814
1815
_enter(",%x,{%llx:%llu},,",
1816
key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1817
1818
call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus,
1819
sizeof(__be32) * 2 +
1820
sizeof(struct yfs_xdr_YFSFid),
1821
sizeof(struct yfs_xdr_YFSFetchStatus) +
1822
sizeof(struct yfs_xdr_YFSCallBack) +
1823
sizeof(struct yfs_xdr_YFSVolSync));
1824
if (!call)
1825
return afs_op_nomem(op);
1826
1827
/* marshall the parameters */
1828
bp = call->request;
1829
bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1830
bp = xdr_encode_u32(bp, 0); /* RPC flags */
1831
bp = xdr_encode_YFSFid(bp, &vp->fid);
1832
yfs_check_req(call, bp);
1833
1834
call->fid = vp->fid;
1835
trace_afs_make_fs_call(call, &vp->fid);
1836
afs_make_op_call(op, call, GFP_NOFS);
1837
}
1838
1839
/*
1840
* Deliver reply data to an YFS.InlineBulkStatus call
1841
*/
1842
static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1843
{
1844
struct afs_operation *op = call->op;
1845
struct afs_status_cb *scb;
1846
const __be32 *bp;
1847
u32 tmp;
1848
int ret;
1849
1850
_enter("{%u}", call->unmarshall);
1851
1852
switch (call->unmarshall) {
1853
case 0:
1854
afs_extract_to_tmp(call);
1855
call->unmarshall++;
1856
fallthrough;
1857
1858
/* Extract the file status count and array in two steps */
1859
case 1:
1860
_debug("extract status count");
1861
ret = afs_extract_data(call, true);
1862
if (ret < 0)
1863
return ret;
1864
1865
tmp = ntohl(call->tmp);
1866
_debug("status count: %u/%u", tmp, op->nr_files);
1867
if (tmp != op->nr_files)
1868
return afs_protocol_error(call, afs_eproto_ibulkst_count);
1869
1870
call->count = 0;
1871
call->unmarshall++;
1872
more_counts:
1873
afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1874
fallthrough;
1875
1876
case 2:
1877
_debug("extract status array %u", call->count);
1878
ret = afs_extract_data(call, true);
1879
if (ret < 0)
1880
return ret;
1881
1882
switch (call->count) {
1883
case 0:
1884
scb = &op->file[0].scb;
1885
break;
1886
case 1:
1887
scb = &op->file[1].scb;
1888
break;
1889
default:
1890
scb = &op->more_files[call->count - 2].scb;
1891
break;
1892
}
1893
1894
bp = call->buffer;
1895
xdr_decode_YFSFetchStatus(&bp, call, scb);
1896
1897
call->count++;
1898
if (call->count < op->nr_files)
1899
goto more_counts;
1900
1901
call->count = 0;
1902
call->unmarshall++;
1903
afs_extract_to_tmp(call);
1904
fallthrough;
1905
1906
/* Extract the callback count and array in two steps */
1907
case 3:
1908
_debug("extract CB count");
1909
ret = afs_extract_data(call, true);
1910
if (ret < 0)
1911
return ret;
1912
1913
tmp = ntohl(call->tmp);
1914
_debug("CB count: %u", tmp);
1915
if (tmp != op->nr_files)
1916
return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
1917
call->count = 0;
1918
call->unmarshall++;
1919
more_cbs:
1920
afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1921
fallthrough;
1922
1923
case 4:
1924
_debug("extract CB array");
1925
ret = afs_extract_data(call, true);
1926
if (ret < 0)
1927
return ret;
1928
1929
_debug("unmarshall CB array");
1930
switch (call->count) {
1931
case 0:
1932
scb = &op->file[0].scb;
1933
break;
1934
case 1:
1935
scb = &op->file[1].scb;
1936
break;
1937
default:
1938
scb = &op->more_files[call->count - 2].scb;
1939
break;
1940
}
1941
1942
bp = call->buffer;
1943
xdr_decode_YFSCallBack(&bp, call, scb);
1944
call->count++;
1945
if (call->count < op->nr_files)
1946
goto more_cbs;
1947
1948
afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1949
call->unmarshall++;
1950
fallthrough;
1951
1952
case 5:
1953
ret = afs_extract_data(call, false);
1954
if (ret < 0)
1955
return ret;
1956
1957
bp = call->buffer;
1958
xdr_decode_YFSVolSync(&bp, &op->volsync);
1959
1960
call->unmarshall++;
1961
fallthrough;
1962
1963
case 6:
1964
break;
1965
}
1966
1967
_leave(" = 0 [done]");
1968
return 0;
1969
}
1970
1971
/*
1972
* FS.InlineBulkStatus operation type
1973
*/
1974
static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1975
.name = "YFS.InlineBulkStatus",
1976
.op = yfs_FS_InlineBulkStatus,
1977
.deliver = yfs_deliver_fs_inline_bulk_status,
1978
.destructor = afs_flat_call_destructor,
1979
};
1980
1981
/*
1982
* Fetch the status information for up to 1024 files
1983
*/
1984
void yfs_fs_inline_bulk_status(struct afs_operation *op)
1985
{
1986
struct afs_vnode_param *dvp = &op->file[0];
1987
struct afs_vnode_param *vp = &op->file[1];
1988
struct afs_call *call;
1989
__be32 *bp;
1990
int i;
1991
1992
_enter(",%x,{%llx:%llu},%u",
1993
key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);
1994
1995
call = afs_alloc_flat_call(op->net, &yfs_RXYFSInlineBulkStatus,
1996
sizeof(__be32) +
1997
sizeof(__be32) +
1998
sizeof(__be32) +
1999
sizeof(struct yfs_xdr_YFSFid) * op->nr_files,
2000
sizeof(struct yfs_xdr_YFSFetchStatus));
2001
if (!call)
2002
return afs_op_nomem(op);
2003
2004
/* marshall the parameters */
2005
bp = call->request;
2006
bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
2007
bp = xdr_encode_u32(bp, 0); /* RPCFlags */
2008
bp = xdr_encode_u32(bp, op->nr_files);
2009
bp = xdr_encode_YFSFid(bp, &dvp->fid);
2010
bp = xdr_encode_YFSFid(bp, &vp->fid);
2011
for (i = 0; i < op->nr_files - 2; i++)
2012
bp = xdr_encode_YFSFid(bp, &op->more_files[i].fid);
2013
yfs_check_req(call, bp);
2014
2015
call->fid = vp->fid;
2016
trace_afs_make_fs_call(call, &vp->fid);
2017
afs_make_op_call(op, call, GFP_NOFS);
2018
}
2019
2020
/*
2021
* Deliver reply data to an YFS.FetchOpaqueACL.
2022
*/
2023
static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
2024
{
2025
struct afs_operation *op = call->op;
2026
struct afs_vnode_param *vp = &op->file[0];
2027
struct yfs_acl *yacl = op->yacl;
2028
struct afs_acl *acl;
2029
const __be32 *bp;
2030
unsigned int size;
2031
int ret;
2032
2033
_enter("{%u}", call->unmarshall);
2034
2035
switch (call->unmarshall) {
2036
case 0:
2037
afs_extract_to_tmp(call);
2038
call->unmarshall++;
2039
fallthrough;
2040
2041
/* Extract the file ACL length */
2042
case 1:
2043
ret = afs_extract_data(call, true);
2044
if (ret < 0)
2045
return ret;
2046
2047
size = call->count2 = ntohl(call->tmp);
2048
size = round_up(size, 4);
2049
2050
if (yacl->flags & YFS_ACL_WANT_ACL) {
2051
acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2052
if (!acl)
2053
return -ENOMEM;
2054
yacl->acl = acl;
2055
acl->size = call->count2;
2056
afs_extract_begin(call, acl->data, size);
2057
} else {
2058
afs_extract_discard(call, size);
2059
}
2060
call->unmarshall++;
2061
fallthrough;
2062
2063
/* Extract the file ACL */
2064
case 2:
2065
ret = afs_extract_data(call, true);
2066
if (ret < 0)
2067
return ret;
2068
2069
afs_extract_to_tmp(call);
2070
call->unmarshall++;
2071
fallthrough;
2072
2073
/* Extract the volume ACL length */
2074
case 3:
2075
ret = afs_extract_data(call, true);
2076
if (ret < 0)
2077
return ret;
2078
2079
size = call->count2 = ntohl(call->tmp);
2080
size = round_up(size, 4);
2081
2082
if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2083
acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2084
if (!acl)
2085
return -ENOMEM;
2086
yacl->vol_acl = acl;
2087
acl->size = call->count2;
2088
afs_extract_begin(call, acl->data, size);
2089
} else {
2090
afs_extract_discard(call, size);
2091
}
2092
call->unmarshall++;
2093
fallthrough;
2094
2095
/* Extract the volume ACL */
2096
case 4:
2097
ret = afs_extract_data(call, true);
2098
if (ret < 0)
2099
return ret;
2100
2101
afs_extract_to_buf(call,
2102
sizeof(__be32) * 2 +
2103
sizeof(struct yfs_xdr_YFSFetchStatus) +
2104
sizeof(struct yfs_xdr_YFSVolSync));
2105
call->unmarshall++;
2106
fallthrough;
2107
2108
/* extract the metadata */
2109
case 5:
2110
ret = afs_extract_data(call, false);
2111
if (ret < 0)
2112
return ret;
2113
2114
bp = call->buffer;
2115
yacl->inherit_flag = ntohl(*bp++);
2116
yacl->num_cleaned = ntohl(*bp++);
2117
xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
2118
xdr_decode_YFSVolSync(&bp, &op->volsync);
2119
2120
call->unmarshall++;
2121
fallthrough;
2122
2123
case 6:
2124
break;
2125
}
2126
2127
_leave(" = 0 [done]");
2128
return 0;
2129
}
2130
2131
void yfs_free_opaque_acl(struct yfs_acl *yacl)
2132
{
2133
if (yacl) {
2134
kfree(yacl->acl);
2135
kfree(yacl->vol_acl);
2136
kfree(yacl);
2137
}
2138
}
2139
2140
/*
2141
* YFS.FetchOpaqueACL operation type
2142
*/
2143
static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2144
.name = "YFS.FetchOpaqueACL",
2145
.op = yfs_FS_FetchOpaqueACL,
2146
.deliver = yfs_deliver_fs_fetch_opaque_acl,
2147
.destructor = afs_flat_call_destructor,
2148
};
2149
2150
/*
2151
* Fetch the YFS advanced ACLs for a file.
2152
*/
2153
void yfs_fs_fetch_opaque_acl(struct afs_operation *op)
2154
{
2155
struct afs_vnode_param *vp = &op->file[0];
2156
struct afs_call *call;
2157
__be32 *bp;
2158
2159
_enter(",%x,{%llx:%llu},,",
2160
key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2161
2162
call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchOpaqueACL,
2163
sizeof(__be32) * 2 +
2164
sizeof(struct yfs_xdr_YFSFid),
2165
sizeof(__be32) * 2 +
2166
sizeof(struct yfs_xdr_YFSFetchStatus) +
2167
sizeof(struct yfs_xdr_YFSVolSync));
2168
if (!call)
2169
return afs_op_nomem(op);
2170
2171
/* marshall the parameters */
2172
bp = call->request;
2173
bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2174
bp = xdr_encode_u32(bp, 0); /* RPC flags */
2175
bp = xdr_encode_YFSFid(bp, &vp->fid);
2176
yfs_check_req(call, bp);
2177
2178
call->fid = vp->fid;
2179
trace_afs_make_fs_call(call, &vp->fid);
2180
afs_make_op_call(op, call, GFP_KERNEL);
2181
}
2182
2183
/*
2184
* YFS.StoreOpaqueACL2 operation type
2185
*/
2186
static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2187
.name = "YFS.StoreOpaqueACL2",
2188
.op = yfs_FS_StoreOpaqueACL2,
2189
.deliver = yfs_deliver_status_and_volsync,
2190
.destructor = afs_flat_call_destructor,
2191
};
2192
2193
/*
2194
* Fetch the YFS ACL for a file.
2195
*/
2196
void yfs_fs_store_opaque_acl2(struct afs_operation *op)
2197
{
2198
struct afs_vnode_param *vp = &op->file[0];
2199
struct afs_call *call;
2200
struct afs_acl *acl = op->acl;
2201
size_t size;
2202
__be32 *bp;
2203
2204
_enter(",%x,{%llx:%llu},,",
2205
key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2206
2207
size = round_up(acl->size, 4);
2208
call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreOpaqueACL2,
2209
sizeof(__be32) * 2 +
2210
sizeof(struct yfs_xdr_YFSFid) +
2211
sizeof(__be32) + size,
2212
sizeof(struct yfs_xdr_YFSFetchStatus) +
2213
sizeof(struct yfs_xdr_YFSVolSync));
2214
if (!call)
2215
return afs_op_nomem(op);
2216
2217
/* marshall the parameters */
2218
bp = call->request;
2219
bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2220
bp = xdr_encode_u32(bp, 0); /* RPC flags */
2221
bp = xdr_encode_YFSFid(bp, &vp->fid);
2222
bp = xdr_encode_u32(bp, acl->size);
2223
memcpy(bp, acl->data, acl->size);
2224
if (acl->size != size)
2225
memset((void *)bp + acl->size, 0, size - acl->size);
2226
bp += size / sizeof(__be32);
2227
yfs_check_req(call, bp);
2228
2229
call->fid = vp->fid;
2230
trace_afs_make_fs_call(call, &vp->fid);
2231
afs_make_op_call(op, call, GFP_KERNEL);
2232
}
2233
2234