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