18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* AFS File Server client stubs 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved. 58c2ecf20Sopenharmony_ci * Written by David Howells (dhowells@redhat.com) 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/init.h> 98c2ecf20Sopenharmony_ci#include <linux/slab.h> 108c2ecf20Sopenharmony_ci#include <linux/sched.h> 118c2ecf20Sopenharmony_ci#include <linux/circ_buf.h> 128c2ecf20Sopenharmony_ci#include <linux/iversion.h> 138c2ecf20Sopenharmony_ci#include "internal.h" 148c2ecf20Sopenharmony_ci#include "afs_fs.h" 158c2ecf20Sopenharmony_ci#include "xdr_fs.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * decode an AFSFid block 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_cistatic void xdr_decode_AFSFid(const __be32 **_bp, struct afs_fid *fid) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci const __be32 *bp = *_bp; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci fid->vid = ntohl(*bp++); 258c2ecf20Sopenharmony_ci fid->vnode = ntohl(*bp++); 268c2ecf20Sopenharmony_ci fid->unique = ntohl(*bp++); 278c2ecf20Sopenharmony_ci *_bp = bp; 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * Dump a bad file status record. 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_cistatic void xdr_dump_bad(const __be32 *bp) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci __be32 x[4]; 368c2ecf20Sopenharmony_ci int i; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci pr_notice("AFS XDR: Bad status record\n"); 398c2ecf20Sopenharmony_ci for (i = 0; i < 5 * 4 * 4; i += 16) { 408c2ecf20Sopenharmony_ci memcpy(x, bp, 16); 418c2ecf20Sopenharmony_ci bp += 4; 428c2ecf20Sopenharmony_ci pr_notice("%03x: %08x %08x %08x %08x\n", 438c2ecf20Sopenharmony_ci i, ntohl(x[0]), ntohl(x[1]), ntohl(x[2]), ntohl(x[3])); 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci memcpy(x, bp, 4); 478c2ecf20Sopenharmony_ci pr_notice("0x50: %08x\n", ntohl(x[0])); 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* 518c2ecf20Sopenharmony_ci * decode an AFSFetchStatus block 528c2ecf20Sopenharmony_ci */ 538c2ecf20Sopenharmony_cistatic void xdr_decode_AFSFetchStatus(const __be32 **_bp, 548c2ecf20Sopenharmony_ci struct afs_call *call, 558c2ecf20Sopenharmony_ci struct afs_status_cb *scb) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; 588c2ecf20Sopenharmony_ci struct afs_file_status *status = &scb->status; 598c2ecf20Sopenharmony_ci bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus); 608c2ecf20Sopenharmony_ci u64 data_version, size; 618c2ecf20Sopenharmony_ci u32 type, abort_code; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci abort_code = ntohl(xdr->abort_code); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) { 668c2ecf20Sopenharmony_ci if (xdr->if_version == htonl(0) && 678c2ecf20Sopenharmony_ci abort_code != 0 && 688c2ecf20Sopenharmony_ci inline_error) { 698c2ecf20Sopenharmony_ci /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus 708c2ecf20Sopenharmony_ci * whereby it doesn't set the interface version in the error 718c2ecf20Sopenharmony_ci * case. 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci status->abort_code = abort_code; 748c2ecf20Sopenharmony_ci scb->have_error = true; 758c2ecf20Sopenharmony_ci goto advance; 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); 798c2ecf20Sopenharmony_ci goto bad; 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci if (abort_code != 0 && inline_error) { 838c2ecf20Sopenharmony_ci status->abort_code = abort_code; 848c2ecf20Sopenharmony_ci scb->have_error = true; 858c2ecf20Sopenharmony_ci goto advance; 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci type = ntohl(xdr->type); 898c2ecf20Sopenharmony_ci switch (type) { 908c2ecf20Sopenharmony_ci case AFS_FTYPE_FILE: 918c2ecf20Sopenharmony_ci case AFS_FTYPE_DIR: 928c2ecf20Sopenharmony_ci case AFS_FTYPE_SYMLINK: 938c2ecf20Sopenharmony_ci status->type = type; 948c2ecf20Sopenharmony_ci break; 958c2ecf20Sopenharmony_ci default: 968c2ecf20Sopenharmony_ci goto bad; 978c2ecf20Sopenharmony_ci } 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci status->nlink = ntohl(xdr->nlink); 1008c2ecf20Sopenharmony_ci status->author = ntohl(xdr->author); 1018c2ecf20Sopenharmony_ci status->owner = ntohl(xdr->owner); 1028c2ecf20Sopenharmony_ci status->caller_access = ntohl(xdr->caller_access); /* Ticket dependent */ 1038c2ecf20Sopenharmony_ci status->anon_access = ntohl(xdr->anon_access); 1048c2ecf20Sopenharmony_ci status->mode = ntohl(xdr->mode) & S_IALLUGO; 1058c2ecf20Sopenharmony_ci status->group = ntohl(xdr->group); 1068c2ecf20Sopenharmony_ci status->lock_count = ntohl(xdr->lock_count); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci status->mtime_client.tv_sec = ntohl(xdr->mtime_client); 1098c2ecf20Sopenharmony_ci status->mtime_client.tv_nsec = 0; 1108c2ecf20Sopenharmony_ci status->mtime_server.tv_sec = ntohl(xdr->mtime_server); 1118c2ecf20Sopenharmony_ci status->mtime_server.tv_nsec = 0; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci size = (u64)ntohl(xdr->size_lo); 1148c2ecf20Sopenharmony_ci size |= (u64)ntohl(xdr->size_hi) << 32; 1158c2ecf20Sopenharmony_ci status->size = size; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci data_version = (u64)ntohl(xdr->data_version_lo); 1188c2ecf20Sopenharmony_ci data_version |= (u64)ntohl(xdr->data_version_hi) << 32; 1198c2ecf20Sopenharmony_ci status->data_version = data_version; 1208c2ecf20Sopenharmony_ci scb->have_status = true; 1218c2ecf20Sopenharmony_ciadvance: 1228c2ecf20Sopenharmony_ci *_bp = (const void *)*_bp + sizeof(*xdr); 1238c2ecf20Sopenharmony_ci return; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cibad: 1268c2ecf20Sopenharmony_ci xdr_dump_bad(*_bp); 1278c2ecf20Sopenharmony_ci afs_protocol_error(call, afs_eproto_bad_status); 1288c2ecf20Sopenharmony_ci goto advance; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci return ktime_divns(call->issue_time, NSEC_PER_SEC) + expiry; 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_cistatic void xdr_decode_AFSCallBack(const __be32 **_bp, 1378c2ecf20Sopenharmony_ci struct afs_call *call, 1388c2ecf20Sopenharmony_ci struct afs_status_cb *scb) 1398c2ecf20Sopenharmony_ci{ 1408c2ecf20Sopenharmony_ci struct afs_callback *cb = &scb->callback; 1418c2ecf20Sopenharmony_ci const __be32 *bp = *_bp; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci bp++; /* version */ 1448c2ecf20Sopenharmony_ci cb->expires_at = xdr_decode_expiry(call, ntohl(*bp++)); 1458c2ecf20Sopenharmony_ci bp++; /* type */ 1468c2ecf20Sopenharmony_ci scb->have_cb = true; 1478c2ecf20Sopenharmony_ci *_bp = bp; 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci/* 1518c2ecf20Sopenharmony_ci * decode an AFSVolSync block 1528c2ecf20Sopenharmony_ci */ 1538c2ecf20Sopenharmony_cistatic void xdr_decode_AFSVolSync(const __be32 **_bp, 1548c2ecf20Sopenharmony_ci struct afs_volsync *volsync) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci const __be32 *bp = *_bp; 1578c2ecf20Sopenharmony_ci u32 creation; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci creation = ntohl(*bp++); 1608c2ecf20Sopenharmony_ci bp++; /* spare2 */ 1618c2ecf20Sopenharmony_ci bp++; /* spare3 */ 1628c2ecf20Sopenharmony_ci bp++; /* spare4 */ 1638c2ecf20Sopenharmony_ci bp++; /* spare5 */ 1648c2ecf20Sopenharmony_ci bp++; /* spare6 */ 1658c2ecf20Sopenharmony_ci *_bp = bp; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci if (volsync) 1688c2ecf20Sopenharmony_ci volsync->creation = creation; 1698c2ecf20Sopenharmony_ci} 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci/* 1728c2ecf20Sopenharmony_ci * encode the requested attributes into an AFSStoreStatus block 1738c2ecf20Sopenharmony_ci */ 1748c2ecf20Sopenharmony_cistatic void xdr_encode_AFS_StoreStatus(__be32 **_bp, struct iattr *attr) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci __be32 *bp = *_bp; 1778c2ecf20Sopenharmony_ci u32 mask = 0, mtime = 0, owner = 0, group = 0, mode = 0; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci mask = 0; 1808c2ecf20Sopenharmony_ci if (attr->ia_valid & ATTR_MTIME) { 1818c2ecf20Sopenharmony_ci mask |= AFS_SET_MTIME; 1828c2ecf20Sopenharmony_ci mtime = attr->ia_mtime.tv_sec; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci if (attr->ia_valid & ATTR_UID) { 1868c2ecf20Sopenharmony_ci mask |= AFS_SET_OWNER; 1878c2ecf20Sopenharmony_ci owner = from_kuid(&init_user_ns, attr->ia_uid); 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if (attr->ia_valid & ATTR_GID) { 1918c2ecf20Sopenharmony_ci mask |= AFS_SET_GROUP; 1928c2ecf20Sopenharmony_ci group = from_kgid(&init_user_ns, attr->ia_gid); 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci if (attr->ia_valid & ATTR_MODE) { 1968c2ecf20Sopenharmony_ci mask |= AFS_SET_MODE; 1978c2ecf20Sopenharmony_ci mode = attr->ia_mode & S_IALLUGO; 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci *bp++ = htonl(mask); 2018c2ecf20Sopenharmony_ci *bp++ = htonl(mtime); 2028c2ecf20Sopenharmony_ci *bp++ = htonl(owner); 2038c2ecf20Sopenharmony_ci *bp++ = htonl(group); 2048c2ecf20Sopenharmony_ci *bp++ = htonl(mode); 2058c2ecf20Sopenharmony_ci *bp++ = 0; /* segment size */ 2068c2ecf20Sopenharmony_ci *_bp = bp; 2078c2ecf20Sopenharmony_ci} 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci/* 2108c2ecf20Sopenharmony_ci * decode an AFSFetchVolumeStatus block 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_cistatic void xdr_decode_AFSFetchVolumeStatus(const __be32 **_bp, 2138c2ecf20Sopenharmony_ci struct afs_volume_status *vs) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci const __be32 *bp = *_bp; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci vs->vid = ntohl(*bp++); 2188c2ecf20Sopenharmony_ci vs->parent_id = ntohl(*bp++); 2198c2ecf20Sopenharmony_ci vs->online = ntohl(*bp++); 2208c2ecf20Sopenharmony_ci vs->in_service = ntohl(*bp++); 2218c2ecf20Sopenharmony_ci vs->blessed = ntohl(*bp++); 2228c2ecf20Sopenharmony_ci vs->needs_salvage = ntohl(*bp++); 2238c2ecf20Sopenharmony_ci vs->type = ntohl(*bp++); 2248c2ecf20Sopenharmony_ci vs->min_quota = ntohl(*bp++); 2258c2ecf20Sopenharmony_ci vs->max_quota = ntohl(*bp++); 2268c2ecf20Sopenharmony_ci vs->blocks_in_use = ntohl(*bp++); 2278c2ecf20Sopenharmony_ci vs->part_blocks_avail = ntohl(*bp++); 2288c2ecf20Sopenharmony_ci vs->part_max_blocks = ntohl(*bp++); 2298c2ecf20Sopenharmony_ci vs->vol_copy_date = 0; 2308c2ecf20Sopenharmony_ci vs->vol_backup_date = 0; 2318c2ecf20Sopenharmony_ci *_bp = bp; 2328c2ecf20Sopenharmony_ci} 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci/* 2358c2ecf20Sopenharmony_ci * deliver reply data to an FS.FetchStatus 2368c2ecf20Sopenharmony_ci */ 2378c2ecf20Sopenharmony_cistatic int afs_deliver_fs_fetch_status(struct afs_call *call) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 2408c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[op->fetch_status.which]; 2418c2ecf20Sopenharmony_ci const __be32 *bp; 2428c2ecf20Sopenharmony_ci int ret; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 2458c2ecf20Sopenharmony_ci if (ret < 0) 2468c2ecf20Sopenharmony_ci return ret; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci /* unmarshall the reply once we've received all of it */ 2498c2ecf20Sopenharmony_ci bp = call->buffer; 2508c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 2518c2ecf20Sopenharmony_ci xdr_decode_AFSCallBack(&bp, call, &vp->scb); 2528c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 2558c2ecf20Sopenharmony_ci return 0; 2568c2ecf20Sopenharmony_ci} 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci/* 2598c2ecf20Sopenharmony_ci * FS.FetchStatus operation type 2608c2ecf20Sopenharmony_ci */ 2618c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSFetchStatus = { 2628c2ecf20Sopenharmony_ci .name = "FS.FetchStatus", 2638c2ecf20Sopenharmony_ci .op = afs_FS_FetchStatus, 2648c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_fetch_status, 2658c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 2668c2ecf20Sopenharmony_ci}; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci/* 2698c2ecf20Sopenharmony_ci * fetch the status information for a file 2708c2ecf20Sopenharmony_ci */ 2718c2ecf20Sopenharmony_civoid afs_fs_fetch_status(struct afs_operation *op) 2728c2ecf20Sopenharmony_ci{ 2738c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[op->fetch_status.which]; 2748c2ecf20Sopenharmony_ci struct afs_call *call; 2758c2ecf20Sopenharmony_ci __be32 *bp; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 2788c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSFetchStatus, 2818c2ecf20Sopenharmony_ci 16, (21 + 3 + 6) * 4); 2828c2ecf20Sopenharmony_ci if (!call) 2838c2ecf20Sopenharmony_ci return afs_op_nomem(op); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci /* marshall the parameters */ 2868c2ecf20Sopenharmony_ci bp = call->request; 2878c2ecf20Sopenharmony_ci bp[0] = htonl(FSFETCHSTATUS); 2888c2ecf20Sopenharmony_ci bp[1] = htonl(vp->fid.vid); 2898c2ecf20Sopenharmony_ci bp[2] = htonl(vp->fid.vnode); 2908c2ecf20Sopenharmony_ci bp[3] = htonl(vp->fid.unique); 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 2938c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 2948c2ecf20Sopenharmony_ci} 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci/* 2978c2ecf20Sopenharmony_ci * deliver reply data to an FS.FetchData 2988c2ecf20Sopenharmony_ci */ 2998c2ecf20Sopenharmony_cistatic int afs_deliver_fs_fetch_data(struct afs_call *call) 3008c2ecf20Sopenharmony_ci{ 3018c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 3028c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 3038c2ecf20Sopenharmony_ci struct afs_read *req = op->fetch.req; 3048c2ecf20Sopenharmony_ci const __be32 *bp; 3058c2ecf20Sopenharmony_ci unsigned int size; 3068c2ecf20Sopenharmony_ci int ret; 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci _enter("{%u,%zu/%llu}", 3098c2ecf20Sopenharmony_ci call->unmarshall, iov_iter_count(call->iter), req->actual_len); 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci switch (call->unmarshall) { 3128c2ecf20Sopenharmony_ci case 0: 3138c2ecf20Sopenharmony_ci req->actual_len = 0; 3148c2ecf20Sopenharmony_ci req->index = 0; 3158c2ecf20Sopenharmony_ci req->offset = req->pos & (PAGE_SIZE - 1); 3168c2ecf20Sopenharmony_ci call->unmarshall++; 3178c2ecf20Sopenharmony_ci if (call->operation_ID == FSFETCHDATA64) { 3188c2ecf20Sopenharmony_ci afs_extract_to_tmp64(call); 3198c2ecf20Sopenharmony_ci } else { 3208c2ecf20Sopenharmony_ci call->tmp_u = htonl(0); 3218c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci fallthrough; 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci /* extract the returned data length */ 3268c2ecf20Sopenharmony_ci case 1: 3278c2ecf20Sopenharmony_ci _debug("extract data length"); 3288c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 3298c2ecf20Sopenharmony_ci if (ret < 0) 3308c2ecf20Sopenharmony_ci return ret; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci req->actual_len = be64_to_cpu(call->tmp64); 3338c2ecf20Sopenharmony_ci _debug("DATA length: %llu", req->actual_len); 3348c2ecf20Sopenharmony_ci req->remain = min(req->len, req->actual_len); 3358c2ecf20Sopenharmony_ci if (req->remain == 0) 3368c2ecf20Sopenharmony_ci goto no_more_data; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci call->unmarshall++; 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci begin_page: 3418c2ecf20Sopenharmony_ci ASSERTCMP(req->index, <, req->nr_pages); 3428c2ecf20Sopenharmony_ci if (req->remain > PAGE_SIZE - req->offset) 3438c2ecf20Sopenharmony_ci size = PAGE_SIZE - req->offset; 3448c2ecf20Sopenharmony_ci else 3458c2ecf20Sopenharmony_ci size = req->remain; 3468c2ecf20Sopenharmony_ci call->bvec[0].bv_len = size; 3478c2ecf20Sopenharmony_ci call->bvec[0].bv_offset = req->offset; 3488c2ecf20Sopenharmony_ci call->bvec[0].bv_page = req->pages[req->index]; 3498c2ecf20Sopenharmony_ci iov_iter_bvec(&call->def_iter, READ, call->bvec, 1, size); 3508c2ecf20Sopenharmony_ci ASSERTCMP(size, <=, PAGE_SIZE); 3518c2ecf20Sopenharmony_ci fallthrough; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci /* extract the returned data */ 3548c2ecf20Sopenharmony_ci case 2: 3558c2ecf20Sopenharmony_ci _debug("extract data %zu/%llu", 3568c2ecf20Sopenharmony_ci iov_iter_count(call->iter), req->remain); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 3598c2ecf20Sopenharmony_ci if (ret < 0) 3608c2ecf20Sopenharmony_ci return ret; 3618c2ecf20Sopenharmony_ci req->remain -= call->bvec[0].bv_len; 3628c2ecf20Sopenharmony_ci req->offset += call->bvec[0].bv_len; 3638c2ecf20Sopenharmony_ci ASSERTCMP(req->offset, <=, PAGE_SIZE); 3648c2ecf20Sopenharmony_ci if (req->offset == PAGE_SIZE) { 3658c2ecf20Sopenharmony_ci req->offset = 0; 3668c2ecf20Sopenharmony_ci req->index++; 3678c2ecf20Sopenharmony_ci if (req->remain > 0) 3688c2ecf20Sopenharmony_ci goto begin_page; 3698c2ecf20Sopenharmony_ci } 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci ASSERTCMP(req->remain, ==, 0); 3728c2ecf20Sopenharmony_ci if (req->actual_len <= req->len) 3738c2ecf20Sopenharmony_ci goto no_more_data; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci /* Discard any excess data the server gave us */ 3768c2ecf20Sopenharmony_ci afs_extract_discard(call, req->actual_len - req->len); 3778c2ecf20Sopenharmony_ci call->unmarshall = 3; 3788c2ecf20Sopenharmony_ci fallthrough; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci case 3: 3818c2ecf20Sopenharmony_ci _debug("extract discard %zu/%llu", 3828c2ecf20Sopenharmony_ci iov_iter_count(call->iter), req->actual_len - req->len); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 3858c2ecf20Sopenharmony_ci if (ret < 0) 3868c2ecf20Sopenharmony_ci return ret; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci no_more_data: 3898c2ecf20Sopenharmony_ci call->unmarshall = 4; 3908c2ecf20Sopenharmony_ci afs_extract_to_buf(call, (21 + 3 + 6) * 4); 3918c2ecf20Sopenharmony_ci fallthrough; 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* extract the metadata */ 3948c2ecf20Sopenharmony_ci case 4: 3958c2ecf20Sopenharmony_ci ret = afs_extract_data(call, false); 3968c2ecf20Sopenharmony_ci if (ret < 0) 3978c2ecf20Sopenharmony_ci return ret; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci bp = call->buffer; 4008c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 4018c2ecf20Sopenharmony_ci xdr_decode_AFSCallBack(&bp, call, &vp->scb); 4028c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci req->data_version = vp->scb.status.data_version; 4058c2ecf20Sopenharmony_ci req->file_size = vp->scb.status.size; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci call->unmarshall++; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci case 5: 4108c2ecf20Sopenharmony_ci break; 4118c2ecf20Sopenharmony_ci } 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci for (; req->index < req->nr_pages; req->index++) { 4148c2ecf20Sopenharmony_ci if (req->offset < PAGE_SIZE) 4158c2ecf20Sopenharmony_ci zero_user_segment(req->pages[req->index], 4168c2ecf20Sopenharmony_ci req->offset, PAGE_SIZE); 4178c2ecf20Sopenharmony_ci req->offset = 0; 4188c2ecf20Sopenharmony_ci } 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci if (req->page_done) 4218c2ecf20Sopenharmony_ci for (req->index = 0; req->index < req->nr_pages; req->index++) 4228c2ecf20Sopenharmony_ci req->page_done(req); 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 4258c2ecf20Sopenharmony_ci return 0; 4268c2ecf20Sopenharmony_ci} 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci/* 4298c2ecf20Sopenharmony_ci * FS.FetchData operation type 4308c2ecf20Sopenharmony_ci */ 4318c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSFetchData = { 4328c2ecf20Sopenharmony_ci .name = "FS.FetchData", 4338c2ecf20Sopenharmony_ci .op = afs_FS_FetchData, 4348c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_fetch_data, 4358c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 4368c2ecf20Sopenharmony_ci}; 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSFetchData64 = { 4398c2ecf20Sopenharmony_ci .name = "FS.FetchData64", 4408c2ecf20Sopenharmony_ci .op = afs_FS_FetchData64, 4418c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_fetch_data, 4428c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 4438c2ecf20Sopenharmony_ci}; 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci/* 4468c2ecf20Sopenharmony_ci * fetch data from a very large file 4478c2ecf20Sopenharmony_ci */ 4488c2ecf20Sopenharmony_cistatic void afs_fs_fetch_data64(struct afs_operation *op) 4498c2ecf20Sopenharmony_ci{ 4508c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 4518c2ecf20Sopenharmony_ci struct afs_read *req = op->fetch.req; 4528c2ecf20Sopenharmony_ci struct afs_call *call; 4538c2ecf20Sopenharmony_ci __be32 *bp; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci _enter(""); 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData64, 32, (21 + 3 + 6) * 4); 4588c2ecf20Sopenharmony_ci if (!call) 4598c2ecf20Sopenharmony_ci return afs_op_nomem(op); 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci /* marshall the parameters */ 4628c2ecf20Sopenharmony_ci bp = call->request; 4638c2ecf20Sopenharmony_ci bp[0] = htonl(FSFETCHDATA64); 4648c2ecf20Sopenharmony_ci bp[1] = htonl(vp->fid.vid); 4658c2ecf20Sopenharmony_ci bp[2] = htonl(vp->fid.vnode); 4668c2ecf20Sopenharmony_ci bp[3] = htonl(vp->fid.unique); 4678c2ecf20Sopenharmony_ci bp[4] = htonl(upper_32_bits(req->pos)); 4688c2ecf20Sopenharmony_ci bp[5] = htonl(lower_32_bits(req->pos)); 4698c2ecf20Sopenharmony_ci bp[6] = 0; 4708c2ecf20Sopenharmony_ci bp[7] = htonl(lower_32_bits(req->len)); 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 4738c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 4748c2ecf20Sopenharmony_ci} 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci/* 4778c2ecf20Sopenharmony_ci * fetch data from a file 4788c2ecf20Sopenharmony_ci */ 4798c2ecf20Sopenharmony_civoid afs_fs_fetch_data(struct afs_operation *op) 4808c2ecf20Sopenharmony_ci{ 4818c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 4828c2ecf20Sopenharmony_ci struct afs_call *call; 4838c2ecf20Sopenharmony_ci struct afs_read *req = op->fetch.req; 4848c2ecf20Sopenharmony_ci __be32 *bp; 4858c2ecf20Sopenharmony_ci 4868c2ecf20Sopenharmony_ci if (upper_32_bits(req->pos) || 4878c2ecf20Sopenharmony_ci upper_32_bits(req->len) || 4888c2ecf20Sopenharmony_ci upper_32_bits(req->pos + req->len)) 4898c2ecf20Sopenharmony_ci return afs_fs_fetch_data64(op); 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci _enter(""); 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSFetchData, 24, (21 + 3 + 6) * 4); 4948c2ecf20Sopenharmony_ci if (!call) 4958c2ecf20Sopenharmony_ci return afs_op_nomem(op); 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci /* marshall the parameters */ 4988c2ecf20Sopenharmony_ci bp = call->request; 4998c2ecf20Sopenharmony_ci bp[0] = htonl(FSFETCHDATA); 5008c2ecf20Sopenharmony_ci bp[1] = htonl(vp->fid.vid); 5018c2ecf20Sopenharmony_ci bp[2] = htonl(vp->fid.vnode); 5028c2ecf20Sopenharmony_ci bp[3] = htonl(vp->fid.unique); 5038c2ecf20Sopenharmony_ci bp[4] = htonl(lower_32_bits(req->pos)); 5048c2ecf20Sopenharmony_ci bp[5] = htonl(lower_32_bits(req->len)); 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 5078c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 5088c2ecf20Sopenharmony_ci} 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci/* 5118c2ecf20Sopenharmony_ci * deliver reply data to an FS.CreateFile or an FS.MakeDir 5128c2ecf20Sopenharmony_ci */ 5138c2ecf20Sopenharmony_cistatic int afs_deliver_fs_create_vnode(struct afs_call *call) 5148c2ecf20Sopenharmony_ci{ 5158c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 5168c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 5178c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[1]; 5188c2ecf20Sopenharmony_ci const __be32 *bp; 5198c2ecf20Sopenharmony_ci int ret; 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 5228c2ecf20Sopenharmony_ci if (ret < 0) 5238c2ecf20Sopenharmony_ci return ret; 5248c2ecf20Sopenharmony_ci 5258c2ecf20Sopenharmony_ci /* unmarshall the reply once we've received all of it */ 5268c2ecf20Sopenharmony_ci bp = call->buffer; 5278c2ecf20Sopenharmony_ci xdr_decode_AFSFid(&bp, &op->file[1].fid); 5288c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 5298c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb); 5308c2ecf20Sopenharmony_ci xdr_decode_AFSCallBack(&bp, call, &vp->scb); 5318c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 5348c2ecf20Sopenharmony_ci return 0; 5358c2ecf20Sopenharmony_ci} 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci/* 5388c2ecf20Sopenharmony_ci * FS.CreateFile and FS.MakeDir operation type 5398c2ecf20Sopenharmony_ci */ 5408c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSCreateFile = { 5418c2ecf20Sopenharmony_ci .name = "FS.CreateFile", 5428c2ecf20Sopenharmony_ci .op = afs_FS_CreateFile, 5438c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_create_vnode, 5448c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 5458c2ecf20Sopenharmony_ci}; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci/* 5488c2ecf20Sopenharmony_ci * Create a file. 5498c2ecf20Sopenharmony_ci */ 5508c2ecf20Sopenharmony_civoid afs_fs_create_file(struct afs_operation *op) 5518c2ecf20Sopenharmony_ci{ 5528c2ecf20Sopenharmony_ci const struct qstr *name = &op->dentry->d_name; 5538c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 5548c2ecf20Sopenharmony_ci struct afs_call *call; 5558c2ecf20Sopenharmony_ci size_t namesz, reqsz, padsz; 5568c2ecf20Sopenharmony_ci __be32 *bp; 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci _enter(""); 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci namesz = name->len; 5618c2ecf20Sopenharmony_ci padsz = (4 - (namesz & 3)) & 3; 5628c2ecf20Sopenharmony_ci reqsz = (5 * 4) + namesz + padsz + (6 * 4); 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, 5658c2ecf20Sopenharmony_ci reqsz, (3 + 21 + 21 + 3 + 6) * 4); 5668c2ecf20Sopenharmony_ci if (!call) 5678c2ecf20Sopenharmony_ci return afs_op_nomem(op); 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci /* marshall the parameters */ 5708c2ecf20Sopenharmony_ci bp = call->request; 5718c2ecf20Sopenharmony_ci *bp++ = htonl(FSCREATEFILE); 5728c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vid); 5738c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vnode); 5748c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.unique); 5758c2ecf20Sopenharmony_ci *bp++ = htonl(namesz); 5768c2ecf20Sopenharmony_ci memcpy(bp, name->name, namesz); 5778c2ecf20Sopenharmony_ci bp = (void *) bp + namesz; 5788c2ecf20Sopenharmony_ci if (padsz > 0) { 5798c2ecf20Sopenharmony_ci memset(bp, 0, padsz); 5808c2ecf20Sopenharmony_ci bp = (void *) bp + padsz; 5818c2ecf20Sopenharmony_ci } 5828c2ecf20Sopenharmony_ci *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); 5838c2ecf20Sopenharmony_ci *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 5848c2ecf20Sopenharmony_ci *bp++ = 0; /* owner */ 5858c2ecf20Sopenharmony_ci *bp++ = 0; /* group */ 5868c2ecf20Sopenharmony_ci *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */ 5878c2ecf20Sopenharmony_ci *bp++ = 0; /* segment size */ 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci trace_afs_make_fs_call1(call, &dvp->fid, name); 5908c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSMakeDir = { 5948c2ecf20Sopenharmony_ci .name = "FS.MakeDir", 5958c2ecf20Sopenharmony_ci .op = afs_FS_MakeDir, 5968c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_create_vnode, 5978c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 5988c2ecf20Sopenharmony_ci}; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci/* 6018c2ecf20Sopenharmony_ci * Create a new directory 6028c2ecf20Sopenharmony_ci */ 6038c2ecf20Sopenharmony_civoid afs_fs_make_dir(struct afs_operation *op) 6048c2ecf20Sopenharmony_ci{ 6058c2ecf20Sopenharmony_ci const struct qstr *name = &op->dentry->d_name; 6068c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 6078c2ecf20Sopenharmony_ci struct afs_call *call; 6088c2ecf20Sopenharmony_ci size_t namesz, reqsz, padsz; 6098c2ecf20Sopenharmony_ci __be32 *bp; 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci _enter(""); 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci namesz = name->len; 6148c2ecf20Sopenharmony_ci padsz = (4 - (namesz & 3)) & 3; 6158c2ecf20Sopenharmony_ci reqsz = (5 * 4) + namesz + padsz + (6 * 4); 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSMakeDir, 6188c2ecf20Sopenharmony_ci reqsz, (3 + 21 + 21 + 3 + 6) * 4); 6198c2ecf20Sopenharmony_ci if (!call) 6208c2ecf20Sopenharmony_ci return afs_op_nomem(op); 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci /* marshall the parameters */ 6238c2ecf20Sopenharmony_ci bp = call->request; 6248c2ecf20Sopenharmony_ci *bp++ = htonl(FSMAKEDIR); 6258c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vid); 6268c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vnode); 6278c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.unique); 6288c2ecf20Sopenharmony_ci *bp++ = htonl(namesz); 6298c2ecf20Sopenharmony_ci memcpy(bp, name->name, namesz); 6308c2ecf20Sopenharmony_ci bp = (void *) bp + namesz; 6318c2ecf20Sopenharmony_ci if (padsz > 0) { 6328c2ecf20Sopenharmony_ci memset(bp, 0, padsz); 6338c2ecf20Sopenharmony_ci bp = (void *) bp + padsz; 6348c2ecf20Sopenharmony_ci } 6358c2ecf20Sopenharmony_ci *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); 6368c2ecf20Sopenharmony_ci *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 6378c2ecf20Sopenharmony_ci *bp++ = 0; /* owner */ 6388c2ecf20Sopenharmony_ci *bp++ = 0; /* group */ 6398c2ecf20Sopenharmony_ci *bp++ = htonl(op->create.mode & S_IALLUGO); /* unix mode */ 6408c2ecf20Sopenharmony_ci *bp++ = 0; /* segment size */ 6418c2ecf20Sopenharmony_ci 6428c2ecf20Sopenharmony_ci trace_afs_make_fs_call1(call, &dvp->fid, name); 6438c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 6448c2ecf20Sopenharmony_ci} 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci/* 6478c2ecf20Sopenharmony_ci * Deliver reply data to any operation that returns status and volume sync. 6488c2ecf20Sopenharmony_ci */ 6498c2ecf20Sopenharmony_cistatic int afs_deliver_fs_file_status_and_vol(struct afs_call *call) 6508c2ecf20Sopenharmony_ci{ 6518c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 6528c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 6538c2ecf20Sopenharmony_ci const __be32 *bp; 6548c2ecf20Sopenharmony_ci int ret; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 6578c2ecf20Sopenharmony_ci if (ret < 0) 6588c2ecf20Sopenharmony_ci return ret; 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci /* unmarshall the reply once we've received all of it */ 6618c2ecf20Sopenharmony_ci bp = call->buffer; 6628c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 6638c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 6668c2ecf20Sopenharmony_ci return 0; 6678c2ecf20Sopenharmony_ci} 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci/* 6708c2ecf20Sopenharmony_ci * FS.RemoveFile operation type 6718c2ecf20Sopenharmony_ci */ 6728c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSRemoveFile = { 6738c2ecf20Sopenharmony_ci .name = "FS.RemoveFile", 6748c2ecf20Sopenharmony_ci .op = afs_FS_RemoveFile, 6758c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_file_status_and_vol, 6768c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 6778c2ecf20Sopenharmony_ci}; 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci/* 6808c2ecf20Sopenharmony_ci * Remove a file. 6818c2ecf20Sopenharmony_ci */ 6828c2ecf20Sopenharmony_civoid afs_fs_remove_file(struct afs_operation *op) 6838c2ecf20Sopenharmony_ci{ 6848c2ecf20Sopenharmony_ci const struct qstr *name = &op->dentry->d_name; 6858c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 6868c2ecf20Sopenharmony_ci struct afs_call *call; 6878c2ecf20Sopenharmony_ci size_t namesz, reqsz, padsz; 6888c2ecf20Sopenharmony_ci __be32 *bp; 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci _enter(""); 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci namesz = name->len; 6938c2ecf20Sopenharmony_ci padsz = (4 - (namesz & 3)) & 3; 6948c2ecf20Sopenharmony_ci reqsz = (5 * 4) + namesz + padsz; 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveFile, 6978c2ecf20Sopenharmony_ci reqsz, (21 + 6) * 4); 6988c2ecf20Sopenharmony_ci if (!call) 6998c2ecf20Sopenharmony_ci return afs_op_nomem(op); 7008c2ecf20Sopenharmony_ci 7018c2ecf20Sopenharmony_ci /* marshall the parameters */ 7028c2ecf20Sopenharmony_ci bp = call->request; 7038c2ecf20Sopenharmony_ci *bp++ = htonl(FSREMOVEFILE); 7048c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vid); 7058c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vnode); 7068c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.unique); 7078c2ecf20Sopenharmony_ci *bp++ = htonl(namesz); 7088c2ecf20Sopenharmony_ci memcpy(bp, name->name, namesz); 7098c2ecf20Sopenharmony_ci bp = (void *) bp + namesz; 7108c2ecf20Sopenharmony_ci if (padsz > 0) { 7118c2ecf20Sopenharmony_ci memset(bp, 0, padsz); 7128c2ecf20Sopenharmony_ci bp = (void *) bp + padsz; 7138c2ecf20Sopenharmony_ci } 7148c2ecf20Sopenharmony_ci 7158c2ecf20Sopenharmony_ci trace_afs_make_fs_call1(call, &dvp->fid, name); 7168c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 7178c2ecf20Sopenharmony_ci} 7188c2ecf20Sopenharmony_ci 7198c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSRemoveDir = { 7208c2ecf20Sopenharmony_ci .name = "FS.RemoveDir", 7218c2ecf20Sopenharmony_ci .op = afs_FS_RemoveDir, 7228c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_file_status_and_vol, 7238c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 7248c2ecf20Sopenharmony_ci}; 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci/* 7278c2ecf20Sopenharmony_ci * Remove a directory. 7288c2ecf20Sopenharmony_ci */ 7298c2ecf20Sopenharmony_civoid afs_fs_remove_dir(struct afs_operation *op) 7308c2ecf20Sopenharmony_ci{ 7318c2ecf20Sopenharmony_ci const struct qstr *name = &op->dentry->d_name; 7328c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 7338c2ecf20Sopenharmony_ci struct afs_call *call; 7348c2ecf20Sopenharmony_ci size_t namesz, reqsz, padsz; 7358c2ecf20Sopenharmony_ci __be32 *bp; 7368c2ecf20Sopenharmony_ci 7378c2ecf20Sopenharmony_ci _enter(""); 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci namesz = name->len; 7408c2ecf20Sopenharmony_ci padsz = (4 - (namesz & 3)) & 3; 7418c2ecf20Sopenharmony_ci reqsz = (5 * 4) + namesz + padsz; 7428c2ecf20Sopenharmony_ci 7438c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSRemoveDir, 7448c2ecf20Sopenharmony_ci reqsz, (21 + 6) * 4); 7458c2ecf20Sopenharmony_ci if (!call) 7468c2ecf20Sopenharmony_ci return afs_op_nomem(op); 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci /* marshall the parameters */ 7498c2ecf20Sopenharmony_ci bp = call->request; 7508c2ecf20Sopenharmony_ci *bp++ = htonl(FSREMOVEDIR); 7518c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vid); 7528c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vnode); 7538c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.unique); 7548c2ecf20Sopenharmony_ci *bp++ = htonl(namesz); 7558c2ecf20Sopenharmony_ci memcpy(bp, name->name, namesz); 7568c2ecf20Sopenharmony_ci bp = (void *) bp + namesz; 7578c2ecf20Sopenharmony_ci if (padsz > 0) { 7588c2ecf20Sopenharmony_ci memset(bp, 0, padsz); 7598c2ecf20Sopenharmony_ci bp = (void *) bp + padsz; 7608c2ecf20Sopenharmony_ci } 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_ci trace_afs_make_fs_call1(call, &dvp->fid, name); 7638c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 7648c2ecf20Sopenharmony_ci} 7658c2ecf20Sopenharmony_ci 7668c2ecf20Sopenharmony_ci/* 7678c2ecf20Sopenharmony_ci * deliver reply data to an FS.Link 7688c2ecf20Sopenharmony_ci */ 7698c2ecf20Sopenharmony_cistatic int afs_deliver_fs_link(struct afs_call *call) 7708c2ecf20Sopenharmony_ci{ 7718c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 7728c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 7738c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[1]; 7748c2ecf20Sopenharmony_ci const __be32 *bp; 7758c2ecf20Sopenharmony_ci int ret; 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_ci _enter("{%u}", call->unmarshall); 7788c2ecf20Sopenharmony_ci 7798c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 7808c2ecf20Sopenharmony_ci if (ret < 0) 7818c2ecf20Sopenharmony_ci return ret; 7828c2ecf20Sopenharmony_ci 7838c2ecf20Sopenharmony_ci /* unmarshall the reply once we've received all of it */ 7848c2ecf20Sopenharmony_ci bp = call->buffer; 7858c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 7868c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb); 7878c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 7908c2ecf20Sopenharmony_ci return 0; 7918c2ecf20Sopenharmony_ci} 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci/* 7948c2ecf20Sopenharmony_ci * FS.Link operation type 7958c2ecf20Sopenharmony_ci */ 7968c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSLink = { 7978c2ecf20Sopenharmony_ci .name = "FS.Link", 7988c2ecf20Sopenharmony_ci .op = afs_FS_Link, 7998c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_link, 8008c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 8018c2ecf20Sopenharmony_ci}; 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_ci/* 8048c2ecf20Sopenharmony_ci * make a hard link 8058c2ecf20Sopenharmony_ci */ 8068c2ecf20Sopenharmony_civoid afs_fs_link(struct afs_operation *op) 8078c2ecf20Sopenharmony_ci{ 8088c2ecf20Sopenharmony_ci const struct qstr *name = &op->dentry->d_name; 8098c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 8108c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[1]; 8118c2ecf20Sopenharmony_ci struct afs_call *call; 8128c2ecf20Sopenharmony_ci size_t namesz, reqsz, padsz; 8138c2ecf20Sopenharmony_ci __be32 *bp; 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci _enter(""); 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci namesz = name->len; 8188c2ecf20Sopenharmony_ci padsz = (4 - (namesz & 3)) & 3; 8198c2ecf20Sopenharmony_ci reqsz = (5 * 4) + namesz + padsz + (3 * 4); 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSLink, reqsz, (21 + 21 + 6) * 4); 8228c2ecf20Sopenharmony_ci if (!call) 8238c2ecf20Sopenharmony_ci return afs_op_nomem(op); 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_ci /* marshall the parameters */ 8268c2ecf20Sopenharmony_ci bp = call->request; 8278c2ecf20Sopenharmony_ci *bp++ = htonl(FSLINK); 8288c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vid); 8298c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vnode); 8308c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.unique); 8318c2ecf20Sopenharmony_ci *bp++ = htonl(namesz); 8328c2ecf20Sopenharmony_ci memcpy(bp, name->name, namesz); 8338c2ecf20Sopenharmony_ci bp = (void *) bp + namesz; 8348c2ecf20Sopenharmony_ci if (padsz > 0) { 8358c2ecf20Sopenharmony_ci memset(bp, 0, padsz); 8368c2ecf20Sopenharmony_ci bp = (void *) bp + padsz; 8378c2ecf20Sopenharmony_ci } 8388c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 8398c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 8408c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ci trace_afs_make_fs_call1(call, &vp->fid, name); 8438c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 8448c2ecf20Sopenharmony_ci} 8458c2ecf20Sopenharmony_ci 8468c2ecf20Sopenharmony_ci/* 8478c2ecf20Sopenharmony_ci * deliver reply data to an FS.Symlink 8488c2ecf20Sopenharmony_ci */ 8498c2ecf20Sopenharmony_cistatic int afs_deliver_fs_symlink(struct afs_call *call) 8508c2ecf20Sopenharmony_ci{ 8518c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 8528c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 8538c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[1]; 8548c2ecf20Sopenharmony_ci const __be32 *bp; 8558c2ecf20Sopenharmony_ci int ret; 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci _enter("{%u}", call->unmarshall); 8588c2ecf20Sopenharmony_ci 8598c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 8608c2ecf20Sopenharmony_ci if (ret < 0) 8618c2ecf20Sopenharmony_ci return ret; 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci /* unmarshall the reply once we've received all of it */ 8648c2ecf20Sopenharmony_ci bp = call->buffer; 8658c2ecf20Sopenharmony_ci xdr_decode_AFSFid(&bp, &vp->fid); 8668c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 8678c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &dvp->scb); 8688c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 8698c2ecf20Sopenharmony_ci 8708c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 8718c2ecf20Sopenharmony_ci return 0; 8728c2ecf20Sopenharmony_ci} 8738c2ecf20Sopenharmony_ci 8748c2ecf20Sopenharmony_ci/* 8758c2ecf20Sopenharmony_ci * FS.Symlink operation type 8768c2ecf20Sopenharmony_ci */ 8778c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSSymlink = { 8788c2ecf20Sopenharmony_ci .name = "FS.Symlink", 8798c2ecf20Sopenharmony_ci .op = afs_FS_Symlink, 8808c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_symlink, 8818c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 8828c2ecf20Sopenharmony_ci}; 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci/* 8858c2ecf20Sopenharmony_ci * create a symbolic link 8868c2ecf20Sopenharmony_ci */ 8878c2ecf20Sopenharmony_civoid afs_fs_symlink(struct afs_operation *op) 8888c2ecf20Sopenharmony_ci{ 8898c2ecf20Sopenharmony_ci const struct qstr *name = &op->dentry->d_name; 8908c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 8918c2ecf20Sopenharmony_ci struct afs_call *call; 8928c2ecf20Sopenharmony_ci size_t namesz, reqsz, padsz, c_namesz, c_padsz; 8938c2ecf20Sopenharmony_ci __be32 *bp; 8948c2ecf20Sopenharmony_ci 8958c2ecf20Sopenharmony_ci _enter(""); 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ci namesz = name->len; 8988c2ecf20Sopenharmony_ci padsz = (4 - (namesz & 3)) & 3; 8998c2ecf20Sopenharmony_ci 9008c2ecf20Sopenharmony_ci c_namesz = strlen(op->create.symlink); 9018c2ecf20Sopenharmony_ci c_padsz = (4 - (c_namesz & 3)) & 3; 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci reqsz = (6 * 4) + namesz + padsz + c_namesz + c_padsz + (6 * 4); 9048c2ecf20Sopenharmony_ci 9058c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSSymlink, reqsz, 9068c2ecf20Sopenharmony_ci (3 + 21 + 21 + 6) * 4); 9078c2ecf20Sopenharmony_ci if (!call) 9088c2ecf20Sopenharmony_ci return afs_op_nomem(op); 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci /* marshall the parameters */ 9118c2ecf20Sopenharmony_ci bp = call->request; 9128c2ecf20Sopenharmony_ci *bp++ = htonl(FSSYMLINK); 9138c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vid); 9148c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vnode); 9158c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.unique); 9168c2ecf20Sopenharmony_ci *bp++ = htonl(namesz); 9178c2ecf20Sopenharmony_ci memcpy(bp, name->name, namesz); 9188c2ecf20Sopenharmony_ci bp = (void *) bp + namesz; 9198c2ecf20Sopenharmony_ci if (padsz > 0) { 9208c2ecf20Sopenharmony_ci memset(bp, 0, padsz); 9218c2ecf20Sopenharmony_ci bp = (void *) bp + padsz; 9228c2ecf20Sopenharmony_ci } 9238c2ecf20Sopenharmony_ci *bp++ = htonl(c_namesz); 9248c2ecf20Sopenharmony_ci memcpy(bp, op->create.symlink, c_namesz); 9258c2ecf20Sopenharmony_ci bp = (void *) bp + c_namesz; 9268c2ecf20Sopenharmony_ci if (c_padsz > 0) { 9278c2ecf20Sopenharmony_ci memset(bp, 0, c_padsz); 9288c2ecf20Sopenharmony_ci bp = (void *) bp + c_padsz; 9298c2ecf20Sopenharmony_ci } 9308c2ecf20Sopenharmony_ci *bp++ = htonl(AFS_SET_MODE | AFS_SET_MTIME); 9318c2ecf20Sopenharmony_ci *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 9328c2ecf20Sopenharmony_ci *bp++ = 0; /* owner */ 9338c2ecf20Sopenharmony_ci *bp++ = 0; /* group */ 9348c2ecf20Sopenharmony_ci *bp++ = htonl(S_IRWXUGO); /* unix mode */ 9358c2ecf20Sopenharmony_ci *bp++ = 0; /* segment size */ 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci trace_afs_make_fs_call1(call, &dvp->fid, name); 9388c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 9398c2ecf20Sopenharmony_ci} 9408c2ecf20Sopenharmony_ci 9418c2ecf20Sopenharmony_ci/* 9428c2ecf20Sopenharmony_ci * deliver reply data to an FS.Rename 9438c2ecf20Sopenharmony_ci */ 9448c2ecf20Sopenharmony_cistatic int afs_deliver_fs_rename(struct afs_call *call) 9458c2ecf20Sopenharmony_ci{ 9468c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 9478c2ecf20Sopenharmony_ci struct afs_vnode_param *orig_dvp = &op->file[0]; 9488c2ecf20Sopenharmony_ci struct afs_vnode_param *new_dvp = &op->file[1]; 9498c2ecf20Sopenharmony_ci const __be32 *bp; 9508c2ecf20Sopenharmony_ci int ret; 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 9538c2ecf20Sopenharmony_ci if (ret < 0) 9548c2ecf20Sopenharmony_ci return ret; 9558c2ecf20Sopenharmony_ci 9568c2ecf20Sopenharmony_ci bp = call->buffer; 9578c2ecf20Sopenharmony_ci /* If the two dirs are the same, we have two copies of the same status 9588c2ecf20Sopenharmony_ci * report, so we just decode it twice. 9598c2ecf20Sopenharmony_ci */ 9608c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &orig_dvp->scb); 9618c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &new_dvp->scb); 9628c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 9638c2ecf20Sopenharmony_ci 9648c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 9658c2ecf20Sopenharmony_ci return 0; 9668c2ecf20Sopenharmony_ci} 9678c2ecf20Sopenharmony_ci 9688c2ecf20Sopenharmony_ci/* 9698c2ecf20Sopenharmony_ci * FS.Rename operation type 9708c2ecf20Sopenharmony_ci */ 9718c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSRename = { 9728c2ecf20Sopenharmony_ci .name = "FS.Rename", 9738c2ecf20Sopenharmony_ci .op = afs_FS_Rename, 9748c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_rename, 9758c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 9768c2ecf20Sopenharmony_ci}; 9778c2ecf20Sopenharmony_ci 9788c2ecf20Sopenharmony_ci/* 9798c2ecf20Sopenharmony_ci * Rename/move a file or directory. 9808c2ecf20Sopenharmony_ci */ 9818c2ecf20Sopenharmony_civoid afs_fs_rename(struct afs_operation *op) 9828c2ecf20Sopenharmony_ci{ 9838c2ecf20Sopenharmony_ci struct afs_vnode_param *orig_dvp = &op->file[0]; 9848c2ecf20Sopenharmony_ci struct afs_vnode_param *new_dvp = &op->file[1]; 9858c2ecf20Sopenharmony_ci const struct qstr *orig_name = &op->dentry->d_name; 9868c2ecf20Sopenharmony_ci const struct qstr *new_name = &op->dentry_2->d_name; 9878c2ecf20Sopenharmony_ci struct afs_call *call; 9888c2ecf20Sopenharmony_ci size_t reqsz, o_namesz, o_padsz, n_namesz, n_padsz; 9898c2ecf20Sopenharmony_ci __be32 *bp; 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci _enter(""); 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci o_namesz = orig_name->len; 9948c2ecf20Sopenharmony_ci o_padsz = (4 - (o_namesz & 3)) & 3; 9958c2ecf20Sopenharmony_ci 9968c2ecf20Sopenharmony_ci n_namesz = new_name->len; 9978c2ecf20Sopenharmony_ci n_padsz = (4 - (n_namesz & 3)) & 3; 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci reqsz = (4 * 4) + 10008c2ecf20Sopenharmony_ci 4 + o_namesz + o_padsz + 10018c2ecf20Sopenharmony_ci (3 * 4) + 10028c2ecf20Sopenharmony_ci 4 + n_namesz + n_padsz; 10038c2ecf20Sopenharmony_ci 10048c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSRename, reqsz, (21 + 21 + 6) * 4); 10058c2ecf20Sopenharmony_ci if (!call) 10068c2ecf20Sopenharmony_ci return afs_op_nomem(op); 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci /* marshall the parameters */ 10098c2ecf20Sopenharmony_ci bp = call->request; 10108c2ecf20Sopenharmony_ci *bp++ = htonl(FSRENAME); 10118c2ecf20Sopenharmony_ci *bp++ = htonl(orig_dvp->fid.vid); 10128c2ecf20Sopenharmony_ci *bp++ = htonl(orig_dvp->fid.vnode); 10138c2ecf20Sopenharmony_ci *bp++ = htonl(orig_dvp->fid.unique); 10148c2ecf20Sopenharmony_ci *bp++ = htonl(o_namesz); 10158c2ecf20Sopenharmony_ci memcpy(bp, orig_name->name, o_namesz); 10168c2ecf20Sopenharmony_ci bp = (void *) bp + o_namesz; 10178c2ecf20Sopenharmony_ci if (o_padsz > 0) { 10188c2ecf20Sopenharmony_ci memset(bp, 0, o_padsz); 10198c2ecf20Sopenharmony_ci bp = (void *) bp + o_padsz; 10208c2ecf20Sopenharmony_ci } 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci *bp++ = htonl(new_dvp->fid.vid); 10238c2ecf20Sopenharmony_ci *bp++ = htonl(new_dvp->fid.vnode); 10248c2ecf20Sopenharmony_ci *bp++ = htonl(new_dvp->fid.unique); 10258c2ecf20Sopenharmony_ci *bp++ = htonl(n_namesz); 10268c2ecf20Sopenharmony_ci memcpy(bp, new_name->name, n_namesz); 10278c2ecf20Sopenharmony_ci bp = (void *) bp + n_namesz; 10288c2ecf20Sopenharmony_ci if (n_padsz > 0) { 10298c2ecf20Sopenharmony_ci memset(bp, 0, n_padsz); 10308c2ecf20Sopenharmony_ci bp = (void *) bp + n_padsz; 10318c2ecf20Sopenharmony_ci } 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_ci trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name); 10348c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 10358c2ecf20Sopenharmony_ci} 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci/* 10388c2ecf20Sopenharmony_ci * Deliver reply data to FS.StoreData or FS.StoreStatus 10398c2ecf20Sopenharmony_ci */ 10408c2ecf20Sopenharmony_cistatic int afs_deliver_fs_store_data(struct afs_call *call) 10418c2ecf20Sopenharmony_ci{ 10428c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 10438c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 10448c2ecf20Sopenharmony_ci const __be32 *bp; 10458c2ecf20Sopenharmony_ci int ret; 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_ci _enter(""); 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 10508c2ecf20Sopenharmony_ci if (ret < 0) 10518c2ecf20Sopenharmony_ci return ret; 10528c2ecf20Sopenharmony_ci 10538c2ecf20Sopenharmony_ci /* unmarshall the reply once we've received all of it */ 10548c2ecf20Sopenharmony_ci bp = call->buffer; 10558c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 10568c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 10598c2ecf20Sopenharmony_ci return 0; 10608c2ecf20Sopenharmony_ci} 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_ci/* 10638c2ecf20Sopenharmony_ci * FS.StoreData operation type 10648c2ecf20Sopenharmony_ci */ 10658c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSStoreData = { 10668c2ecf20Sopenharmony_ci .name = "FS.StoreData", 10678c2ecf20Sopenharmony_ci .op = afs_FS_StoreData, 10688c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_store_data, 10698c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 10708c2ecf20Sopenharmony_ci}; 10718c2ecf20Sopenharmony_ci 10728c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSStoreData64 = { 10738c2ecf20Sopenharmony_ci .name = "FS.StoreData64", 10748c2ecf20Sopenharmony_ci .op = afs_FS_StoreData64, 10758c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_store_data, 10768c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 10778c2ecf20Sopenharmony_ci}; 10788c2ecf20Sopenharmony_ci 10798c2ecf20Sopenharmony_ci/* 10808c2ecf20Sopenharmony_ci * store a set of pages to a very large file 10818c2ecf20Sopenharmony_ci */ 10828c2ecf20Sopenharmony_cistatic void afs_fs_store_data64(struct afs_operation *op, 10838c2ecf20Sopenharmony_ci loff_t pos, loff_t size, loff_t i_size) 10848c2ecf20Sopenharmony_ci{ 10858c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 10868c2ecf20Sopenharmony_ci struct afs_call *call; 10878c2ecf20Sopenharmony_ci __be32 *bp; 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 10908c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64, 10938c2ecf20Sopenharmony_ci (4 + 6 + 3 * 2) * 4, 10948c2ecf20Sopenharmony_ci (21 + 6) * 4); 10958c2ecf20Sopenharmony_ci if (!call) 10968c2ecf20Sopenharmony_ci return afs_op_nomem(op); 10978c2ecf20Sopenharmony_ci 10988c2ecf20Sopenharmony_ci call->send_pages = true; 10998c2ecf20Sopenharmony_ci 11008c2ecf20Sopenharmony_ci /* marshall the parameters */ 11018c2ecf20Sopenharmony_ci bp = call->request; 11028c2ecf20Sopenharmony_ci *bp++ = htonl(FSSTOREDATA64); 11038c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 11048c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 11058c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 11068c2ecf20Sopenharmony_ci 11078c2ecf20Sopenharmony_ci *bp++ = htonl(AFS_SET_MTIME); /* mask */ 11088c2ecf20Sopenharmony_ci *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 11098c2ecf20Sopenharmony_ci *bp++ = 0; /* owner */ 11108c2ecf20Sopenharmony_ci *bp++ = 0; /* group */ 11118c2ecf20Sopenharmony_ci *bp++ = 0; /* unix mode */ 11128c2ecf20Sopenharmony_ci *bp++ = 0; /* segment size */ 11138c2ecf20Sopenharmony_ci 11148c2ecf20Sopenharmony_ci *bp++ = htonl(upper_32_bits(pos)); 11158c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(pos)); 11168c2ecf20Sopenharmony_ci *bp++ = htonl(upper_32_bits(size)); 11178c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(size)); 11188c2ecf20Sopenharmony_ci *bp++ = htonl(upper_32_bits(i_size)); 11198c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(i_size)); 11208c2ecf20Sopenharmony_ci 11218c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 11228c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 11238c2ecf20Sopenharmony_ci} 11248c2ecf20Sopenharmony_ci 11258c2ecf20Sopenharmony_ci/* 11268c2ecf20Sopenharmony_ci * store a set of pages 11278c2ecf20Sopenharmony_ci */ 11288c2ecf20Sopenharmony_civoid afs_fs_store_data(struct afs_operation *op) 11298c2ecf20Sopenharmony_ci{ 11308c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 11318c2ecf20Sopenharmony_ci struct afs_call *call; 11328c2ecf20Sopenharmony_ci loff_t size, pos, i_size; 11338c2ecf20Sopenharmony_ci __be32 *bp; 11348c2ecf20Sopenharmony_ci 11358c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 11368c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci size = (loff_t)op->store.last_to - (loff_t)op->store.first_offset; 11398c2ecf20Sopenharmony_ci if (op->store.first != op->store.last) 11408c2ecf20Sopenharmony_ci size += (loff_t)(op->store.last - op->store.first) << PAGE_SHIFT; 11418c2ecf20Sopenharmony_ci pos = (loff_t)op->store.first << PAGE_SHIFT; 11428c2ecf20Sopenharmony_ci pos += op->store.first_offset; 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_ci i_size = i_size_read(&vp->vnode->vfs_inode); 11458c2ecf20Sopenharmony_ci if (pos + size > i_size) 11468c2ecf20Sopenharmony_ci i_size = size + pos; 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_ci _debug("size %llx, at %llx, i_size %llx", 11498c2ecf20Sopenharmony_ci (unsigned long long) size, (unsigned long long) pos, 11508c2ecf20Sopenharmony_ci (unsigned long long) i_size); 11518c2ecf20Sopenharmony_ci 11528c2ecf20Sopenharmony_ci if (upper_32_bits(pos) || upper_32_bits(i_size) || upper_32_bits(size) || 11538c2ecf20Sopenharmony_ci upper_32_bits(pos + size)) 11548c2ecf20Sopenharmony_ci return afs_fs_store_data64(op, pos, size, i_size); 11558c2ecf20Sopenharmony_ci 11568c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData, 11578c2ecf20Sopenharmony_ci (4 + 6 + 3) * 4, 11588c2ecf20Sopenharmony_ci (21 + 6) * 4); 11598c2ecf20Sopenharmony_ci if (!call) 11608c2ecf20Sopenharmony_ci return afs_op_nomem(op); 11618c2ecf20Sopenharmony_ci 11628c2ecf20Sopenharmony_ci call->send_pages = true; 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci /* marshall the parameters */ 11658c2ecf20Sopenharmony_ci bp = call->request; 11668c2ecf20Sopenharmony_ci *bp++ = htonl(FSSTOREDATA); 11678c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 11688c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 11698c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_ci *bp++ = htonl(AFS_SET_MTIME); /* mask */ 11728c2ecf20Sopenharmony_ci *bp++ = htonl(op->mtime.tv_sec); /* mtime */ 11738c2ecf20Sopenharmony_ci *bp++ = 0; /* owner */ 11748c2ecf20Sopenharmony_ci *bp++ = 0; /* group */ 11758c2ecf20Sopenharmony_ci *bp++ = 0; /* unix mode */ 11768c2ecf20Sopenharmony_ci *bp++ = 0; /* segment size */ 11778c2ecf20Sopenharmony_ci 11788c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(pos)); 11798c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(size)); 11808c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(i_size)); 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 11838c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 11848c2ecf20Sopenharmony_ci} 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_ci/* 11878c2ecf20Sopenharmony_ci * FS.StoreStatus operation type 11888c2ecf20Sopenharmony_ci */ 11898c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSStoreStatus = { 11908c2ecf20Sopenharmony_ci .name = "FS.StoreStatus", 11918c2ecf20Sopenharmony_ci .op = afs_FS_StoreStatus, 11928c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_store_data, 11938c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 11948c2ecf20Sopenharmony_ci}; 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSStoreData_as_Status = { 11978c2ecf20Sopenharmony_ci .name = "FS.StoreData", 11988c2ecf20Sopenharmony_ci .op = afs_FS_StoreData, 11998c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_store_data, 12008c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 12018c2ecf20Sopenharmony_ci}; 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSStoreData64_as_Status = { 12048c2ecf20Sopenharmony_ci .name = "FS.StoreData64", 12058c2ecf20Sopenharmony_ci .op = afs_FS_StoreData64, 12068c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_store_data, 12078c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 12088c2ecf20Sopenharmony_ci}; 12098c2ecf20Sopenharmony_ci 12108c2ecf20Sopenharmony_ci/* 12118c2ecf20Sopenharmony_ci * set the attributes on a very large file, using FS.StoreData rather than 12128c2ecf20Sopenharmony_ci * FS.StoreStatus so as to alter the file size also 12138c2ecf20Sopenharmony_ci */ 12148c2ecf20Sopenharmony_cistatic void afs_fs_setattr_size64(struct afs_operation *op) 12158c2ecf20Sopenharmony_ci{ 12168c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 12178c2ecf20Sopenharmony_ci struct afs_call *call; 12188c2ecf20Sopenharmony_ci struct iattr *attr = op->setattr.attr; 12198c2ecf20Sopenharmony_ci __be32 *bp; 12208c2ecf20Sopenharmony_ci 12218c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 12228c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 12238c2ecf20Sopenharmony_ci 12248c2ecf20Sopenharmony_ci ASSERT(attr->ia_valid & ATTR_SIZE); 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData64_as_Status, 12278c2ecf20Sopenharmony_ci (4 + 6 + 3 * 2) * 4, 12288c2ecf20Sopenharmony_ci (21 + 6) * 4); 12298c2ecf20Sopenharmony_ci if (!call) 12308c2ecf20Sopenharmony_ci return afs_op_nomem(op); 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_ci /* marshall the parameters */ 12338c2ecf20Sopenharmony_ci bp = call->request; 12348c2ecf20Sopenharmony_ci *bp++ = htonl(FSSTOREDATA64); 12358c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 12368c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 12378c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_ci xdr_encode_AFS_StoreStatus(&bp, attr); 12408c2ecf20Sopenharmony_ci 12418c2ecf20Sopenharmony_ci *bp++ = htonl(upper_32_bits(attr->ia_size)); /* position of start of write */ 12428c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(attr->ia_size)); 12438c2ecf20Sopenharmony_ci *bp++ = 0; /* size of write */ 12448c2ecf20Sopenharmony_ci *bp++ = 0; 12458c2ecf20Sopenharmony_ci *bp++ = htonl(upper_32_bits(attr->ia_size)); /* new file length */ 12468c2ecf20Sopenharmony_ci *bp++ = htonl(lower_32_bits(attr->ia_size)); 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 12498c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 12508c2ecf20Sopenharmony_ci} 12518c2ecf20Sopenharmony_ci 12528c2ecf20Sopenharmony_ci/* 12538c2ecf20Sopenharmony_ci * set the attributes on a file, using FS.StoreData rather than FS.StoreStatus 12548c2ecf20Sopenharmony_ci * so as to alter the file size also 12558c2ecf20Sopenharmony_ci */ 12568c2ecf20Sopenharmony_cistatic void afs_fs_setattr_size(struct afs_operation *op) 12578c2ecf20Sopenharmony_ci{ 12588c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 12598c2ecf20Sopenharmony_ci struct afs_call *call; 12608c2ecf20Sopenharmony_ci struct iattr *attr = op->setattr.attr; 12618c2ecf20Sopenharmony_ci __be32 *bp; 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 12648c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_ci ASSERT(attr->ia_valid & ATTR_SIZE); 12678c2ecf20Sopenharmony_ci if (upper_32_bits(attr->ia_size)) 12688c2ecf20Sopenharmony_ci return afs_fs_setattr_size64(op); 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSStoreData_as_Status, 12718c2ecf20Sopenharmony_ci (4 + 6 + 3) * 4, 12728c2ecf20Sopenharmony_ci (21 + 6) * 4); 12738c2ecf20Sopenharmony_ci if (!call) 12748c2ecf20Sopenharmony_ci return afs_op_nomem(op); 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci /* marshall the parameters */ 12778c2ecf20Sopenharmony_ci bp = call->request; 12788c2ecf20Sopenharmony_ci *bp++ = htonl(FSSTOREDATA); 12798c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 12808c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 12818c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 12828c2ecf20Sopenharmony_ci 12838c2ecf20Sopenharmony_ci xdr_encode_AFS_StoreStatus(&bp, attr); 12848c2ecf20Sopenharmony_ci 12858c2ecf20Sopenharmony_ci *bp++ = htonl(attr->ia_size); /* position of start of write */ 12868c2ecf20Sopenharmony_ci *bp++ = 0; /* size of write */ 12878c2ecf20Sopenharmony_ci *bp++ = htonl(attr->ia_size); /* new file length */ 12888c2ecf20Sopenharmony_ci 12898c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 12908c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 12918c2ecf20Sopenharmony_ci} 12928c2ecf20Sopenharmony_ci 12938c2ecf20Sopenharmony_ci/* 12948c2ecf20Sopenharmony_ci * set the attributes on a file, using FS.StoreData if there's a change in file 12958c2ecf20Sopenharmony_ci * size, and FS.StoreStatus otherwise 12968c2ecf20Sopenharmony_ci */ 12978c2ecf20Sopenharmony_civoid afs_fs_setattr(struct afs_operation *op) 12988c2ecf20Sopenharmony_ci{ 12998c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 13008c2ecf20Sopenharmony_ci struct afs_call *call; 13018c2ecf20Sopenharmony_ci struct iattr *attr = op->setattr.attr; 13028c2ecf20Sopenharmony_ci __be32 *bp; 13038c2ecf20Sopenharmony_ci 13048c2ecf20Sopenharmony_ci if (attr->ia_valid & ATTR_SIZE) 13058c2ecf20Sopenharmony_ci return afs_fs_setattr_size(op); 13068c2ecf20Sopenharmony_ci 13078c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 13088c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSStoreStatus, 13118c2ecf20Sopenharmony_ci (4 + 6) * 4, 13128c2ecf20Sopenharmony_ci (21 + 6) * 4); 13138c2ecf20Sopenharmony_ci if (!call) 13148c2ecf20Sopenharmony_ci return afs_op_nomem(op); 13158c2ecf20Sopenharmony_ci 13168c2ecf20Sopenharmony_ci /* marshall the parameters */ 13178c2ecf20Sopenharmony_ci bp = call->request; 13188c2ecf20Sopenharmony_ci *bp++ = htonl(FSSTORESTATUS); 13198c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 13208c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 13218c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 13228c2ecf20Sopenharmony_ci 13238c2ecf20Sopenharmony_ci xdr_encode_AFS_StoreStatus(&bp, op->setattr.attr); 13248c2ecf20Sopenharmony_ci 13258c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 13268c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 13278c2ecf20Sopenharmony_ci} 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_ci/* 13308c2ecf20Sopenharmony_ci * deliver reply data to an FS.GetVolumeStatus 13318c2ecf20Sopenharmony_ci */ 13328c2ecf20Sopenharmony_cistatic int afs_deliver_fs_get_volume_status(struct afs_call *call) 13338c2ecf20Sopenharmony_ci{ 13348c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 13358c2ecf20Sopenharmony_ci const __be32 *bp; 13368c2ecf20Sopenharmony_ci char *p; 13378c2ecf20Sopenharmony_ci u32 size; 13388c2ecf20Sopenharmony_ci int ret; 13398c2ecf20Sopenharmony_ci 13408c2ecf20Sopenharmony_ci _enter("{%u}", call->unmarshall); 13418c2ecf20Sopenharmony_ci 13428c2ecf20Sopenharmony_ci switch (call->unmarshall) { 13438c2ecf20Sopenharmony_ci case 0: 13448c2ecf20Sopenharmony_ci call->unmarshall++; 13458c2ecf20Sopenharmony_ci afs_extract_to_buf(call, 12 * 4); 13468c2ecf20Sopenharmony_ci fallthrough; 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_ci /* extract the returned status record */ 13498c2ecf20Sopenharmony_ci case 1: 13508c2ecf20Sopenharmony_ci _debug("extract status"); 13518c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 13528c2ecf20Sopenharmony_ci if (ret < 0) 13538c2ecf20Sopenharmony_ci return ret; 13548c2ecf20Sopenharmony_ci 13558c2ecf20Sopenharmony_ci bp = call->buffer; 13568c2ecf20Sopenharmony_ci xdr_decode_AFSFetchVolumeStatus(&bp, &op->volstatus.vs); 13578c2ecf20Sopenharmony_ci call->unmarshall++; 13588c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 13598c2ecf20Sopenharmony_ci fallthrough; 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci /* extract the volume name length */ 13628c2ecf20Sopenharmony_ci case 2: 13638c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 13648c2ecf20Sopenharmony_ci if (ret < 0) 13658c2ecf20Sopenharmony_ci return ret; 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci call->count = ntohl(call->tmp); 13688c2ecf20Sopenharmony_ci _debug("volname length: %u", call->count); 13698c2ecf20Sopenharmony_ci if (call->count >= AFSNAMEMAX) 13708c2ecf20Sopenharmony_ci return afs_protocol_error(call, afs_eproto_volname_len); 13718c2ecf20Sopenharmony_ci size = (call->count + 3) & ~3; /* It's padded */ 13728c2ecf20Sopenharmony_ci afs_extract_to_buf(call, size); 13738c2ecf20Sopenharmony_ci call->unmarshall++; 13748c2ecf20Sopenharmony_ci fallthrough; 13758c2ecf20Sopenharmony_ci 13768c2ecf20Sopenharmony_ci /* extract the volume name */ 13778c2ecf20Sopenharmony_ci case 3: 13788c2ecf20Sopenharmony_ci _debug("extract volname"); 13798c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 13808c2ecf20Sopenharmony_ci if (ret < 0) 13818c2ecf20Sopenharmony_ci return ret; 13828c2ecf20Sopenharmony_ci 13838c2ecf20Sopenharmony_ci p = call->buffer; 13848c2ecf20Sopenharmony_ci p[call->count] = 0; 13858c2ecf20Sopenharmony_ci _debug("volname '%s'", p); 13868c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 13878c2ecf20Sopenharmony_ci call->unmarshall++; 13888c2ecf20Sopenharmony_ci fallthrough; 13898c2ecf20Sopenharmony_ci 13908c2ecf20Sopenharmony_ci /* extract the offline message length */ 13918c2ecf20Sopenharmony_ci case 4: 13928c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 13938c2ecf20Sopenharmony_ci if (ret < 0) 13948c2ecf20Sopenharmony_ci return ret; 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_ci call->count = ntohl(call->tmp); 13978c2ecf20Sopenharmony_ci _debug("offline msg length: %u", call->count); 13988c2ecf20Sopenharmony_ci if (call->count >= AFSNAMEMAX) 13998c2ecf20Sopenharmony_ci return afs_protocol_error(call, afs_eproto_offline_msg_len); 14008c2ecf20Sopenharmony_ci size = (call->count + 3) & ~3; /* It's padded */ 14018c2ecf20Sopenharmony_ci afs_extract_to_buf(call, size); 14028c2ecf20Sopenharmony_ci call->unmarshall++; 14038c2ecf20Sopenharmony_ci fallthrough; 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci /* extract the offline message */ 14068c2ecf20Sopenharmony_ci case 5: 14078c2ecf20Sopenharmony_ci _debug("extract offline"); 14088c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 14098c2ecf20Sopenharmony_ci if (ret < 0) 14108c2ecf20Sopenharmony_ci return ret; 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci p = call->buffer; 14138c2ecf20Sopenharmony_ci p[call->count] = 0; 14148c2ecf20Sopenharmony_ci _debug("offline '%s'", p); 14158c2ecf20Sopenharmony_ci 14168c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 14178c2ecf20Sopenharmony_ci call->unmarshall++; 14188c2ecf20Sopenharmony_ci fallthrough; 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_ci /* extract the message of the day length */ 14218c2ecf20Sopenharmony_ci case 6: 14228c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 14238c2ecf20Sopenharmony_ci if (ret < 0) 14248c2ecf20Sopenharmony_ci return ret; 14258c2ecf20Sopenharmony_ci 14268c2ecf20Sopenharmony_ci call->count = ntohl(call->tmp); 14278c2ecf20Sopenharmony_ci _debug("motd length: %u", call->count); 14288c2ecf20Sopenharmony_ci if (call->count >= AFSNAMEMAX) 14298c2ecf20Sopenharmony_ci return afs_protocol_error(call, afs_eproto_motd_len); 14308c2ecf20Sopenharmony_ci size = (call->count + 3) & ~3; /* It's padded */ 14318c2ecf20Sopenharmony_ci afs_extract_to_buf(call, size); 14328c2ecf20Sopenharmony_ci call->unmarshall++; 14338c2ecf20Sopenharmony_ci fallthrough; 14348c2ecf20Sopenharmony_ci 14358c2ecf20Sopenharmony_ci /* extract the message of the day */ 14368c2ecf20Sopenharmony_ci case 7: 14378c2ecf20Sopenharmony_ci _debug("extract motd"); 14388c2ecf20Sopenharmony_ci ret = afs_extract_data(call, false); 14398c2ecf20Sopenharmony_ci if (ret < 0) 14408c2ecf20Sopenharmony_ci return ret; 14418c2ecf20Sopenharmony_ci 14428c2ecf20Sopenharmony_ci p = call->buffer; 14438c2ecf20Sopenharmony_ci p[call->count] = 0; 14448c2ecf20Sopenharmony_ci _debug("motd '%s'", p); 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci call->unmarshall++; 14478c2ecf20Sopenharmony_ci 14488c2ecf20Sopenharmony_ci case 8: 14498c2ecf20Sopenharmony_ci break; 14508c2ecf20Sopenharmony_ci } 14518c2ecf20Sopenharmony_ci 14528c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 14538c2ecf20Sopenharmony_ci return 0; 14548c2ecf20Sopenharmony_ci} 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_ci/* 14578c2ecf20Sopenharmony_ci * FS.GetVolumeStatus operation type 14588c2ecf20Sopenharmony_ci */ 14598c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSGetVolumeStatus = { 14608c2ecf20Sopenharmony_ci .name = "FS.GetVolumeStatus", 14618c2ecf20Sopenharmony_ci .op = afs_FS_GetVolumeStatus, 14628c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_get_volume_status, 14638c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 14648c2ecf20Sopenharmony_ci}; 14658c2ecf20Sopenharmony_ci 14668c2ecf20Sopenharmony_ci/* 14678c2ecf20Sopenharmony_ci * fetch the status of a volume 14688c2ecf20Sopenharmony_ci */ 14698c2ecf20Sopenharmony_civoid afs_fs_get_volume_status(struct afs_operation *op) 14708c2ecf20Sopenharmony_ci{ 14718c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 14728c2ecf20Sopenharmony_ci struct afs_call *call; 14738c2ecf20Sopenharmony_ci __be32 *bp; 14748c2ecf20Sopenharmony_ci 14758c2ecf20Sopenharmony_ci _enter(""); 14768c2ecf20Sopenharmony_ci 14778c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSGetVolumeStatus, 2 * 4, 14788c2ecf20Sopenharmony_ci max(12 * 4, AFSOPAQUEMAX + 1)); 14798c2ecf20Sopenharmony_ci if (!call) 14808c2ecf20Sopenharmony_ci return afs_op_nomem(op); 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci /* marshall the parameters */ 14838c2ecf20Sopenharmony_ci bp = call->request; 14848c2ecf20Sopenharmony_ci bp[0] = htonl(FSGETVOLUMESTATUS); 14858c2ecf20Sopenharmony_ci bp[1] = htonl(vp->fid.vid); 14868c2ecf20Sopenharmony_ci 14878c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 14888c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 14898c2ecf20Sopenharmony_ci} 14908c2ecf20Sopenharmony_ci 14918c2ecf20Sopenharmony_ci/* 14928c2ecf20Sopenharmony_ci * deliver reply data to an FS.SetLock, FS.ExtendLock or FS.ReleaseLock 14938c2ecf20Sopenharmony_ci */ 14948c2ecf20Sopenharmony_cistatic int afs_deliver_fs_xxxx_lock(struct afs_call *call) 14958c2ecf20Sopenharmony_ci{ 14968c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 14978c2ecf20Sopenharmony_ci const __be32 *bp; 14988c2ecf20Sopenharmony_ci int ret; 14998c2ecf20Sopenharmony_ci 15008c2ecf20Sopenharmony_ci _enter("{%u}", call->unmarshall); 15018c2ecf20Sopenharmony_ci 15028c2ecf20Sopenharmony_ci ret = afs_transfer_reply(call); 15038c2ecf20Sopenharmony_ci if (ret < 0) 15048c2ecf20Sopenharmony_ci return ret; 15058c2ecf20Sopenharmony_ci 15068c2ecf20Sopenharmony_ci /* unmarshall the reply once we've received all of it */ 15078c2ecf20Sopenharmony_ci bp = call->buffer; 15088c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 15098c2ecf20Sopenharmony_ci 15108c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 15118c2ecf20Sopenharmony_ci return 0; 15128c2ecf20Sopenharmony_ci} 15138c2ecf20Sopenharmony_ci 15148c2ecf20Sopenharmony_ci/* 15158c2ecf20Sopenharmony_ci * FS.SetLock operation type 15168c2ecf20Sopenharmony_ci */ 15178c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSSetLock = { 15188c2ecf20Sopenharmony_ci .name = "FS.SetLock", 15198c2ecf20Sopenharmony_ci .op = afs_FS_SetLock, 15208c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_xxxx_lock, 15218c2ecf20Sopenharmony_ci .done = afs_lock_op_done, 15228c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 15238c2ecf20Sopenharmony_ci}; 15248c2ecf20Sopenharmony_ci 15258c2ecf20Sopenharmony_ci/* 15268c2ecf20Sopenharmony_ci * FS.ExtendLock operation type 15278c2ecf20Sopenharmony_ci */ 15288c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSExtendLock = { 15298c2ecf20Sopenharmony_ci .name = "FS.ExtendLock", 15308c2ecf20Sopenharmony_ci .op = afs_FS_ExtendLock, 15318c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_xxxx_lock, 15328c2ecf20Sopenharmony_ci .done = afs_lock_op_done, 15338c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 15348c2ecf20Sopenharmony_ci}; 15358c2ecf20Sopenharmony_ci 15368c2ecf20Sopenharmony_ci/* 15378c2ecf20Sopenharmony_ci * FS.ReleaseLock operation type 15388c2ecf20Sopenharmony_ci */ 15398c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSReleaseLock = { 15408c2ecf20Sopenharmony_ci .name = "FS.ReleaseLock", 15418c2ecf20Sopenharmony_ci .op = afs_FS_ReleaseLock, 15428c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_xxxx_lock, 15438c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 15448c2ecf20Sopenharmony_ci}; 15458c2ecf20Sopenharmony_ci 15468c2ecf20Sopenharmony_ci/* 15478c2ecf20Sopenharmony_ci * Set a lock on a file 15488c2ecf20Sopenharmony_ci */ 15498c2ecf20Sopenharmony_civoid afs_fs_set_lock(struct afs_operation *op) 15508c2ecf20Sopenharmony_ci{ 15518c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 15528c2ecf20Sopenharmony_ci struct afs_call *call; 15538c2ecf20Sopenharmony_ci __be32 *bp; 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci _enter(""); 15568c2ecf20Sopenharmony_ci 15578c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSSetLock, 5 * 4, 6 * 4); 15588c2ecf20Sopenharmony_ci if (!call) 15598c2ecf20Sopenharmony_ci return afs_op_nomem(op); 15608c2ecf20Sopenharmony_ci 15618c2ecf20Sopenharmony_ci /* marshall the parameters */ 15628c2ecf20Sopenharmony_ci bp = call->request; 15638c2ecf20Sopenharmony_ci *bp++ = htonl(FSSETLOCK); 15648c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 15658c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 15668c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 15678c2ecf20Sopenharmony_ci *bp++ = htonl(op->lock.type); 15688c2ecf20Sopenharmony_ci 15698c2ecf20Sopenharmony_ci trace_afs_make_fs_calli(call, &vp->fid, op->lock.type); 15708c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 15718c2ecf20Sopenharmony_ci} 15728c2ecf20Sopenharmony_ci 15738c2ecf20Sopenharmony_ci/* 15748c2ecf20Sopenharmony_ci * extend a lock on a file 15758c2ecf20Sopenharmony_ci */ 15768c2ecf20Sopenharmony_civoid afs_fs_extend_lock(struct afs_operation *op) 15778c2ecf20Sopenharmony_ci{ 15788c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 15798c2ecf20Sopenharmony_ci struct afs_call *call; 15808c2ecf20Sopenharmony_ci __be32 *bp; 15818c2ecf20Sopenharmony_ci 15828c2ecf20Sopenharmony_ci _enter(""); 15838c2ecf20Sopenharmony_ci 15848c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSExtendLock, 4 * 4, 6 * 4); 15858c2ecf20Sopenharmony_ci if (!call) 15868c2ecf20Sopenharmony_ci return afs_op_nomem(op); 15878c2ecf20Sopenharmony_ci 15888c2ecf20Sopenharmony_ci /* marshall the parameters */ 15898c2ecf20Sopenharmony_ci bp = call->request; 15908c2ecf20Sopenharmony_ci *bp++ = htonl(FSEXTENDLOCK); 15918c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 15928c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 15938c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 15948c2ecf20Sopenharmony_ci 15958c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 15968c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 15978c2ecf20Sopenharmony_ci} 15988c2ecf20Sopenharmony_ci 15998c2ecf20Sopenharmony_ci/* 16008c2ecf20Sopenharmony_ci * release a lock on a file 16018c2ecf20Sopenharmony_ci */ 16028c2ecf20Sopenharmony_civoid afs_fs_release_lock(struct afs_operation *op) 16038c2ecf20Sopenharmony_ci{ 16048c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 16058c2ecf20Sopenharmony_ci struct afs_call *call; 16068c2ecf20Sopenharmony_ci __be32 *bp; 16078c2ecf20Sopenharmony_ci 16088c2ecf20Sopenharmony_ci _enter(""); 16098c2ecf20Sopenharmony_ci 16108c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSReleaseLock, 4 * 4, 6 * 4); 16118c2ecf20Sopenharmony_ci if (!call) 16128c2ecf20Sopenharmony_ci return afs_op_nomem(op); 16138c2ecf20Sopenharmony_ci 16148c2ecf20Sopenharmony_ci /* marshall the parameters */ 16158c2ecf20Sopenharmony_ci bp = call->request; 16168c2ecf20Sopenharmony_ci *bp++ = htonl(FSRELEASELOCK); 16178c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 16188c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 16198c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 16208c2ecf20Sopenharmony_ci 16218c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 16228c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 16238c2ecf20Sopenharmony_ci} 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_ci/* 16268c2ecf20Sopenharmony_ci * Deliver reply data to an FS.GiveUpAllCallBacks operation. 16278c2ecf20Sopenharmony_ci */ 16288c2ecf20Sopenharmony_cistatic int afs_deliver_fs_give_up_all_callbacks(struct afs_call *call) 16298c2ecf20Sopenharmony_ci{ 16308c2ecf20Sopenharmony_ci return afs_transfer_reply(call); 16318c2ecf20Sopenharmony_ci} 16328c2ecf20Sopenharmony_ci 16338c2ecf20Sopenharmony_ci/* 16348c2ecf20Sopenharmony_ci * FS.GiveUpAllCallBacks operation type 16358c2ecf20Sopenharmony_ci */ 16368c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSGiveUpAllCallBacks = { 16378c2ecf20Sopenharmony_ci .name = "FS.GiveUpAllCallBacks", 16388c2ecf20Sopenharmony_ci .op = afs_FS_GiveUpAllCallBacks, 16398c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_give_up_all_callbacks, 16408c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 16418c2ecf20Sopenharmony_ci}; 16428c2ecf20Sopenharmony_ci 16438c2ecf20Sopenharmony_ci/* 16448c2ecf20Sopenharmony_ci * Flush all the callbacks we have on a server. 16458c2ecf20Sopenharmony_ci */ 16468c2ecf20Sopenharmony_ciint afs_fs_give_up_all_callbacks(struct afs_net *net, 16478c2ecf20Sopenharmony_ci struct afs_server *server, 16488c2ecf20Sopenharmony_ci struct afs_addr_cursor *ac, 16498c2ecf20Sopenharmony_ci struct key *key) 16508c2ecf20Sopenharmony_ci{ 16518c2ecf20Sopenharmony_ci struct afs_call *call; 16528c2ecf20Sopenharmony_ci __be32 *bp; 16538c2ecf20Sopenharmony_ci 16548c2ecf20Sopenharmony_ci _enter(""); 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(net, &afs_RXFSGiveUpAllCallBacks, 1 * 4, 0); 16578c2ecf20Sopenharmony_ci if (!call) 16588c2ecf20Sopenharmony_ci return -ENOMEM; 16598c2ecf20Sopenharmony_ci 16608c2ecf20Sopenharmony_ci call->key = key; 16618c2ecf20Sopenharmony_ci 16628c2ecf20Sopenharmony_ci /* marshall the parameters */ 16638c2ecf20Sopenharmony_ci bp = call->request; 16648c2ecf20Sopenharmony_ci *bp++ = htonl(FSGIVEUPALLCALLBACKS); 16658c2ecf20Sopenharmony_ci 16668c2ecf20Sopenharmony_ci call->server = afs_use_server(server, afs_server_trace_give_up_cb); 16678c2ecf20Sopenharmony_ci afs_make_call(ac, call, GFP_NOFS); 16688c2ecf20Sopenharmony_ci return afs_wait_for_call_to_complete(call, ac); 16698c2ecf20Sopenharmony_ci} 16708c2ecf20Sopenharmony_ci 16718c2ecf20Sopenharmony_ci/* 16728c2ecf20Sopenharmony_ci * Deliver reply data to an FS.GetCapabilities operation. 16738c2ecf20Sopenharmony_ci */ 16748c2ecf20Sopenharmony_cistatic int afs_deliver_fs_get_capabilities(struct afs_call *call) 16758c2ecf20Sopenharmony_ci{ 16768c2ecf20Sopenharmony_ci u32 count; 16778c2ecf20Sopenharmony_ci int ret; 16788c2ecf20Sopenharmony_ci 16798c2ecf20Sopenharmony_ci _enter("{%u,%zu}", call->unmarshall, iov_iter_count(call->iter)); 16808c2ecf20Sopenharmony_ci 16818c2ecf20Sopenharmony_ci switch (call->unmarshall) { 16828c2ecf20Sopenharmony_ci case 0: 16838c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 16848c2ecf20Sopenharmony_ci call->unmarshall++; 16858c2ecf20Sopenharmony_ci fallthrough; 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci /* Extract the capabilities word count */ 16888c2ecf20Sopenharmony_ci case 1: 16898c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 16908c2ecf20Sopenharmony_ci if (ret < 0) 16918c2ecf20Sopenharmony_ci return ret; 16928c2ecf20Sopenharmony_ci 16938c2ecf20Sopenharmony_ci count = ntohl(call->tmp); 16948c2ecf20Sopenharmony_ci 16958c2ecf20Sopenharmony_ci call->count = count; 16968c2ecf20Sopenharmony_ci call->count2 = count; 16978c2ecf20Sopenharmony_ci afs_extract_discard(call, count * sizeof(__be32)); 16988c2ecf20Sopenharmony_ci call->unmarshall++; 16998c2ecf20Sopenharmony_ci fallthrough; 17008c2ecf20Sopenharmony_ci 17018c2ecf20Sopenharmony_ci /* Extract capabilities words */ 17028c2ecf20Sopenharmony_ci case 2: 17038c2ecf20Sopenharmony_ci ret = afs_extract_data(call, false); 17048c2ecf20Sopenharmony_ci if (ret < 0) 17058c2ecf20Sopenharmony_ci return ret; 17068c2ecf20Sopenharmony_ci 17078c2ecf20Sopenharmony_ci /* TODO: Examine capabilities */ 17088c2ecf20Sopenharmony_ci 17098c2ecf20Sopenharmony_ci call->unmarshall++; 17108c2ecf20Sopenharmony_ci break; 17118c2ecf20Sopenharmony_ci } 17128c2ecf20Sopenharmony_ci 17138c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 17148c2ecf20Sopenharmony_ci return 0; 17158c2ecf20Sopenharmony_ci} 17168c2ecf20Sopenharmony_ci 17178c2ecf20Sopenharmony_ci/* 17188c2ecf20Sopenharmony_ci * FS.GetCapabilities operation type 17198c2ecf20Sopenharmony_ci */ 17208c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSGetCapabilities = { 17218c2ecf20Sopenharmony_ci .name = "FS.GetCapabilities", 17228c2ecf20Sopenharmony_ci .op = afs_FS_GetCapabilities, 17238c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_get_capabilities, 17248c2ecf20Sopenharmony_ci .done = afs_fileserver_probe_result, 17258c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 17268c2ecf20Sopenharmony_ci}; 17278c2ecf20Sopenharmony_ci 17288c2ecf20Sopenharmony_ci/* 17298c2ecf20Sopenharmony_ci * Probe a fileserver for the capabilities that it supports. This RPC can 17308c2ecf20Sopenharmony_ci * reply with up to 196 words. The operation is asynchronous and if we managed 17318c2ecf20Sopenharmony_ci * to allocate a call, true is returned the result is delivered through the 17328c2ecf20Sopenharmony_ci * ->done() - otherwise we return false to indicate we didn't even try. 17338c2ecf20Sopenharmony_ci */ 17348c2ecf20Sopenharmony_cibool afs_fs_get_capabilities(struct afs_net *net, struct afs_server *server, 17358c2ecf20Sopenharmony_ci struct afs_addr_cursor *ac, struct key *key) 17368c2ecf20Sopenharmony_ci{ 17378c2ecf20Sopenharmony_ci struct afs_call *call; 17388c2ecf20Sopenharmony_ci __be32 *bp; 17398c2ecf20Sopenharmony_ci 17408c2ecf20Sopenharmony_ci _enter(""); 17418c2ecf20Sopenharmony_ci 17428c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(net, &afs_RXFSGetCapabilities, 1 * 4, 16 * 4); 17438c2ecf20Sopenharmony_ci if (!call) 17448c2ecf20Sopenharmony_ci return false; 17458c2ecf20Sopenharmony_ci 17468c2ecf20Sopenharmony_ci call->key = key; 17478c2ecf20Sopenharmony_ci call->server = afs_use_server(server, afs_server_trace_get_caps); 17488c2ecf20Sopenharmony_ci call->upgrade = true; 17498c2ecf20Sopenharmony_ci call->async = true; 17508c2ecf20Sopenharmony_ci call->max_lifespan = AFS_PROBE_MAX_LIFESPAN; 17518c2ecf20Sopenharmony_ci 17528c2ecf20Sopenharmony_ci /* marshall the parameters */ 17538c2ecf20Sopenharmony_ci bp = call->request; 17548c2ecf20Sopenharmony_ci *bp++ = htonl(FSGETCAPABILITIES); 17558c2ecf20Sopenharmony_ci 17568c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, NULL); 17578c2ecf20Sopenharmony_ci afs_make_call(ac, call, GFP_NOFS); 17588c2ecf20Sopenharmony_ci afs_put_call(call); 17598c2ecf20Sopenharmony_ci return true; 17608c2ecf20Sopenharmony_ci} 17618c2ecf20Sopenharmony_ci 17628c2ecf20Sopenharmony_ci/* 17638c2ecf20Sopenharmony_ci * Deliver reply data to an FS.InlineBulkStatus call 17648c2ecf20Sopenharmony_ci */ 17658c2ecf20Sopenharmony_cistatic int afs_deliver_fs_inline_bulk_status(struct afs_call *call) 17668c2ecf20Sopenharmony_ci{ 17678c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 17688c2ecf20Sopenharmony_ci struct afs_status_cb *scb; 17698c2ecf20Sopenharmony_ci const __be32 *bp; 17708c2ecf20Sopenharmony_ci u32 tmp; 17718c2ecf20Sopenharmony_ci int ret; 17728c2ecf20Sopenharmony_ci 17738c2ecf20Sopenharmony_ci _enter("{%u}", call->unmarshall); 17748c2ecf20Sopenharmony_ci 17758c2ecf20Sopenharmony_ci switch (call->unmarshall) { 17768c2ecf20Sopenharmony_ci case 0: 17778c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 17788c2ecf20Sopenharmony_ci call->unmarshall++; 17798c2ecf20Sopenharmony_ci fallthrough; 17808c2ecf20Sopenharmony_ci 17818c2ecf20Sopenharmony_ci /* Extract the file status count and array in two steps */ 17828c2ecf20Sopenharmony_ci case 1: 17838c2ecf20Sopenharmony_ci _debug("extract status count"); 17848c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 17858c2ecf20Sopenharmony_ci if (ret < 0) 17868c2ecf20Sopenharmony_ci return ret; 17878c2ecf20Sopenharmony_ci 17888c2ecf20Sopenharmony_ci tmp = ntohl(call->tmp); 17898c2ecf20Sopenharmony_ci _debug("status count: %u/%u", tmp, op->nr_files); 17908c2ecf20Sopenharmony_ci if (tmp != op->nr_files) 17918c2ecf20Sopenharmony_ci return afs_protocol_error(call, afs_eproto_ibulkst_count); 17928c2ecf20Sopenharmony_ci 17938c2ecf20Sopenharmony_ci call->count = 0; 17948c2ecf20Sopenharmony_ci call->unmarshall++; 17958c2ecf20Sopenharmony_ci more_counts: 17968c2ecf20Sopenharmony_ci afs_extract_to_buf(call, 21 * sizeof(__be32)); 17978c2ecf20Sopenharmony_ci fallthrough; 17988c2ecf20Sopenharmony_ci 17998c2ecf20Sopenharmony_ci case 2: 18008c2ecf20Sopenharmony_ci _debug("extract status array %u", call->count); 18018c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 18028c2ecf20Sopenharmony_ci if (ret < 0) 18038c2ecf20Sopenharmony_ci return ret; 18048c2ecf20Sopenharmony_ci 18058c2ecf20Sopenharmony_ci switch (call->count) { 18068c2ecf20Sopenharmony_ci case 0: 18078c2ecf20Sopenharmony_ci scb = &op->file[0].scb; 18088c2ecf20Sopenharmony_ci break; 18098c2ecf20Sopenharmony_ci case 1: 18108c2ecf20Sopenharmony_ci scb = &op->file[1].scb; 18118c2ecf20Sopenharmony_ci break; 18128c2ecf20Sopenharmony_ci default: 18138c2ecf20Sopenharmony_ci scb = &op->more_files[call->count - 2].scb; 18148c2ecf20Sopenharmony_ci break; 18158c2ecf20Sopenharmony_ci } 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci bp = call->buffer; 18188c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, scb); 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci call->count++; 18218c2ecf20Sopenharmony_ci if (call->count < op->nr_files) 18228c2ecf20Sopenharmony_ci goto more_counts; 18238c2ecf20Sopenharmony_ci 18248c2ecf20Sopenharmony_ci call->count = 0; 18258c2ecf20Sopenharmony_ci call->unmarshall++; 18268c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 18278c2ecf20Sopenharmony_ci fallthrough; 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci /* Extract the callback count and array in two steps */ 18308c2ecf20Sopenharmony_ci case 3: 18318c2ecf20Sopenharmony_ci _debug("extract CB count"); 18328c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 18338c2ecf20Sopenharmony_ci if (ret < 0) 18348c2ecf20Sopenharmony_ci return ret; 18358c2ecf20Sopenharmony_ci 18368c2ecf20Sopenharmony_ci tmp = ntohl(call->tmp); 18378c2ecf20Sopenharmony_ci _debug("CB count: %u", tmp); 18388c2ecf20Sopenharmony_ci if (tmp != op->nr_files) 18398c2ecf20Sopenharmony_ci return afs_protocol_error(call, afs_eproto_ibulkst_cb_count); 18408c2ecf20Sopenharmony_ci call->count = 0; 18418c2ecf20Sopenharmony_ci call->unmarshall++; 18428c2ecf20Sopenharmony_ci more_cbs: 18438c2ecf20Sopenharmony_ci afs_extract_to_buf(call, 3 * sizeof(__be32)); 18448c2ecf20Sopenharmony_ci fallthrough; 18458c2ecf20Sopenharmony_ci 18468c2ecf20Sopenharmony_ci case 4: 18478c2ecf20Sopenharmony_ci _debug("extract CB array"); 18488c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 18498c2ecf20Sopenharmony_ci if (ret < 0) 18508c2ecf20Sopenharmony_ci return ret; 18518c2ecf20Sopenharmony_ci 18528c2ecf20Sopenharmony_ci _debug("unmarshall CB array"); 18538c2ecf20Sopenharmony_ci switch (call->count) { 18548c2ecf20Sopenharmony_ci case 0: 18558c2ecf20Sopenharmony_ci scb = &op->file[0].scb; 18568c2ecf20Sopenharmony_ci break; 18578c2ecf20Sopenharmony_ci case 1: 18588c2ecf20Sopenharmony_ci scb = &op->file[1].scb; 18598c2ecf20Sopenharmony_ci break; 18608c2ecf20Sopenharmony_ci default: 18618c2ecf20Sopenharmony_ci scb = &op->more_files[call->count - 2].scb; 18628c2ecf20Sopenharmony_ci break; 18638c2ecf20Sopenharmony_ci } 18648c2ecf20Sopenharmony_ci 18658c2ecf20Sopenharmony_ci bp = call->buffer; 18668c2ecf20Sopenharmony_ci xdr_decode_AFSCallBack(&bp, call, scb); 18678c2ecf20Sopenharmony_ci call->count++; 18688c2ecf20Sopenharmony_ci if (call->count < op->nr_files) 18698c2ecf20Sopenharmony_ci goto more_cbs; 18708c2ecf20Sopenharmony_ci 18718c2ecf20Sopenharmony_ci afs_extract_to_buf(call, 6 * sizeof(__be32)); 18728c2ecf20Sopenharmony_ci call->unmarshall++; 18738c2ecf20Sopenharmony_ci fallthrough; 18748c2ecf20Sopenharmony_ci 18758c2ecf20Sopenharmony_ci case 5: 18768c2ecf20Sopenharmony_ci ret = afs_extract_data(call, false); 18778c2ecf20Sopenharmony_ci if (ret < 0) 18788c2ecf20Sopenharmony_ci return ret; 18798c2ecf20Sopenharmony_ci 18808c2ecf20Sopenharmony_ci bp = call->buffer; 18818c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 18828c2ecf20Sopenharmony_ci 18838c2ecf20Sopenharmony_ci call->unmarshall++; 18848c2ecf20Sopenharmony_ci 18858c2ecf20Sopenharmony_ci case 6: 18868c2ecf20Sopenharmony_ci break; 18878c2ecf20Sopenharmony_ci } 18888c2ecf20Sopenharmony_ci 18898c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 18908c2ecf20Sopenharmony_ci return 0; 18918c2ecf20Sopenharmony_ci} 18928c2ecf20Sopenharmony_ci 18938c2ecf20Sopenharmony_cistatic void afs_done_fs_inline_bulk_status(struct afs_call *call) 18948c2ecf20Sopenharmony_ci{ 18958c2ecf20Sopenharmony_ci if (call->error == -ECONNABORTED && 18968c2ecf20Sopenharmony_ci call->abort_code == RX_INVALID_OPERATION) { 18978c2ecf20Sopenharmony_ci set_bit(AFS_SERVER_FL_NO_IBULK, &call->server->flags); 18988c2ecf20Sopenharmony_ci if (call->op) 18998c2ecf20Sopenharmony_ci set_bit(AFS_VOLUME_MAYBE_NO_IBULK, &call->op->volume->flags); 19008c2ecf20Sopenharmony_ci } 19018c2ecf20Sopenharmony_ci} 19028c2ecf20Sopenharmony_ci 19038c2ecf20Sopenharmony_ci/* 19048c2ecf20Sopenharmony_ci * FS.InlineBulkStatus operation type 19058c2ecf20Sopenharmony_ci */ 19068c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSInlineBulkStatus = { 19078c2ecf20Sopenharmony_ci .name = "FS.InlineBulkStatus", 19088c2ecf20Sopenharmony_ci .op = afs_FS_InlineBulkStatus, 19098c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_inline_bulk_status, 19108c2ecf20Sopenharmony_ci .done = afs_done_fs_inline_bulk_status, 19118c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 19128c2ecf20Sopenharmony_ci}; 19138c2ecf20Sopenharmony_ci 19148c2ecf20Sopenharmony_ci/* 19158c2ecf20Sopenharmony_ci * Fetch the status information for up to 50 files 19168c2ecf20Sopenharmony_ci */ 19178c2ecf20Sopenharmony_civoid afs_fs_inline_bulk_status(struct afs_operation *op) 19188c2ecf20Sopenharmony_ci{ 19198c2ecf20Sopenharmony_ci struct afs_vnode_param *dvp = &op->file[0]; 19208c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[1]; 19218c2ecf20Sopenharmony_ci struct afs_call *call; 19228c2ecf20Sopenharmony_ci __be32 *bp; 19238c2ecf20Sopenharmony_ci int i; 19248c2ecf20Sopenharmony_ci 19258c2ecf20Sopenharmony_ci if (test_bit(AFS_SERVER_FL_NO_IBULK, &op->server->flags)) { 19268c2ecf20Sopenharmony_ci op->error = -ENOTSUPP; 19278c2ecf20Sopenharmony_ci return; 19288c2ecf20Sopenharmony_ci } 19298c2ecf20Sopenharmony_ci 19308c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},%u", 19318c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files); 19328c2ecf20Sopenharmony_ci 19338c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSInlineBulkStatus, 19348c2ecf20Sopenharmony_ci (2 + op->nr_files * 3) * 4, 19358c2ecf20Sopenharmony_ci 21 * 4); 19368c2ecf20Sopenharmony_ci if (!call) 19378c2ecf20Sopenharmony_ci return afs_op_nomem(op); 19388c2ecf20Sopenharmony_ci 19398c2ecf20Sopenharmony_ci /* marshall the parameters */ 19408c2ecf20Sopenharmony_ci bp = call->request; 19418c2ecf20Sopenharmony_ci *bp++ = htonl(FSINLINEBULKSTATUS); 19428c2ecf20Sopenharmony_ci *bp++ = htonl(op->nr_files); 19438c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vid); 19448c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.vnode); 19458c2ecf20Sopenharmony_ci *bp++ = htonl(dvp->fid.unique); 19468c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vid); 19478c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.vnode); 19488c2ecf20Sopenharmony_ci *bp++ = htonl(vp->fid.unique); 19498c2ecf20Sopenharmony_ci for (i = 0; i < op->nr_files - 2; i++) { 19508c2ecf20Sopenharmony_ci *bp++ = htonl(op->more_files[i].fid.vid); 19518c2ecf20Sopenharmony_ci *bp++ = htonl(op->more_files[i].fid.vnode); 19528c2ecf20Sopenharmony_ci *bp++ = htonl(op->more_files[i].fid.unique); 19538c2ecf20Sopenharmony_ci } 19548c2ecf20Sopenharmony_ci 19558c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 19568c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_NOFS); 19578c2ecf20Sopenharmony_ci} 19588c2ecf20Sopenharmony_ci 19598c2ecf20Sopenharmony_ci/* 19608c2ecf20Sopenharmony_ci * deliver reply data to an FS.FetchACL 19618c2ecf20Sopenharmony_ci */ 19628c2ecf20Sopenharmony_cistatic int afs_deliver_fs_fetch_acl(struct afs_call *call) 19638c2ecf20Sopenharmony_ci{ 19648c2ecf20Sopenharmony_ci struct afs_operation *op = call->op; 19658c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 19668c2ecf20Sopenharmony_ci struct afs_acl *acl; 19678c2ecf20Sopenharmony_ci const __be32 *bp; 19688c2ecf20Sopenharmony_ci unsigned int size; 19698c2ecf20Sopenharmony_ci int ret; 19708c2ecf20Sopenharmony_ci 19718c2ecf20Sopenharmony_ci _enter("{%u}", call->unmarshall); 19728c2ecf20Sopenharmony_ci 19738c2ecf20Sopenharmony_ci switch (call->unmarshall) { 19748c2ecf20Sopenharmony_ci case 0: 19758c2ecf20Sopenharmony_ci afs_extract_to_tmp(call); 19768c2ecf20Sopenharmony_ci call->unmarshall++; 19778c2ecf20Sopenharmony_ci fallthrough; 19788c2ecf20Sopenharmony_ci 19798c2ecf20Sopenharmony_ci /* extract the returned data length */ 19808c2ecf20Sopenharmony_ci case 1: 19818c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 19828c2ecf20Sopenharmony_ci if (ret < 0) 19838c2ecf20Sopenharmony_ci return ret; 19848c2ecf20Sopenharmony_ci 19858c2ecf20Sopenharmony_ci size = call->count2 = ntohl(call->tmp); 19868c2ecf20Sopenharmony_ci size = round_up(size, 4); 19878c2ecf20Sopenharmony_ci 19888c2ecf20Sopenharmony_ci acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); 19898c2ecf20Sopenharmony_ci if (!acl) 19908c2ecf20Sopenharmony_ci return -ENOMEM; 19918c2ecf20Sopenharmony_ci op->acl = acl; 19928c2ecf20Sopenharmony_ci acl->size = call->count2; 19938c2ecf20Sopenharmony_ci afs_extract_begin(call, acl->data, size); 19948c2ecf20Sopenharmony_ci call->unmarshall++; 19958c2ecf20Sopenharmony_ci fallthrough; 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_ci /* extract the returned data */ 19988c2ecf20Sopenharmony_ci case 2: 19998c2ecf20Sopenharmony_ci ret = afs_extract_data(call, true); 20008c2ecf20Sopenharmony_ci if (ret < 0) 20018c2ecf20Sopenharmony_ci return ret; 20028c2ecf20Sopenharmony_ci 20038c2ecf20Sopenharmony_ci afs_extract_to_buf(call, (21 + 6) * 4); 20048c2ecf20Sopenharmony_ci call->unmarshall++; 20058c2ecf20Sopenharmony_ci fallthrough; 20068c2ecf20Sopenharmony_ci 20078c2ecf20Sopenharmony_ci /* extract the metadata */ 20088c2ecf20Sopenharmony_ci case 3: 20098c2ecf20Sopenharmony_ci ret = afs_extract_data(call, false); 20108c2ecf20Sopenharmony_ci if (ret < 0) 20118c2ecf20Sopenharmony_ci return ret; 20128c2ecf20Sopenharmony_ci 20138c2ecf20Sopenharmony_ci bp = call->buffer; 20148c2ecf20Sopenharmony_ci xdr_decode_AFSFetchStatus(&bp, call, &vp->scb); 20158c2ecf20Sopenharmony_ci xdr_decode_AFSVolSync(&bp, &op->volsync); 20168c2ecf20Sopenharmony_ci 20178c2ecf20Sopenharmony_ci call->unmarshall++; 20188c2ecf20Sopenharmony_ci 20198c2ecf20Sopenharmony_ci case 4: 20208c2ecf20Sopenharmony_ci break; 20218c2ecf20Sopenharmony_ci } 20228c2ecf20Sopenharmony_ci 20238c2ecf20Sopenharmony_ci _leave(" = 0 [done]"); 20248c2ecf20Sopenharmony_ci return 0; 20258c2ecf20Sopenharmony_ci} 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_ci/* 20288c2ecf20Sopenharmony_ci * FS.FetchACL operation type 20298c2ecf20Sopenharmony_ci */ 20308c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSFetchACL = { 20318c2ecf20Sopenharmony_ci .name = "FS.FetchACL", 20328c2ecf20Sopenharmony_ci .op = afs_FS_FetchACL, 20338c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_fetch_acl, 20348c2ecf20Sopenharmony_ci}; 20358c2ecf20Sopenharmony_ci 20368c2ecf20Sopenharmony_ci/* 20378c2ecf20Sopenharmony_ci * Fetch the ACL for a file. 20388c2ecf20Sopenharmony_ci */ 20398c2ecf20Sopenharmony_civoid afs_fs_fetch_acl(struct afs_operation *op) 20408c2ecf20Sopenharmony_ci{ 20418c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 20428c2ecf20Sopenharmony_ci struct afs_call *call; 20438c2ecf20Sopenharmony_ci __be32 *bp; 20448c2ecf20Sopenharmony_ci 20458c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 20468c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 20478c2ecf20Sopenharmony_ci 20488c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSFetchACL, 16, (21 + 6) * 4); 20498c2ecf20Sopenharmony_ci if (!call) 20508c2ecf20Sopenharmony_ci return afs_op_nomem(op); 20518c2ecf20Sopenharmony_ci 20528c2ecf20Sopenharmony_ci /* marshall the parameters */ 20538c2ecf20Sopenharmony_ci bp = call->request; 20548c2ecf20Sopenharmony_ci bp[0] = htonl(FSFETCHACL); 20558c2ecf20Sopenharmony_ci bp[1] = htonl(vp->fid.vid); 20568c2ecf20Sopenharmony_ci bp[2] = htonl(vp->fid.vnode); 20578c2ecf20Sopenharmony_ci bp[3] = htonl(vp->fid.unique); 20588c2ecf20Sopenharmony_ci 20598c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 20608c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_KERNEL); 20618c2ecf20Sopenharmony_ci} 20628c2ecf20Sopenharmony_ci 20638c2ecf20Sopenharmony_ci/* 20648c2ecf20Sopenharmony_ci * FS.StoreACL operation type 20658c2ecf20Sopenharmony_ci */ 20668c2ecf20Sopenharmony_cistatic const struct afs_call_type afs_RXFSStoreACL = { 20678c2ecf20Sopenharmony_ci .name = "FS.StoreACL", 20688c2ecf20Sopenharmony_ci .op = afs_FS_StoreACL, 20698c2ecf20Sopenharmony_ci .deliver = afs_deliver_fs_file_status_and_vol, 20708c2ecf20Sopenharmony_ci .destructor = afs_flat_call_destructor, 20718c2ecf20Sopenharmony_ci}; 20728c2ecf20Sopenharmony_ci 20738c2ecf20Sopenharmony_ci/* 20748c2ecf20Sopenharmony_ci * Fetch the ACL for a file. 20758c2ecf20Sopenharmony_ci */ 20768c2ecf20Sopenharmony_civoid afs_fs_store_acl(struct afs_operation *op) 20778c2ecf20Sopenharmony_ci{ 20788c2ecf20Sopenharmony_ci struct afs_vnode_param *vp = &op->file[0]; 20798c2ecf20Sopenharmony_ci struct afs_call *call; 20808c2ecf20Sopenharmony_ci const struct afs_acl *acl = op->acl; 20818c2ecf20Sopenharmony_ci size_t size; 20828c2ecf20Sopenharmony_ci __be32 *bp; 20838c2ecf20Sopenharmony_ci 20848c2ecf20Sopenharmony_ci _enter(",%x,{%llx:%llu},,", 20858c2ecf20Sopenharmony_ci key_serial(op->key), vp->fid.vid, vp->fid.vnode); 20868c2ecf20Sopenharmony_ci 20878c2ecf20Sopenharmony_ci size = round_up(acl->size, 4); 20888c2ecf20Sopenharmony_ci call = afs_alloc_flat_call(op->net, &afs_RXFSStoreACL, 20898c2ecf20Sopenharmony_ci 5 * 4 + size, (21 + 6) * 4); 20908c2ecf20Sopenharmony_ci if (!call) 20918c2ecf20Sopenharmony_ci return afs_op_nomem(op); 20928c2ecf20Sopenharmony_ci 20938c2ecf20Sopenharmony_ci /* marshall the parameters */ 20948c2ecf20Sopenharmony_ci bp = call->request; 20958c2ecf20Sopenharmony_ci bp[0] = htonl(FSSTOREACL); 20968c2ecf20Sopenharmony_ci bp[1] = htonl(vp->fid.vid); 20978c2ecf20Sopenharmony_ci bp[2] = htonl(vp->fid.vnode); 20988c2ecf20Sopenharmony_ci bp[3] = htonl(vp->fid.unique); 20998c2ecf20Sopenharmony_ci bp[4] = htonl(acl->size); 21008c2ecf20Sopenharmony_ci memcpy(&bp[5], acl->data, acl->size); 21018c2ecf20Sopenharmony_ci if (acl->size != size) 21028c2ecf20Sopenharmony_ci memset((void *)&bp[5] + acl->size, 0, size - acl->size); 21038c2ecf20Sopenharmony_ci 21048c2ecf20Sopenharmony_ci trace_afs_make_fs_call(call, &vp->fid); 21058c2ecf20Sopenharmony_ci afs_make_op_call(op, call, GFP_KERNEL); 21068c2ecf20Sopenharmony_ci} 2107