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 #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