brintos

brintos / linux-shallow public Read only

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