2131 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* AFS File Server client stubs3 *4 * Copyright (C) 2002, 2007 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 <linux/netfs.h>14#include "internal.h"15#include "afs_fs.h"16#include "xdr_fs.h"17 18/*19 * decode an AFSFid block20 */21static void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid)22{23 const __be32 *bp = *_bp;24 25 fid->vid = ntohl(*bp++);26 fid->vnode = ntohl(*bp++);27 fid->unique = ntohl(*bp++);28 *_bp = bp;29}30 31/*32 * Dump a bad file status record.33 */34static void xdr_dump_bad(const __be32 *bp)35{36 __be32 x[4];37 int i;38 39 pr_notice("AFS XDR: Bad status record\n");40 for (i = 0; i < 5 * 4 * 4; i += 16) {41 memcpy(x, bp, 16);42 bp += 4;43 pr_notice("%03x: %08x %08x %08x %08x\n",44 i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3]));45 }46 47 memcpy(x, bp, 4);48 pr_notice("0x50: %08x\n", ntohl(x[0]));49}50 51/*52 * decode an AFSFetchStatus block53 */54static void xdr_decode_AFSFetchStatus(const __be32 **_bp,55 struct afs_call *call,56 struct afs_status_cb *scb)57{58 const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;59 struct afs_file_status *status = &scb->status;60 bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);61 u64 data_version, size;62 u32 type, abort_code;63 64 abort_code = ntohl(xdr->abort_code);65 66 if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {67 if (xdr->if_version == htonl(0) &&68 abort_code != 0 &&69 inline_error) {70 /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus71 * whereby it doesn't set the interface version in the error72 * case.73 */74 status->abort_code = abort_code;75 scb->have_error = true;76 goto advance;77 }78 79 pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));80 goto bad;81 }82 83 if (abort_code != 0 && inline_error) {84 status->abort_code = abort_code;85 scb->have_error = true;86 goto advance;87 }88 89 type = ntohl(xdr->type);90 switch (type) {91 case AFS_FTYPE_FILE:92 case AFS_FTYPE_DIR:93 case AFS_FTYPE_SYMLINK:94 status->type = type;95 break;96 default:97 goto bad;98 }99 100 status->nlink = ntohl(xdr->nlink);101 status->author = ntohl(xdr->author);102 status->owner = ntohl(xdr->owner);103 status->caller_access = ntohl(xdr->caller_access); /* Ticket dependent */104 status->anon_access = ntohl(xdr->anon_access);105 status->mode = ntohl(xdr->mode) & S_IALLUGO;106 status->group = ntohl(xdr->group);107 status->lock_count = ntohl(xdr->lock_count);108 109 status->mtime_client.tv_sec = ntohl(xdr->mtime_client);110 status->mtime_client.tv_nsec = 0;111 status->mtime_server.tv_sec = ntohl(xdr->mtime_server);112 status->mtime_server.tv_nsec = 0;113 114 size = (u64)ntohl(xdr->size_lo);115 size |= (u64)ntohl(xdr->size_hi) << 32;116 status->size = size;117 118 data_version = (u64)ntohl(xdr->data_version_lo);119 data_version |= (u64)ntohl(xdr->data_version_hi) << 32;120 status->data_version = data_version;121 scb->have_status = true;122advance:123 *_bp = (const void *)*_bp + sizeof(*xdr);124 return;125 126bad:127 xdr_dump_bad(*_bp);128 afs_protocol_error(call, afs_eproto_bad_status);129 goto advance;130}131 132static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry)133{134 return ktime_divns(call->issue_time, NSEC_PER_SEC) + expiry;135}136 137static void xdr_decode_AFSCallBack(const __be32 **_bp,138 struct afs_call *call,139 struct afs_status_cb *scb)140{141 struct afs_callback *cb = &scb->callback;142 const __be32 *bp = *_bp;143 144 bp++; /* version */145 cb->expires_at = xdr_decode_expiry(call, ntohl(*bp++));146 bp++; /* type */147 scb->have_cb = true;148 *_bp = bp;149}150 151/*152 * decode an AFSVolSync block153 */154static void xdr_decode_AFSVolSync(const __be32 **_bp,155 struct afs_volsync *volsync)156{157 const __be32 *bp = *_bp;158 u32 creation;159 160 creation = ntohl(*bp++);161 bp++; /* spare2 */162 bp++; /* spare3 */163 bp++; /* spare4 */164 bp++; /* spare5 */165 bp++; /* spare6 */166 *_bp = bp;167 168 if (volsync)169 volsync->creation = creation;170}171 172/*173 * encode the requested attributes into an AFSStoreStatus block174 */175static void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr)176{177 __be32 *bp = *_bp;178 u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0;179 180 mask = 0;181 if (attr->ia_valid & ATTR_MTIME) {182 mask |= AFS_SET_MTIME;183 mtime = attr->ia_mtime.tv_sec;184 }185 186 if (attr->ia_valid & ATTR_UID) {187 mask |= AFS_SET_OWNER;188 owner = from_kuid(&init_user_ns, attr->ia_uid);189 }190 191 if (attr->ia_valid & ATTR_GID) {192 mask |= AFS_SET_GROUP;193 group = from_kgid(&init_user_ns, attr->ia_gid);194 }195 196 if (attr->ia_valid & ATTR_MODE) {197 mask |= AFS_SET_MODE;198 mode = attr->ia_mode & S_IALLUGO;199 }200 201 *bp++ = htonl(mask);202 *bp++ = htonl(mtime);203 *bp++ = htonl(owner);204 *bp++ = htonl(group);205 *bp++ = htonl(mode);206 *bp++ = 0; /* segment size */207 *_bp = bp;208}209 210/*211 * decode an AFSFetchVolumeStatus block212 */213static void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp,214 struct afs_volume_status *vs)215{216 const __be32 *bp = *_bp;217 218 vs->vid = ntohl(*bp++);219 vs->parent_id = ntohl(*bp++);220 vs->online = ntohl(*bp++);221 vs->in_service = ntohl(*bp++);222 vs->blessed = ntohl(*bp++);223 vs->needs_salvage = ntohl(*bp++);224 vs->type = ntohl(*bp++);225 vs->min_quota = ntohl(*bp++);226 vs->max_quota = ntohl(*bp++);227 vs->blocks_in_use = ntohl(*bp++);228 vs->part_blocks_avail = ntohl(*bp++);229 vs->part_max_blocks = ntohl(*bp++);230 vs->vol_copy_date = 0;231 vs->vol_backup_date = 0;232 *_bp = bp;233}234 235/*236 * deliver reply data to an FS.FetchStatus237 */238static int afs_deliver_fs_fetch_status(struct afs_call *call)239{240 struct afs_operation *op = call->op;241 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];242 const __be32 *bp;243 int ret;244 245 ret = afs_transfer_reply(call);246 if (ret < 0)247 return ret;248 249 /* unmarshall the reply once we've received all of it */250 bp = call->buffer;251 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);252 xdr_decode_AFSCallBack(&bp, call, &vp->scb);253 xdr_decode_AFSVolSync(&bp, &op->volsync);254 255 _leave(" = 0 [done]");256 return 0;257}258 259/*260 * FS.FetchStatus operation type261 */262static const struct afs_call_type afs_RXFSFetchStatus = {263 .name = "FS.FetchStatus",264 .op = afs_FS_FetchStatus,265 .deliver = afs_deliver_fs_fetch_status,266 .destructor = afs_flat_call_destructor,267};268 269/*270 * fetch the status information for a file271 */272void afs_fs_fetch_status(struct afs_operation *op)273{274 struct afs_vnode_param *vp = &op->file[op->fetch_status.which];275 struct afs_call *call;276 __be32 *bp;277 278 _enter(",%x,{%llx:%llu},,",279 key_serial(op->key), vp->fid.vid, vp->fid.vnode);280 281 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchStatus,282 16, (21 + 3 + 6) * 4);283 if (!call)284 return afs_op_nomem(op);285 286 /* marshall the parameters */287 bp = call->request;288 bp[0] = htonl(FSFETCHSTATUS);289 bp[1] = htonl(vp->fid.vid);290 bp[2] = htonl(vp->fid.vnode);291 bp[3] = htonl(vp->fid.unique);292 293 call->fid = vp->fid;294 trace_afs_make_fs_call(call, &vp->fid);295 afs_make_op_call(op, call, GFP_NOFS);296}297 298/*299 * deliver reply data to an FS.FetchData300 */301static int afs_deliver_fs_fetch_data(struct afs_call *call)302{303 struct afs_operation *op = call->op;304 struct afs_vnode_param *vp = &op->file[0];305 struct afs_read *req = op->fetch.req;306 const __be32 *bp;307 size_t count_before;308 int ret;309 310 _enter("{%u,%zu,%zu/%llu}",311 call->unmarshall, call->iov_len, iov_iter_count(call->iter),312 req->actual_len);313 314 switch (call->unmarshall) {315 case 0:316 req->actual_len = 0;317 call->unmarshall++;318 if (call->operation_ID == FSFETCHDATA64) {319 afs_extract_to_tmp64(call);320 } else {321 call->tmp_u = htonl(0);322 afs_extract_to_tmp(call);323 }324 fallthrough;325 326 /* Extract the returned data length into327 * ->actual_len. This may indicate more or less data than was328 * requested will be returned.329 */330 case 1:331 _debug("extract data length");332 ret = afs_extract_data(call, true);333 if (ret < 0)334 return ret;335 336 req->actual_len = be64_to_cpu(call->tmp64);337 _debug("DATA length: %llu", req->actual_len);338 339 if (req->actual_len == 0)340 goto no_more_data;341 342 call->iter = req->iter;343 call->iov_len = min(req->actual_len, req->len);344 call->unmarshall++;345 fallthrough;346 347 /* extract the returned data */348 case 2:349 count_before = call->iov_len;350 _debug("extract data %zu/%llu", count_before, req->actual_len);351 352 ret = afs_extract_data(call, true);353 if (req->subreq) {354 req->subreq->transferred += count_before - call->iov_len;355 netfs_read_subreq_progress(req->subreq, false);356 }357 if (ret < 0)358 return ret;359 360 call->iter = &call->def_iter;361 if (req->actual_len <= req->len)362 goto no_more_data;363 364 /* Discard any excess data the server gave us */365 afs_extract_discard(call, req->actual_len - req->len);366 call->unmarshall = 3;367 fallthrough;368 369 case 3:370 _debug("extract discard %zu/%llu",371 iov_iter_count(call->iter), req->actual_len - req->len);372 373 ret = afs_extract_data(call, true);374 if (ret < 0)375 return ret;376 377 no_more_data:378 call->unmarshall = 4;379 afs_extract_to_buf(call, (21 + 3 + 6) * 4);380 fallthrough;381 382 /* extract the metadata */383 case 4:384 ret = afs_extract_data(call, false);385 if (ret < 0)386 return ret;387 388 bp = call->buffer;389 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);390 xdr_decode_AFSCallBack(&bp, call, &vp->scb);391 xdr_decode_AFSVolSync(&bp, &op->volsync);392 393 req->data_version = vp->scb.status.data_version;394 req->file_size = vp->scb.status.size;395 396 call->unmarshall++;397 fallthrough;398 399 case 5:400 break;401 }402 403 _leave(" = 0 [done]");404 return 0;405}406 407/*408 * FS.FetchData operation type409 */410static const struct afs_call_type afs_RXFSFetchData = {411 .name = "FS.FetchData",412 .op = afs_FS_FetchData,413 .deliver = afs_deliver_fs_fetch_data,414 .destructor = afs_flat_call_destructor,415};416 417static const struct afs_call_type afs_RXFSFetchData64 = {418 .name = "FS.FetchData64",419 .op = afs_FS_FetchData64,420 .deliver = afs_deliver_fs_fetch_data,421 .destructor = afs_flat_call_destructor,422};423 424/*425 * fetch data from a very large file426 */427static void afs_fs_fetch_data64(struct afs_operation *op)428{429 struct afs_vnode_param *vp = &op->file[0];430 struct afs_read *req = op->fetch.req;431 struct afs_call *call;432 __be32 *bp;433 434 _enter("");435 436 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4);437 if (!call)438 return afs_op_nomem(op);439 440 /* marshall the parameters */441 bp = call->request;442 bp[0] = htonl(FSFETCHDATA64);443 bp[1] = htonl(vp->fid.vid);444 bp[2] = htonl(vp->fid.vnode);445 bp[3] = htonl(vp->fid.unique);446 bp[4] = htonl(upper_32_bits(req->pos));447 bp[5] = htonl(lower_32_bits(req->pos));448 bp[6] = 0;449 bp[7] = htonl(lower_32_bits(req->len));450 451 call->fid = vp->fid;452 trace_afs_make_fs_call(call, &vp->fid);453 afs_make_op_call(op, call, GFP_NOFS);454}455 456/*457 * fetch data from a file458 */459void afs_fs_fetch_data(struct afs_operation *op)460{461 struct afs_vnode_param *vp = &op->file[0];462 struct afs_call *call;463 struct afs_read *req = op->fetch.req;464 __be32 *bp;465 466 if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))467 return afs_fs_fetch_data64(op);468 469 _enter("");470 471 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4);472 if (!call)473 return afs_op_nomem(op);474 475 req->call_debug_id = call->debug_id;476 477 /* marshall the parameters */478 bp = call->request;479 bp[0] = htonl(FSFETCHDATA);480 bp[1] = htonl(vp->fid.vid);481 bp[2] = htonl(vp->fid.vnode);482 bp[3] = htonl(vp->fid.unique);483 bp[4] = htonl(lower_32_bits(req->pos));484 bp[5] = htonl(lower_32_bits(req->len));485 486 call->fid = vp->fid;487 trace_afs_make_fs_call(call, &vp->fid);488 afs_make_op_call(op, call, GFP_NOFS);489}490 491/*492 * deliver reply data to an FS.CreateFile or an FS.MakeDir493 */494static int afs_deliver_fs_create_vnode(struct afs_call *call)495{496 struct afs_operation *op = call->op;497 struct afs_vnode_param *dvp = &op->file[0];498 struct afs_vnode_param *vp = &op->file[1];499 const __be32 *bp;500 int ret;501 502 ret = afs_transfer_reply(call);503 if (ret < 0)504 return ret;505 506 /* unmarshall the reply once we've received all of it */507 bp = call->buffer;508 xdr_decode_AFSFid(&bp, &op->file[1].fid);509 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);510 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);511 xdr_decode_AFSCallBack(&bp, call, &vp->scb);512 xdr_decode_AFSVolSync(&bp, &op->volsync);513 514 _leave(" = 0 [done]");515 return 0;516}517 518/*519 * FS.CreateFile and FS.MakeDir operation type520 */521static const struct afs_call_type afs_RXFSCreateFile = {522 .name = "FS.CreateFile",523 .op = afs_FS_CreateFile,524 .deliver = afs_deliver_fs_create_vnode,525 .destructor = afs_flat_call_destructor,526};527 528/*529 * Create a file.530 */531void afs_fs_create_file(struct afs_operation *op)532{533 const struct qstr *name = &op->dentry->d_name;534 struct afs_vnode_param *dvp = &op->file[0];535 struct afs_call *call;536 size_t namesz, reqsz, padsz;537 __be32 *bp;538 539 _enter("");540 541 namesz = name->len;542 padsz = (4 - (namesz & 3)) & 3;543 reqsz = (5 * 4) + namesz + padsz + (6 * 4);544 545 call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile,546 reqsz, (3 + 21 + 21 + 3 + 6) * 4);547 if (!call)548 return afs_op_nomem(op);549 550 /* marshall the parameters */551 bp = call->request;552 *bp++ = htonl(FSCREATEFILE);553 *bp++ = htonl(dvp->fid.vid);554 *bp++ = htonl(dvp->fid.vnode);555 *bp++ = htonl(dvp->fid.unique);556 *bp++ = htonl(namesz);557 memcpy(bp, name->name, namesz);558 bp = (void *) bp + namesz;559 if (padsz > 0) {560 memset(bp, 0, padsz);561 bp = (void *) bp + padsz;562 }563 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);564 *bp++ = htonl(op->mtime.tv_sec); /* mtime */565 *bp++ = 0; /* owner */566 *bp++ = 0; /* group */567 *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */568 *bp++ = 0; /* segment size */569 570 call->fid = dvp->fid;571 trace_afs_make_fs_call1(call, &dvp->fid, name);572 afs_make_op_call(op, call, GFP_NOFS);573}574 575static const struct afs_call_type afs_RXFSMakeDir = {576 .name = "FS.MakeDir",577 .op = afs_FS_MakeDir,578 .deliver = afs_deliver_fs_create_vnode,579 .destructor = afs_flat_call_destructor,580};581 582/*583 * Create a new directory584 */585void afs_fs_make_dir(struct afs_operation *op)586{587 const struct qstr *name = &op->dentry->d_name;588 struct afs_vnode_param *dvp = &op->file[0];589 struct afs_call *call;590 size_t namesz, reqsz, padsz;591 __be32 *bp;592 593 _enter("");594 595 namesz = name->len;596 padsz = (4 - (namesz & 3)) & 3;597 reqsz = (5 * 4) + namesz + padsz + (6 * 4);598 599 call = afs_alloc_flat_call(op->net, &afs_RXFSMakeDir,600 reqsz, (3 + 21 + 21 + 3 + 6) * 4);601 if (!call)602 return afs_op_nomem(op);603 604 /* marshall the parameters */605 bp = call->request;606 *bp++ = htonl(FSMAKEDIR);607 *bp++ = htonl(dvp->fid.vid);608 *bp++ = htonl(dvp->fid.vnode);609 *bp++ = htonl(dvp->fid.unique);610 *bp++ = htonl(namesz);611 memcpy(bp, name->name, namesz);612 bp = (void *) bp + namesz;613 if (padsz > 0) {614 memset(bp, 0, padsz);615 bp = (void *) bp + padsz;616 }617 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);618 *bp++ = htonl(op->mtime.tv_sec); /* mtime */619 *bp++ = 0; /* owner */620 *bp++ = 0; /* group */621 *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */622 *bp++ = 0; /* segment size */623 624 call->fid = dvp->fid;625 trace_afs_make_fs_call1(call, &dvp->fid, name);626 afs_make_op_call(op, call, GFP_NOFS);627}628 629/*630 * Deliver reply data to any operation that returns status and volume sync.631 */632static int afs_deliver_fs_file_status_and_vol(struct afs_call *call)633{634 struct afs_operation *op = call->op;635 struct afs_vnode_param *vp = &op->file[0];636 const __be32 *bp;637 int ret;638 639 ret = afs_transfer_reply(call);640 if (ret < 0)641 return ret;642 643 /* unmarshall the reply once we've received all of it */644 bp = call->buffer;645 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);646 xdr_decode_AFSVolSync(&bp, &op->volsync);647 648 _leave(" = 0 [done]");649 return 0;650}651 652/*653 * FS.RemoveFile operation type654 */655static const struct afs_call_type afs_RXFSRemoveFile = {656 .name = "FS.RemoveFile",657 .op = afs_FS_RemoveFile,658 .deliver = afs_deliver_fs_file_status_and_vol,659 .destructor = afs_flat_call_destructor,660};661 662/*663 * Remove a file.664 */665void afs_fs_remove_file(struct afs_operation *op)666{667 const struct qstr *name = &op->dentry->d_name;668 struct afs_vnode_param *dvp = &op->file[0];669 struct afs_call *call;670 size_t namesz, reqsz, padsz;671 __be32 *bp;672 673 _enter("");674 675 namesz = name->len;676 padsz = (4 - (namesz & 3)) & 3;677 reqsz = (5 * 4) + namesz + padsz;678 679 call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveFile,680 reqsz, (21 + 6) * 4);681 if (!call)682 return afs_op_nomem(op);683 684 /* marshall the parameters */685 bp = call->request;686 *bp++ = htonl(FSREMOVEFILE);687 *bp++ = htonl(dvp->fid.vid);688 *bp++ = htonl(dvp->fid.vnode);689 *bp++ = htonl(dvp->fid.unique);690 *bp++ = htonl(namesz);691 memcpy(bp, name->name, namesz);692 bp = (void *) bp + namesz;693 if (padsz > 0) {694 memset(bp, 0, padsz);695 bp = (void *) bp + padsz;696 }697 698 call->fid = dvp->fid;699 trace_afs_make_fs_call1(call, &dvp->fid, name);700 afs_make_op_call(op, call, GFP_NOFS);701}702 703static const struct afs_call_type afs_RXFSRemoveDir = {704 .name = "FS.RemoveDir",705 .op = afs_FS_RemoveDir,706 .deliver = afs_deliver_fs_file_status_and_vol,707 .destructor = afs_flat_call_destructor,708};709 710/*711 * Remove a directory.712 */713void afs_fs_remove_dir(struct afs_operation *op)714{715 const struct qstr *name = &op->dentry->d_name;716 struct afs_vnode_param *dvp = &op->file[0];717 struct afs_call *call;718 size_t namesz, reqsz, padsz;719 __be32 *bp;720 721 _enter("");722 723 namesz = name->len;724 padsz = (4 - (namesz & 3)) & 3;725 reqsz = (5 * 4) + namesz + padsz;726 727 call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveDir,728 reqsz, (21 + 6) * 4);729 if (!call)730 return afs_op_nomem(op);731 732 /* marshall the parameters */733 bp = call->request;734 *bp++ = htonl(FSREMOVEDIR);735 *bp++ = htonl(dvp->fid.vid);736 *bp++ = htonl(dvp->fid.vnode);737 *bp++ = htonl(dvp->fid.unique);738 *bp++ = htonl(namesz);739 memcpy(bp, name->name, namesz);740 bp = (void *) bp + namesz;741 if (padsz > 0) {742 memset(bp, 0, padsz);743 bp = (void *) bp + padsz;744 }745 746 call->fid = dvp->fid;747 trace_afs_make_fs_call1(call, &dvp->fid, name);748 afs_make_op_call(op, call, GFP_NOFS);749}750 751/*752 * deliver reply data to an FS.Link753 */754static int afs_deliver_fs_link(struct afs_call *call)755{756 struct afs_operation *op = call->op;757 struct afs_vnode_param *dvp = &op->file[0];758 struct afs_vnode_param *vp = &op->file[1];759 const __be32 *bp;760 int ret;761 762 _enter("{%u}", call->unmarshall);763 764 ret = afs_transfer_reply(call);765 if (ret < 0)766 return ret;767 768 /* unmarshall the reply once we've received all of it */769 bp = call->buffer;770 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);771 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);772 xdr_decode_AFSVolSync(&bp, &op->volsync);773 774 _leave(" = 0 [done]");775 return 0;776}777 778/*779 * FS.Link operation type780 */781static const struct afs_call_type afs_RXFSLink = {782 .name = "FS.Link",783 .op = afs_FS_Link,784 .deliver = afs_deliver_fs_link,785 .destructor = afs_flat_call_destructor,786};787 788/*789 * make a hard link790 */791void afs_fs_link(struct afs_operation *op)792{793 const struct qstr *name = &op->dentry->d_name;794 struct afs_vnode_param *dvp = &op->file[0];795 struct afs_vnode_param *vp = &op->file[1];796 struct afs_call *call;797 size_t namesz, reqsz, padsz;798 __be32 *bp;799 800 _enter("");801 802 namesz = name->len;803 padsz = (4 - (namesz & 3)) & 3;804 reqsz = (5 * 4) + namesz + padsz + (3 * 4);805 806 call = afs_alloc_flat_call(op->net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4);807 if (!call)808 return afs_op_nomem(op);809 810 /* marshall the parameters */811 bp = call->request;812 *bp++ = htonl(FSLINK);813 *bp++ = htonl(dvp->fid.vid);814 *bp++ = htonl(dvp->fid.vnode);815 *bp++ = htonl(dvp->fid.unique);816 *bp++ = htonl(namesz);817 memcpy(bp, name->name, namesz);818 bp = (void *) bp + namesz;819 if (padsz > 0) {820 memset(bp, 0, padsz);821 bp = (void *) bp + padsz;822 }823 *bp++ = htonl(vp->fid.vid);824 *bp++ = htonl(vp->fid.vnode);825 *bp++ = htonl(vp->fid.unique);826 827 call->fid = vp->fid;828 trace_afs_make_fs_call1(call, &vp->fid, name);829 afs_make_op_call(op, call, GFP_NOFS);830}831 832/*833 * deliver reply data to an FS.Symlink834 */835static int afs_deliver_fs_symlink(struct afs_call *call)836{837 struct afs_operation *op = call->op;838 struct afs_vnode_param *dvp = &op->file[0];839 struct afs_vnode_param *vp = &op->file[1];840 const __be32 *bp;841 int ret;842 843 _enter("{%u}", call->unmarshall);844 845 ret = afs_transfer_reply(call);846 if (ret < 0)847 return ret;848 849 /* unmarshall the reply once we've received all of it */850 bp = call->buffer;851 xdr_decode_AFSFid(&bp, &vp->fid);852 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);853 xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb);854 xdr_decode_AFSVolSync(&bp, &op->volsync);855 856 _leave(" = 0 [done]");857 return 0;858}859 860/*861 * FS.Symlink operation type862 */863static const struct afs_call_type afs_RXFSSymlink = {864 .name = "FS.Symlink",865 .op = afs_FS_Symlink,866 .deliver = afs_deliver_fs_symlink,867 .destructor = afs_flat_call_destructor,868};869 870/*871 * create a symbolic link872 */873void afs_fs_symlink(struct afs_operation *op)874{875 const struct qstr *name = &op->dentry->d_name;876 struct afs_vnode_param *dvp = &op->file[0];877 struct afs_call *call;878 size_t namesz, reqsz, padsz, c_namesz, c_padsz;879 __be32 *bp;880 881 _enter("");882 883 namesz = name->len;884 padsz = (4 - (namesz & 3)) & 3;885 886 c_namesz = strlen(op->create.symlink);887 c_padsz = (4 - (c_namesz & 3)) & 3;888 889 reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4);890 891 call = afs_alloc_flat_call(op->net, &afs_RXFSSymlink, reqsz,892 (3 + 21 + 21 + 6) * 4);893 if (!call)894 return afs_op_nomem(op);895 896 /* marshall the parameters */897 bp = call->request;898 *bp++ = htonl(FSSYMLINK);899 *bp++ = htonl(dvp->fid.vid);900 *bp++ = htonl(dvp->fid.vnode);901 *bp++ = htonl(dvp->fid.unique);902 *bp++ = htonl(namesz);903 memcpy(bp, name->name, namesz);904 bp = (void *) bp + namesz;905 if (padsz > 0) {906 memset(bp, 0, padsz);907 bp = (void *) bp + padsz;908 }909 *bp++ = htonl(c_namesz);910 memcpy(bp, op->create.symlink, c_namesz);911 bp = (void *) bp + c_namesz;912 if (c_padsz > 0) {913 memset(bp, 0, c_padsz);914 bp = (void *) bp + c_padsz;915 }916 *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME);917 *bp++ = htonl(op->mtime.tv_sec); /* mtime */918 *bp++ = 0; /* owner */919 *bp++ = 0; /* group */920 *bp++ = htonl(S_IRWXUGO); /* unix mode */921 *bp++ = 0; /* segment size */922 923 call->fid = dvp->fid;924 trace_afs_make_fs_call1(call, &dvp->fid, name);925 afs_make_op_call(op, call, GFP_NOFS);926}927 928/*929 * deliver reply data to an FS.Rename930 */931static int afs_deliver_fs_rename(struct afs_call *call)932{933 struct afs_operation *op = call->op;934 struct afs_vnode_param *orig_dvp = &op->file[0];935 struct afs_vnode_param *new_dvp = &op->file[1];936 const __be32 *bp;937 int ret;938 939 ret = afs_transfer_reply(call);940 if (ret < 0)941 return ret;942 943 bp = call->buffer;944 /* If the two dirs are the same, we have two copies of the same status945 * report, so we just decode it twice.946 */947 xdr_decode_AFSFetchStatus(&bp, call, &orig_dvp->scb);948 xdr_decode_AFSFetchStatus(&bp, call, &new_dvp->scb);949 xdr_decode_AFSVolSync(&bp, &op->volsync);950 951 _leave(" = 0 [done]");952 return 0;953}954 955/*956 * FS.Rename operation type957 */958static const struct afs_call_type afs_RXFSRename = {959 .name = "FS.Rename",960 .op = afs_FS_Rename,961 .deliver = afs_deliver_fs_rename,962 .destructor = afs_flat_call_destructor,963};964 965/*966 * Rename/move a file or directory.967 */968void afs_fs_rename(struct afs_operation *op)969{970 struct afs_vnode_param *orig_dvp = &op->file[0];971 struct afs_vnode_param *new_dvp = &op->file[1];972 const struct qstr *orig_name = &op->dentry->d_name;973 const struct qstr *new_name = &op->dentry_2->d_name;974 struct afs_call *call;975 size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz;976 __be32 *bp;977 978 _enter("");979 980 o_namesz = orig_name->len;981 o_padsz = (4 - (o_namesz & 3)) & 3;982 983 n_namesz = new_name->len;984 n_padsz = (4 - (n_namesz & 3)) & 3;985 986 reqsz = (4 * 4) +987 4 + o_namesz + o_padsz +988 (3 * 4) +989 4 + n_namesz + n_padsz;990 991 call = afs_alloc_flat_call(op->net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4);992 if (!call)993 return afs_op_nomem(op);994 995 /* marshall the parameters */996 bp = call->request;997 *bp++ = htonl(FSRENAME);998 *bp++ = htonl(orig_dvp->fid.vid);999 *bp++ = htonl(orig_dvp->fid.vnode);1000 *bp++ = htonl(orig_dvp->fid.unique);1001 *bp++ = htonl(o_namesz);1002 memcpy(bp, orig_name->name, o_namesz);1003 bp = (void *) bp + o_namesz;1004 if (o_padsz > 0) {1005 memset(bp, 0, o_padsz);1006 bp = (void *) bp + o_padsz;1007 }1008 1009 *bp++ = htonl(new_dvp->fid.vid);1010 *bp++ = htonl(new_dvp->fid.vnode);1011 *bp++ = htonl(new_dvp->fid.unique);1012 *bp++ = htonl(n_namesz);1013 memcpy(bp, new_name->name, n_namesz);1014 bp = (void *) bp + n_namesz;1015 if (n_padsz > 0) {1016 memset(bp, 0, n_padsz);1017 bp = (void *) bp + n_padsz;1018 }1019 1020 call->fid = orig_dvp->fid;1021 trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);1022 afs_make_op_call(op, call, GFP_NOFS);1023}1024 1025/*1026 * Deliver reply data to FS.StoreData or FS.StoreStatus1027 */1028static int afs_deliver_fs_store_data(struct afs_call *call)1029{1030 struct afs_operation *op = call->op;1031 struct afs_vnode_param *vp = &op->file[0];1032 const __be32 *bp;1033 int ret;1034 1035 _enter("");1036 1037 ret = afs_transfer_reply(call);1038 if (ret < 0)1039 return ret;1040 1041 /* unmarshall the reply once we've received all of it */1042 bp = call->buffer;1043 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);1044 xdr_decode_AFSVolSync(&bp, &op->volsync);1045 1046 _leave(" = 0 [done]");1047 return 0;1048}1049 1050/*1051 * FS.StoreData operation type1052 */1053static const struct afs_call_type afs_RXFSStoreData = {1054 .name = "FS.StoreData",1055 .op = afs_FS_StoreData,1056 .deliver = afs_deliver_fs_store_data,1057 .destructor = afs_flat_call_destructor,1058};1059 1060static const struct afs_call_type afs_RXFSStoreData64 = {1061 .name = "FS.StoreData64",1062 .op = afs_FS_StoreData64,1063 .deliver = afs_deliver_fs_store_data,1064 .destructor = afs_flat_call_destructor,1065};1066 1067/*1068 * store a set of pages to a very large file1069 */1070static void afs_fs_store_data64(struct afs_operation *op)1071{1072 struct afs_vnode_param *vp = &op->file[0];1073 struct afs_call *call;1074 __be32 *bp;1075 1076 _enter(",%x,{%llx:%llu},,",1077 key_serial(op->key), vp->fid.vid, vp->fid.vnode);1078 1079 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64,1080 (4 + 6 + 3 * 2) * 4,1081 (21 + 6) * 4);1082 if (!call)1083 return afs_op_nomem(op);1084 1085 call->write_iter = op->store.write_iter;1086 1087 /* marshall the parameters */1088 bp = call->request;1089 *bp++ = htonl(FSSTOREDATA64);1090 *bp++ = htonl(vp->fid.vid);1091 *bp++ = htonl(vp->fid.vnode);1092 *bp++ = htonl(vp->fid.unique);1093 1094 *bp++ = htonl(AFS_SET_MTIME); /* mask */1095 *bp++ = htonl(op->mtime.tv_sec); /* mtime */1096 *bp++ = 0; /* owner */1097 *bp++ = 0; /* group */1098 *bp++ = 0; /* unix mode */1099 *bp++ = 0; /* segment size */1100 1101 *bp++ = htonl(upper_32_bits(op->store.pos));1102 *bp++ = htonl(lower_32_bits(op->store.pos));1103 *bp++ = htonl(upper_32_bits(op->store.size));1104 *bp++ = htonl(lower_32_bits(op->store.size));1105 *bp++ = htonl(upper_32_bits(op->store.i_size));1106 *bp++ = htonl(lower_32_bits(op->store.i_size));1107 1108 call->fid = vp->fid;1109 trace_afs_make_fs_call(call, &vp->fid);1110 afs_make_op_call(op, call, GFP_NOFS);1111}1112 1113/*1114 * Write data to a file on the server.1115 */1116void afs_fs_store_data(struct afs_operation *op)1117{1118 struct afs_vnode_param *vp = &op->file[0];1119 struct afs_call *call;1120 __be32 *bp;1121 1122 _enter(",%x,{%llx:%llu},,",1123 key_serial(op->key), vp->fid.vid, vp->fid.vnode);1124 1125 _debug("size %llx, at %llx, i_size %llx",1126 (unsigned long long)op->store.size,1127 (unsigned long long)op->store.pos,1128 (unsigned long long)op->store.i_size);1129 1130 if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))1131 return afs_fs_store_data64(op);1132 1133 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData,1134 (4 + 6 + 3) * 4,1135 (21 + 6) * 4);1136 if (!call)1137 return afs_op_nomem(op);1138 1139 call->write_iter = op->store.write_iter;1140 1141 /* marshall the parameters */1142 bp = call->request;1143 *bp++ = htonl(FSSTOREDATA);1144 *bp++ = htonl(vp->fid.vid);1145 *bp++ = htonl(vp->fid.vnode);1146 *bp++ = htonl(vp->fid.unique);1147 1148 *bp++ = htonl(AFS_SET_MTIME); /* mask */1149 *bp++ = htonl(op->mtime.tv_sec); /* mtime */1150 *bp++ = 0; /* owner */1151 *bp++ = 0; /* group */1152 *bp++ = 0; /* unix mode */1153 *bp++ = 0; /* segment size */1154 1155 *bp++ = htonl(lower_32_bits(op->store.pos));1156 *bp++ = htonl(lower_32_bits(op->store.size));1157 *bp++ = htonl(lower_32_bits(op->store.i_size));1158 1159 call->fid = vp->fid;1160 trace_afs_make_fs_call(call, &vp->fid);1161 afs_make_op_call(op, call, GFP_NOFS);1162}1163 1164/*1165 * FS.StoreStatus operation type1166 */1167static const struct afs_call_type afs_RXFSStoreStatus = {1168 .name = "FS.StoreStatus",1169 .op = afs_FS_StoreStatus,1170 .deliver = afs_deliver_fs_store_data,1171 .destructor = afs_flat_call_destructor,1172};1173 1174static const struct afs_call_type afs_RXFSStoreData_as_Status = {1175 .name = "FS.StoreData",1176 .op = afs_FS_StoreData,1177 .deliver = afs_deliver_fs_store_data,1178 .destructor = afs_flat_call_destructor,1179};1180 1181static const struct afs_call_type afs_RXFSStoreData64_as_Status = {1182 .name = "FS.StoreData64",1183 .op = afs_FS_StoreData64,1184 .deliver = afs_deliver_fs_store_data,1185 .destructor = afs_flat_call_destructor,1186};1187 1188/*1189 * set the attributes on a very large file, using FS.StoreData rather than1190 * FS.StoreStatus so as to alter the file size also1191 */1192static void afs_fs_setattr_size64(struct afs_operation *op)1193{1194 struct afs_vnode_param *vp = &op->file[0];1195 struct afs_call *call;1196 struct iattr *attr = op->setattr.attr;1197 __be32 *bp;1198 1199 _enter(",%x,{%llx:%llu},,",1200 key_serial(op->key), vp->fid.vid, vp->fid.vnode);1201 1202 ASSERT(attr->ia_valid & ATTR_SIZE);1203 1204 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64_as_Status,1205 (4 + 6 + 3 * 2) * 4,1206 (21 + 6) * 4);1207 if (!call)1208 return afs_op_nomem(op);1209 1210 /* marshall the parameters */1211 bp = call->request;1212 *bp++ = htonl(FSSTOREDATA64);1213 *bp++ = htonl(vp->fid.vid);1214 *bp++ = htonl(vp->fid.vnode);1215 *bp++ = htonl(vp->fid.unique);1216 1217 xdr_encode_AFS_StoreStatus(&bp, attr);1218 1219 *bp++ = htonl(upper_32_bits(attr->ia_size)); /* position of start of write */1220 *bp++ = htonl(lower_32_bits(attr->ia_size));1221 *bp++ = 0; /* size of write */1222 *bp++ = 0;1223 *bp++ = htonl(upper_32_bits(attr->ia_size)); /* new file length */1224 *bp++ = htonl(lower_32_bits(attr->ia_size));1225 1226 call->fid = vp->fid;1227 trace_afs_make_fs_call(call, &vp->fid);1228 afs_make_op_call(op, call, GFP_NOFS);1229}1230 1231/*1232 * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus1233 * so as to alter the file size also1234 */1235static void afs_fs_setattr_size(struct afs_operation *op)1236{1237 struct afs_vnode_param *vp = &op->file[0];1238 struct afs_call *call;1239 struct iattr *attr = op->setattr.attr;1240 __be32 *bp;1241 1242 _enter(",%x,{%llx:%llu},,",1243 key_serial(op->key), vp->fid.vid, vp->fid.vnode);1244 1245 ASSERT(attr->ia_valid & ATTR_SIZE);1246 if (test_bit(AFS_SERVER_FL_HAS_FS64, &op->server->flags))1247 return afs_fs_setattr_size64(op);1248 1249 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status,1250 (4 + 6 + 3) * 4,1251 (21 + 6) * 4);1252 if (!call)1253 return afs_op_nomem(op);1254 1255 /* marshall the parameters */1256 bp = call->request;1257 *bp++ = htonl(FSSTOREDATA);1258 *bp++ = htonl(vp->fid.vid);1259 *bp++ = htonl(vp->fid.vnode);1260 *bp++ = htonl(vp->fid.unique);1261 1262 xdr_encode_AFS_StoreStatus(&bp, attr);1263 1264 *bp++ = htonl(attr->ia_size); /* position of start of write */1265 *bp++ = 0; /* size of write */1266 *bp++ = htonl(attr->ia_size); /* new file length */1267 1268 call->fid = vp->fid;1269 trace_afs_make_fs_call(call, &vp->fid);1270 afs_make_op_call(op, call, GFP_NOFS);1271}1272 1273/*1274 * set the attributes on a file, using FS.StoreData if there's a change in file1275 * size, and FS.StoreStatus otherwise1276 */1277void afs_fs_setattr(struct afs_operation *op)1278{1279 struct afs_vnode_param *vp = &op->file[0];1280 struct afs_call *call;1281 struct iattr *attr = op->setattr.attr;1282 __be32 *bp;1283 1284 if (attr->ia_valid & ATTR_SIZE)1285 return afs_fs_setattr_size(op);1286 1287 _enter(",%x,{%llx:%llu},,",1288 key_serial(op->key), vp->fid.vid, vp->fid.vnode);1289 1290 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreStatus,1291 (4 + 6) * 4,1292 (21 + 6) * 4);1293 if (!call)1294 return afs_op_nomem(op);1295 1296 /* marshall the parameters */1297 bp = call->request;1298 *bp++ = htonl(FSSTORESTATUS);1299 *bp++ = htonl(vp->fid.vid);1300 *bp++ = htonl(vp->fid.vnode);1301 *bp++ = htonl(vp->fid.unique);1302 1303 xdr_encode_AFS_StoreStatus(&bp, op->setattr.attr);1304 1305 call->fid = vp->fid;1306 trace_afs_make_fs_call(call, &vp->fid);1307 afs_make_op_call(op, call, GFP_NOFS);1308}1309 1310/*1311 * deliver reply data to an FS.GetVolumeStatus1312 */1313static int afs_deliver_fs_get_volume_status(struct afs_call *call)1314{1315 struct afs_operation *op = call->op;1316 const __be32 *bp;1317 char *p;1318 u32 size;1319 int ret;1320 1321 _enter("{%u}", call->unmarshall);1322 1323 switch (call->unmarshall) {1324 case 0:1325 call->unmarshall++;1326 afs_extract_to_buf(call, 12 * 4);1327 fallthrough;1328 1329 /* extract the returned status record */1330 case 1:1331 _debug("extract status");1332 ret = afs_extract_data(call, true);1333 if (ret < 0)1334 return ret;1335 1336 bp = call->buffer;1337 xdr_decode_AFSFetchVolumeStatus(&bp, &op->volstatus.vs);1338 call->unmarshall++;1339 afs_extract_to_tmp(call);1340 fallthrough;1341 1342 /* extract the volume name length */1343 case 2:1344 ret = afs_extract_data(call, true);1345 if (ret < 0)1346 return ret;1347 1348 call->count = ntohl(call->tmp);1349 _debug("volname length: %u", call->count);1350 if (call->count >= AFSNAMEMAX)1351 return afs_protocol_error(call, afs_eproto_volname_len);1352 size = (call->count + 3) & ~3; /* It's padded */1353 afs_extract_to_buf(call, size);1354 call->unmarshall++;1355 fallthrough;1356 1357 /* extract the volume name */1358 case 3:1359 _debug("extract volname");1360 ret = afs_extract_data(call, true);1361 if (ret < 0)1362 return ret;1363 1364 p = call->buffer;1365 p[call->count] = 0;1366 _debug("volname '%s'", p);1367 afs_extract_to_tmp(call);1368 call->unmarshall++;1369 fallthrough;1370 1371 /* extract the offline message length */1372 case 4:1373 ret = afs_extract_data(call, true);1374 if (ret < 0)1375 return ret;1376 1377 call->count = ntohl(call->tmp);1378 _debug("offline msg length: %u", call->count);1379 if (call->count >= AFSNAMEMAX)1380 return afs_protocol_error(call, afs_eproto_offline_msg_len);1381 size = (call->count + 3) & ~3; /* It's padded */1382 afs_extract_to_buf(call, size);1383 call->unmarshall++;1384 fallthrough;1385 1386 /* extract the offline message */1387 case 5:1388 _debug("extract offline");1389 ret = afs_extract_data(call, true);1390 if (ret < 0)1391 return ret;1392 1393 p = call->buffer;1394 p[call->count] = 0;1395 _debug("offline '%s'", p);1396 1397 afs_extract_to_tmp(call);1398 call->unmarshall++;1399 fallthrough;1400 1401 /* extract the message of the day length */1402 case 6:1403 ret = afs_extract_data(call, true);1404 if (ret < 0)1405 return ret;1406 1407 call->count = ntohl(call->tmp);1408 _debug("motd length: %u", call->count);1409 if (call->count >= AFSNAMEMAX)1410 return afs_protocol_error(call, afs_eproto_motd_len);1411 size = (call->count + 3) & ~3; /* It's padded */1412 afs_extract_to_buf(call, size);1413 call->unmarshall++;1414 fallthrough;1415 1416 /* extract the message of the day */1417 case 7:1418 _debug("extract motd");1419 ret = afs_extract_data(call, false);1420 if (ret < 0)1421 return ret;1422 1423 p = call->buffer;1424 p[call->count] = 0;1425 _debug("motd '%s'", p);1426 1427 call->unmarshall++;1428 fallthrough;1429 1430 case 8:1431 break;1432 }1433 1434 _leave(" = 0 [done]");1435 return 0;1436}1437 1438/*1439 * FS.GetVolumeStatus operation type1440 */1441static const struct afs_call_type afs_RXFSGetVolumeStatus = {1442 .name = "FS.GetVolumeStatus",1443 .op = afs_FS_GetVolumeStatus,1444 .deliver = afs_deliver_fs_get_volume_status,1445 .destructor = afs_flat_call_destructor,1446};1447 1448/*1449 * fetch the status of a volume1450 */1451void afs_fs_get_volume_status(struct afs_operation *op)1452{1453 struct afs_vnode_param *vp = &op->file[0];1454 struct afs_call *call;1455 __be32 *bp;1456 1457 _enter("");1458 1459 call = afs_alloc_flat_call(op->net, &afs_RXFSGetVolumeStatus, 2 * 4,1460 max(12 * 4, AFSOPAQUEMAX + 1));1461 if (!call)1462 return afs_op_nomem(op);1463 1464 /* marshall the parameters */1465 bp = call->request;1466 bp[0] = htonl(FSGETVOLUMESTATUS);1467 bp[1] = htonl(vp->fid.vid);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 an FS.SetLock, FS.ExtendLock or FS.ReleaseLock1476 */1477static int afs_deliver_fs_xxxx_lock(struct afs_call *call)1478{1479 struct afs_operation *op = call->op;1480 const __be32 *bp;1481 int ret;1482 1483 _enter("{%u}", call->unmarshall);1484 1485 ret = afs_transfer_reply(call);1486 if (ret < 0)1487 return ret;1488 1489 /* unmarshall the reply once we've received all of it */1490 bp = call->buffer;1491 xdr_decode_AFSVolSync(&bp, &op->volsync);1492 1493 _leave(" = 0 [done]");1494 return 0;1495}1496 1497/*1498 * FS.SetLock operation type1499 */1500static const struct afs_call_type afs_RXFSSetLock = {1501 .name = "FS.SetLock",1502 .op = afs_FS_SetLock,1503 .deliver = afs_deliver_fs_xxxx_lock,1504 .done = afs_lock_op_done,1505 .destructor = afs_flat_call_destructor,1506};1507 1508/*1509 * FS.ExtendLock operation type1510 */1511static const struct afs_call_type afs_RXFSExtendLock = {1512 .name = "FS.ExtendLock",1513 .op = afs_FS_ExtendLock,1514 .deliver = afs_deliver_fs_xxxx_lock,1515 .done = afs_lock_op_done,1516 .destructor = afs_flat_call_destructor,1517};1518 1519/*1520 * FS.ReleaseLock operation type1521 */1522static const struct afs_call_type afs_RXFSReleaseLock = {1523 .name = "FS.ReleaseLock",1524 .op = afs_FS_ReleaseLock,1525 .deliver = afs_deliver_fs_xxxx_lock,1526 .destructor = afs_flat_call_destructor,1527};1528 1529/*1530 * Set a lock on a file1531 */1532void afs_fs_set_lock(struct afs_operation *op)1533{1534 struct afs_vnode_param *vp = &op->file[0];1535 struct afs_call *call;1536 __be32 *bp;1537 1538 _enter("");1539 1540 call = afs_alloc_flat_call(op->net, &afs_RXFSSetLock, 5 * 4, 6 * 4);1541 if (!call)1542 return afs_op_nomem(op);1543 1544 /* marshall the parameters */1545 bp = call->request;1546 *bp++ = htonl(FSSETLOCK);1547 *bp++ = htonl(vp->fid.vid);1548 *bp++ = htonl(vp->fid.vnode);1549 *bp++ = htonl(vp->fid.unique);1550 *bp++ = htonl(op->lock.type);1551 1552 call->fid = vp->fid;1553 trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);1554 afs_make_op_call(op, call, GFP_NOFS);1555}1556 1557/*1558 * extend a lock on a file1559 */1560void afs_fs_extend_lock(struct afs_operation *op)1561{1562 struct afs_vnode_param *vp = &op->file[0];1563 struct afs_call *call;1564 __be32 *bp;1565 1566 _enter("");1567 1568 call = afs_alloc_flat_call(op->net, &afs_RXFSExtendLock, 4 * 4, 6 * 4);1569 if (!call)1570 return afs_op_nomem(op);1571 1572 /* marshall the parameters */1573 bp = call->request;1574 *bp++ = htonl(FSEXTENDLOCK);1575 *bp++ = htonl(vp->fid.vid);1576 *bp++ = htonl(vp->fid.vnode);1577 *bp++ = htonl(vp->fid.unique);1578 1579 call->fid = vp->fid;1580 trace_afs_make_fs_call(call, &vp->fid);1581 afs_make_op_call(op, call, GFP_NOFS);1582}1583 1584/*1585 * release a lock on a file1586 */1587void afs_fs_release_lock(struct afs_operation *op)1588{1589 struct afs_vnode_param *vp = &op->file[0];1590 struct afs_call *call;1591 __be32 *bp;1592 1593 _enter("");1594 1595 call = afs_alloc_flat_call(op->net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4);1596 if (!call)1597 return afs_op_nomem(op);1598 1599 /* marshall the parameters */1600 bp = call->request;1601 *bp++ = htonl(FSRELEASELOCK);1602 *bp++ = htonl(vp->fid.vid);1603 *bp++ = htonl(vp->fid.vnode);1604 *bp++ = htonl(vp->fid.unique);1605 1606 call->fid = vp->fid;1607 trace_afs_make_fs_call(call, &vp->fid);1608 afs_make_op_call(op, call, GFP_NOFS);1609}1610 1611/*1612 * Deliver reply data to an FS.GiveUpAllCallBacks operation.1613 */1614static int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call)1615{1616 return afs_transfer_reply(call);1617}1618 1619/*1620 * FS.GiveUpAllCallBacks operation type1621 */1622static const struct afs_call_type afs_RXFSGiveUpAllCallBacks = {1623 .name = "FS.GiveUpAllCallBacks",1624 .op = afs_FS_GiveUpAllCallBacks,1625 .deliver = afs_deliver_fs_give_up_all_callbacks,1626 .destructor = afs_flat_call_destructor,1627};1628 1629/*1630 * Flush all the callbacks we have on a server.1631 */1632int afs_fs_give_up_all_callbacks(struct afs_net *net, struct afs_server *server,1633 struct afs_address *addr, struct key *key)1634{1635 struct afs_call *call;1636 __be32 *bp;1637 int ret;1638 1639 _enter("");1640 1641 call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0);1642 if (!call)1643 return -ENOMEM;1644 1645 call->key = key;1646 call->peer = rxrpc_kernel_get_peer(addr->peer);1647 call->service_id = server->service_id;1648 1649 /* marshall the parameters */1650 bp = call->request;1651 *bp++ = htonl(FSGIVEUPALLCALLBACKS);1652 1653 call->server = afs_use_server(server, afs_server_trace_give_up_cb);1654 afs_make_call(call, GFP_NOFS);1655 afs_wait_for_call_to_complete(call);1656 ret = call->error;1657 if (call->responded)1658 set_bit(AFS_SERVER_FL_RESPONDING, &server->flags);1659 afs_put_call(call);1660 return ret;1661}1662 1663/*1664 * Deliver reply data to an FS.GetCapabilities operation.1665 */1666static int afs_deliver_fs_get_capabilities(struct afs_call *call)1667{1668 u32 count;1669 int ret;1670 1671 _enter("{%u,%zu}", call->unmarshall, iov_iter_count(call->iter));1672 1673 switch (call->unmarshall) {1674 case 0:1675 afs_extract_to_tmp(call);1676 call->unmarshall++;1677 fallthrough;1678 1679 /* Extract the capabilities word count */1680 case 1:1681 ret = afs_extract_data(call, true);1682 if (ret < 0)1683 return ret;1684 1685 count = ntohl(call->tmp);1686 call->count = count;1687 call->count2 = count;1688 if (count == 0) {1689 call->unmarshall = 4;1690 call->tmp = 0;1691 break;1692 }1693 1694 /* Extract the first word of the capabilities to call->tmp */1695 afs_extract_to_tmp(call);1696 call->unmarshall++;1697 fallthrough;1698 1699 case 2:1700 ret = afs_extract_data(call, false);1701 if (ret < 0)1702 return ret;1703 1704 afs_extract_discard(call, (count - 1) * sizeof(__be32));1705 call->unmarshall++;1706 fallthrough;1707 1708 /* Extract remaining capabilities words */1709 case 3:1710 ret = afs_extract_data(call, false);1711 if (ret < 0)1712 return ret;1713 1714 call->unmarshall++;1715 break;1716 }1717 1718 _leave(" = 0 [done]");1719 return 0;1720}1721 1722static void afs_fs_get_capabilities_destructor(struct afs_call *call)1723{1724 afs_put_endpoint_state(call->probe, afs_estate_trace_put_getcaps);1725 afs_flat_call_destructor(call);1726}1727 1728/*1729 * FS.GetCapabilities operation type1730 */1731static const struct afs_call_type afs_RXFSGetCapabilities = {1732 .name = "FS.GetCapabilities",1733 .op = afs_FS_GetCapabilities,1734 .deliver = afs_deliver_fs_get_capabilities,1735 .done = afs_fileserver_probe_result,1736 .destructor = afs_fs_get_capabilities_destructor,1737};1738 1739/*1740 * Probe a fileserver for the capabilities that it supports. This RPC can1741 * reply with up to 196 words. The operation is asynchronous and if we managed1742 * to allocate a call, true is returned the result is delivered through the1743 * ->done() - otherwise we return false to indicate we didn't even try.1744 */1745bool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server,1746 struct afs_endpoint_state *estate, unsigned int addr_index,1747 struct key *key)1748{1749 struct afs_call *call;1750 __be32 *bp;1751 1752 _enter("");1753 1754 call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4);1755 if (!call)1756 return false;1757 1758 call->key = key;1759 call->server = afs_use_server(server, afs_server_trace_get_caps);1760 call->peer = rxrpc_kernel_get_peer(estate->addresses->addrs[addr_index].peer);1761 call->probe = afs_get_endpoint_state(estate, afs_estate_trace_get_getcaps);1762 call->probe_index = addr_index;1763 call->service_id = server->service_id;1764 call->upgrade = true;1765 call->async = true;1766 call->max_lifespan = AFS_PROBE_MAX_LIFESPAN;1767 1768 /* marshall the parameters */1769 bp = call->request;1770 *bp++ = htonl(FSGETCAPABILITIES);1771 1772 trace_afs_make_fs_call(call, NULL);1773 afs_make_call(call, GFP_NOFS);1774 afs_put_call(call);1775 return true;1776}1777 1778/*1779 * Deliver reply data to an FS.InlineBulkStatus call1780 */1781static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)1782{1783 struct afs_operation *op = call->op;1784 struct afs_status_cb *scb;1785 const __be32 *bp;1786 u32 tmp;1787 int ret;1788 1789 _enter("{%u}", call->unmarshall);1790 1791 switch (call->unmarshall) {1792 case 0:1793 afs_extract_to_tmp(call);1794 call->unmarshall++;1795 fallthrough;1796 1797 /* Extract the file status count and array in two steps */1798 case 1:1799 _debug("extract status count");1800 ret = afs_extract_data(call, true);1801 if (ret < 0)1802 return ret;1803 1804 tmp = ntohl(call->tmp);1805 _debug("status count: %u/%u", tmp, op->nr_files);1806 if (tmp != op->nr_files)1807 return afs_protocol_error(call, afs_eproto_ibulkst_count);1808 1809 call->count = 0;1810 call->unmarshall++;1811 more_counts:1812 afs_extract_to_buf(call, 21 * sizeof(__be32));1813 fallthrough;1814 1815 case 2:1816 _debug("extract status array %u", call->count);1817 ret = afs_extract_data(call, true);1818 if (ret < 0)1819 return ret;1820 1821 switch (call->count) {1822 case 0:1823 scb = &op->file[0].scb;1824 break;1825 case 1:1826 scb = &op->file[1].scb;1827 break;1828 default:1829 scb = &op->more_files[call->count - 2].scb;1830 break;1831 }1832 1833 bp = call->buffer;1834 xdr_decode_AFSFetchStatus(&bp, call, scb);1835 1836 call->count++;1837 if (call->count < op->nr_files)1838 goto more_counts;1839 1840 call->count = 0;1841 call->unmarshall++;1842 afs_extract_to_tmp(call);1843 fallthrough;1844 1845 /* Extract the callback count and array in two steps */1846 case 3:1847 _debug("extract CB count");1848 ret = afs_extract_data(call, true);1849 if (ret < 0)1850 return ret;1851 1852 tmp = ntohl(call->tmp);1853 _debug("CB count: %u", tmp);1854 if (tmp != op->nr_files)1855 return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);1856 call->count = 0;1857 call->unmarshall++;1858 more_cbs:1859 afs_extract_to_buf(call, 3 * sizeof(__be32));1860 fallthrough;1861 1862 case 4:1863 _debug("extract CB array");1864 ret = afs_extract_data(call, true);1865 if (ret < 0)1866 return ret;1867 1868 _debug("unmarshall CB array");1869 switch (call->count) {1870 case 0:1871 scb = &op->file[0].scb;1872 break;1873 case 1:1874 scb = &op->file[1].scb;1875 break;1876 default:1877 scb = &op->more_files[call->count - 2].scb;1878 break;1879 }1880 1881 bp = call->buffer;1882 xdr_decode_AFSCallBack(&bp, call, scb);1883 call->count++;1884 if (call->count < op->nr_files)1885 goto more_cbs;1886 1887 afs_extract_to_buf(call, 6 * sizeof(__be32));1888 call->unmarshall++;1889 fallthrough;1890 1891 case 5:1892 ret = afs_extract_data(call, false);1893 if (ret < 0)1894 return ret;1895 1896 bp = call->buffer;1897 /* Unfortunately, prior to OpenAFS-1.6, volsync here is filled1898 * with rubbish.1899 */1900 xdr_decode_AFSVolSync(&bp, NULL);1901 1902 call->unmarshall++;1903 fallthrough;1904 1905 case 6:1906 break;1907 }1908 1909 _leave(" = 0 [done]");1910 return 0;1911}1912 1913static void afs_done_fs_inline_bulk_status(struct afs_call *call)1914{1915 if (call->error == -ECONNABORTED &&1916 call->abort_code == RX_INVALID_OPERATION) {1917 set_bit(AFS_SERVER_FL_NO_IBULK, &call->server->flags);1918 if (call->op)1919 set_bit(AFS_VOLUME_MAYBE_NO_IBULK, &call->op->volume->flags);1920 }1921}1922 1923/*1924 * FS.InlineBulkStatus operation type1925 */1926static const struct afs_call_type afs_RXFSInlineBulkStatus = {1927 .name = "FS.InlineBulkStatus",1928 .op = afs_FS_InlineBulkStatus,1929 .deliver = afs_deliver_fs_inline_bulk_status,1930 .done = afs_done_fs_inline_bulk_status,1931 .destructor = afs_flat_call_destructor,1932};1933 1934/*1935 * Fetch the status information for up to 50 files1936 */1937void afs_fs_inline_bulk_status(struct afs_operation *op)1938{1939 struct afs_vnode_param *dvp = &op->file[0];1940 struct afs_vnode_param *vp = &op->file[1];1941 struct afs_call *call;1942 __be32 *bp;1943 int i;1944 1945 if (test_bit(AFS_SERVER_FL_NO_IBULK, &op->server->flags)) {1946 afs_op_set_error(op, -ENOTSUPP);1947 return;1948 }1949 1950 _enter(",%x,{%llx:%llu},%u",1951 key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);1952 1953 call = afs_alloc_flat_call(op->net, &afs_RXFSInlineBulkStatus,1954 (2 + op->nr_files * 3) * 4,1955 21 * 4);1956 if (!call)1957 return afs_op_nomem(op);1958 1959 /* marshall the parameters */1960 bp = call->request;1961 *bp++ = htonl(FSINLINEBULKSTATUS);1962 *bp++ = htonl(op->nr_files);1963 *bp++ = htonl(dvp->fid.vid);1964 *bp++ = htonl(dvp->fid.vnode);1965 *bp++ = htonl(dvp->fid.unique);1966 *bp++ = htonl(vp->fid.vid);1967 *bp++ = htonl(vp->fid.vnode);1968 *bp++ = htonl(vp->fid.unique);1969 for (i = 0; i < op->nr_files - 2; i++) {1970 *bp++ = htonl(op->more_files[i].fid.vid);1971 *bp++ = htonl(op->more_files[i].fid.vnode);1972 *bp++ = htonl(op->more_files[i].fid.unique);1973 }1974 1975 call->fid = vp->fid;1976 trace_afs_make_fs_call(call, &vp->fid);1977 afs_make_op_call(op, call, GFP_NOFS);1978}1979 1980/*1981 * deliver reply data to an FS.FetchACL1982 */1983static int afs_deliver_fs_fetch_acl(struct afs_call *call)1984{1985 struct afs_operation *op = call->op;1986 struct afs_vnode_param *vp = &op->file[0];1987 struct afs_acl *acl;1988 const __be32 *bp;1989 unsigned int size;1990 int ret;1991 1992 _enter("{%u}", call->unmarshall);1993 1994 switch (call->unmarshall) {1995 case 0:1996 afs_extract_to_tmp(call);1997 call->unmarshall++;1998 fallthrough;1999 2000 /* extract the returned data length */2001 case 1:2002 ret = afs_extract_data(call, true);2003 if (ret < 0)2004 return ret;2005 2006 size = call->count2 = ntohl(call->tmp);2007 size = round_up(size, 4);2008 2009 acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);2010 if (!acl)2011 return -ENOMEM;2012 op->acl = acl;2013 acl->size = call->count2;2014 afs_extract_begin(call, acl->data, size);2015 call->unmarshall++;2016 fallthrough;2017 2018 /* extract the returned data */2019 case 2:2020 ret = afs_extract_data(call, true);2021 if (ret < 0)2022 return ret;2023 2024 afs_extract_to_buf(call, (21 + 6) * 4);2025 call->unmarshall++;2026 fallthrough;2027 2028 /* extract the metadata */2029 case 3:2030 ret = afs_extract_data(call, false);2031 if (ret < 0)2032 return ret;2033 2034 bp = call->buffer;2035 xdr_decode_AFSFetchStatus(&bp, call, &vp->scb);2036 xdr_decode_AFSVolSync(&bp, &op->volsync);2037 2038 call->unmarshall++;2039 fallthrough;2040 2041 case 4:2042 break;2043 }2044 2045 _leave(" = 0 [done]");2046 return 0;2047}2048 2049/*2050 * FS.FetchACL operation type2051 */2052static const struct afs_call_type afs_RXFSFetchACL = {2053 .name = "FS.FetchACL",2054 .op = afs_FS_FetchACL,2055 .deliver = afs_deliver_fs_fetch_acl,2056};2057 2058/*2059 * Fetch the ACL for a file.2060 */2061void afs_fs_fetch_acl(struct afs_operation *op)2062{2063 struct afs_vnode_param *vp = &op->file[0];2064 struct afs_call *call;2065 __be32 *bp;2066 2067 _enter(",%x,{%llx:%llu},,",2068 key_serial(op->key), vp->fid.vid, vp->fid.vnode);2069 2070 call = afs_alloc_flat_call(op->net, &afs_RXFSFetchACL, 16, (21 + 6) * 4);2071 if (!call)2072 return afs_op_nomem(op);2073 2074 /* marshall the parameters */2075 bp = call->request;2076 bp[0] = htonl(FSFETCHACL);2077 bp[1] = htonl(vp->fid.vid);2078 bp[2] = htonl(vp->fid.vnode);2079 bp[3] = htonl(vp->fid.unique);2080 2081 call->fid = vp->fid;2082 trace_afs_make_fs_call(call, &vp->fid);2083 afs_make_op_call(op, call, GFP_KERNEL);2084}2085 2086/*2087 * FS.StoreACL operation type2088 */2089static const struct afs_call_type afs_RXFSStoreACL = {2090 .name = "FS.StoreACL",2091 .op = afs_FS_StoreACL,2092 .deliver = afs_deliver_fs_file_status_and_vol,2093 .destructor = afs_flat_call_destructor,2094};2095 2096/*2097 * Fetch the ACL for a file.2098 */2099void afs_fs_store_acl(struct afs_operation *op)2100{2101 struct afs_vnode_param *vp = &op->file[0];2102 struct afs_call *call;2103 const struct afs_acl *acl = op->acl;2104 size_t size;2105 __be32 *bp;2106 2107 _enter(",%x,{%llx:%llu},,",2108 key_serial(op->key), vp->fid.vid, vp->fid.vnode);2109 2110 size = round_up(acl->size, 4);2111 call = afs_alloc_flat_call(op->net, &afs_RXFSStoreACL,2112 5 * 4 + size, (21 + 6) * 4);2113 if (!call)2114 return afs_op_nomem(op);2115 2116 /* marshall the parameters */2117 bp = call->request;2118 bp[0] = htonl(FSSTOREACL);2119 bp[1] = htonl(vp->fid.vid);2120 bp[2] = htonl(vp->fid.vnode);2121 bp[3] = htonl(vp->fid.unique);2122 bp[4] = htonl(acl->size);2123 memcpy(&bp[5], acl->data, acl->size);2124 if (acl->size != size)2125 memset((void *)&bp[5] + acl->size, 0, size - acl->size);2126 2127 call->fid = vp->fid;2128 trace_afs_make_fs_call(call, &vp->fid);2129 afs_make_op_call(op, call, GFP_KERNEL);2130}2131