cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

yfsclient.c (48536B)


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