File Index
Files and directories
Sign in
FILE

yfsclient.c

File preview with syntax highlighting.

linux-6.19.14/fs/afs/yfsclient.c C
   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 = ktime_add(call->issue_time, xdr_to_u64(x->expiration_time) * 100);
 236	cb->expires_at	= ktime_divns(cb_expiry, NSEC_PER_SEC);
 237	scb->have_cb	= true;
 238	*_bp += xdr_size(x);
 239}
 240
 241/*
 242 * Decode a YFSVolSync block
 243 */
 244static void xdr_decode_YFSVolSync(const __be32 **_bp,
 245				  struct afs_volsync *volsync)
 246{
 247	struct yfs_xdr_YFSVolSync *x = (void *)*_bp;
 248	u64 creation, update;
 249
 250	if (volsync) {
 251		creation = xdr_to_u64(x->vol_creation_date);
 252		do_div(creation, 10 * 1000 * 1000);
 253		volsync->creation = creation;
 254		update = xdr_to_u64(x->vol_update_date);
 255		do_div(update, 10 * 1000 * 1000);
 256		volsync->update = update;
 257	}
 258
 259	*_bp += xdr_size(x);
 260}
 261
 262/*
 263 * Encode the requested attributes into a YFSStoreStatus block
 264 */
 265static __be32 *xdr_encode_YFS_StoreStatus(__be32 *bp, struct iattr *attr)
 266{
 267	struct yfs_xdr_YFSStoreStatus *x = (void *)bp;
 268	s64 mtime = 0, owner = 0, group = 0;
 269	u32 mask = 0, mode = 0;
 270
 271	mask = 0;
 272	if (attr->ia_valid & ATTR_MTIME) {
 273		mask |= AFS_SET_MTIME;
 274		mtime = linux_to_yfs_time(&attr->ia_mtime);
 275	}
 276
 277	if (attr->ia_valid & ATTR_UID) {
 278		mask |= AFS_SET_OWNER;
 279		owner = from_kuid(&init_user_ns, attr->ia_uid);
 280	}
 281
 282	if (attr->ia_valid & ATTR_GID) {
 283		mask |= AFS_SET_GROUP;
 284		group = from_kgid(&init_user_ns, attr->ia_gid);
 285	}
 286
 287	if (attr->ia_valid & ATTR_MODE) {
 288		mask |= AFS_SET_MODE;
 289		mode = attr->ia_mode & S_IALLUGO;
 290	}
 291
 292	x->mask		= htonl(mask);
 293	x->mode		= htonl(mode);
 294	x->mtime_client	= u64_to_xdr(mtime);
 295	x->owner	= u64_to_xdr(owner);
 296	x->group	= u64_to_xdr(group);
 297	return bp + xdr_size(x);
 298}
 299
 300/*
 301 * Decode a YFSFetchVolumeStatus block.
 302 */
 303static void xdr_decode_YFSFetchVolumeStatus(const __be32 **_bp,
 304					    struct afs_volume_status *vs)
 305{
 306	const struct yfs_xdr_YFSFetchVolumeStatus *x = (const void *)*_bp;
 307	u32 flags;
 308
 309	vs->vid			= xdr_to_u64(x->vid);
 310	vs->parent_id		= xdr_to_u64(x->parent_id);
 311	flags			= ntohl(x->flags);
 312	vs->online		= flags & yfs_FVSOnline;
 313	vs->in_service		= flags & yfs_FVSInservice;
 314	vs->blessed		= flags & yfs_FVSBlessed;
 315	vs->needs_salvage	= flags & yfs_FVSNeedsSalvage;
 316	vs->type		= ntohl(x->type);
 317	vs->min_quota		= 0;
 318	vs->max_quota		= xdr_to_u64(x->max_quota);
 319	vs->blocks_in_use	= xdr_to_u64(x->blocks_in_use);
 320	vs->part_blocks_avail	= xdr_to_u64(x->part_blocks_avail);
 321	vs->part_max_blocks	= xdr_to_u64(x->part_max_blocks);
 322	vs->vol_copy_date	= xdr_to_u64(x->vol_copy_date);
 323	vs->vol_backup_date	= xdr_to_u64(x->vol_backup_date);
 324	*_bp += sizeof(*x) / sizeof(__be32);
 325}
 326
 327/*
 328 * Deliver reply data to operations that just return a file status and a volume
 329 * sync record.
 330 */
 331static int yfs_deliver_status_and_volsync(struct afs_call *call)
 332{
 333	struct afs_operation *op = call->op;
 334	const __be32 *bp;
 335	int ret;
 336
 337	ret = afs_transfer_reply(call);
 338	if (ret < 0)
 339		return ret;
 340
 341	bp = call->buffer;
 342	xdr_decode_YFSFetchStatus(&bp, call, &op->file[0].scb);
 343	xdr_decode_YFSVolSync(&bp, &op->volsync);
 344
 345	_leave(" = 0 [done]");
 346	return 0;
 347}
 348
 349/*
 350 * Deliver reply data to an YFS.FetchData64.
 351 */
 352static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
 353{
 354	struct afs_operation *op = call->op;
 355	struct netfs_io_subrequest *subreq = op->fetch.subreq;
 356	struct afs_vnode_param *vp = &op->file[0];
 357	const __be32 *bp;
 358	size_t count_before;
 359	int ret;
 360
 361	_enter("{%u,%zu, %zu/%llu}",
 362	       call->unmarshall, call->iov_len, iov_iter_count(call->iter),
 363	       call->remaining);
 364
 365	switch (call->unmarshall) {
 366	case 0:
 367		call->remaining = 0;
 368		afs_extract_to_tmp64(call);
 369		call->unmarshall++;
 370		fallthrough;
 371
 372		/* Extract the returned data length into ->actual_len.  This
 373		 * may indicate more or less data than was requested will be
 374		 * returned.
 375		 */
 376	case 1:
 377		_debug("extract data length");
 378		ret = afs_extract_data(call, true);
 379		if (ret < 0)
 380			return ret;
 381
 382		call->remaining = be64_to_cpu(call->tmp64);
 383		_debug("DATA length: %llu", call->remaining);
 384
 385		if (call->remaining == 0)
 386			goto no_more_data;
 387
 388		call->iter = &subreq->io_iter;
 389		call->iov_len = min(call->remaining, subreq->len - subreq->transferred);
 390		call->unmarshall++;
 391		fallthrough;
 392
 393		/* extract the returned data */
 394	case 2:
 395		count_before = call->iov_len;
 396		_debug("extract data %zu/%llu", count_before, call->remaining);
 397
 398		ret = afs_extract_data(call, true);
 399		subreq->transferred += count_before - call->iov_len;
 400		if (ret < 0)
 401			return ret;
 402
 403		call->iter = &call->def_iter;
 404		if (call->remaining)
 405			goto no_more_data;
 406
 407		/* Discard any excess data the server gave us */
 408		afs_extract_discard(call, call->remaining);
 409		call->unmarshall = 3;
 410		fallthrough;
 411
 412	case 3:
 413		_debug("extract discard %zu/%llu",
 414		       iov_iter_count(call->iter), call->remaining);
 415
 416		ret = afs_extract_data(call, true);
 417		if (ret < 0)
 418			return ret;
 419
 420	no_more_data:
 421		call->unmarshall = 4;
 422		afs_extract_to_buf(call,
 423				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 424				   sizeof(struct yfs_xdr_YFSCallBack) +
 425				   sizeof(struct yfs_xdr_YFSVolSync));
 426		fallthrough;
 427
 428		/* extract the metadata */
 429	case 4:
 430		ret = afs_extract_data(call, false);
 431		if (ret < 0)
 432			return ret;
 433
 434		bp = call->buffer;
 435		xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
 436		xdr_decode_YFSCallBack(&bp, call, &vp->scb);
 437		xdr_decode_YFSVolSync(&bp, &op->volsync);
 438
 439		if (subreq->start + subreq->transferred >= vp->scb.status.size)
 440			__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
 441
 442		call->unmarshall++;
 443		fallthrough;
 444
 445	case 5:
 446		break;
 447	}
 448
 449	_leave(" = 0 [done]");
 450	return 0;
 451}
 452
 453/*
 454 * YFS.FetchData64 operation type
 455 */
 456static const struct afs_call_type yfs_RXYFSFetchData64 = {
 457	.name		= "YFS.FetchData64",
 458	.op		= yfs_FS_FetchData64,
 459	.async_rx	= afs_fetch_data_async_rx,
 460	.deliver	= yfs_deliver_fs_fetch_data64,
 461	.immediate_cancel = afs_fetch_data_immediate_cancel,
 462	.destructor	= afs_flat_call_destructor,
 463};
 464
 465/*
 466 * Fetch data from a file.
 467 */
 468void yfs_fs_fetch_data(struct afs_operation *op)
 469{
 470	struct netfs_io_subrequest *subreq = op->fetch.subreq;
 471	struct afs_vnode_param *vp = &op->file[0];
 472	struct afs_call *call;
 473	__be32 *bp;
 474
 475	_enter(",%x,{%llx:%llu},%llx,%zx",
 476	       key_serial(op->key), vp->fid.vid, vp->fid.vnode,
 477	       subreq->start + subreq->transferred,
 478	       subreq->len   - subreq->transferred);
 479
 480	call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchData64,
 481				   sizeof(__be32) * 2 +
 482				   sizeof(struct yfs_xdr_YFSFid) +
 483				   sizeof(struct yfs_xdr_u64) * 2,
 484				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 485				   sizeof(struct yfs_xdr_YFSCallBack) +
 486				   sizeof(struct yfs_xdr_YFSVolSync));
 487	if (!call)
 488		return afs_op_nomem(op);
 489
 490	if (op->flags & AFS_OPERATION_ASYNC)
 491		call->async = true;
 492
 493	/* marshall the parameters */
 494	bp = call->request;
 495	bp = xdr_encode_u32(bp, YFSFETCHDATA64);
 496	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 497	bp = xdr_encode_YFSFid(bp, &vp->fid);
 498	bp = xdr_encode_u64(bp, subreq->start + subreq->transferred);
 499	bp = xdr_encode_u64(bp, subreq->len   - subreq->transferred);
 500	yfs_check_req(call, bp);
 501
 502	call->fid = vp->fid;
 503	trace_afs_make_fs_call(call, &vp->fid);
 504	afs_make_op_call(op, call, GFP_NOFS);
 505}
 506
 507/*
 508 * Deliver reply data for YFS.CreateFile or YFS.MakeDir.
 509 */
 510static int yfs_deliver_fs_create_vnode(struct afs_call *call)
 511{
 512	struct afs_operation *op = call->op;
 513	struct afs_vnode_param *dvp = &op->file[0];
 514	struct afs_vnode_param *vp = &op->file[1];
 515	const __be32 *bp;
 516	int ret;
 517
 518	_enter("{%u}", call->unmarshall);
 519
 520	ret = afs_transfer_reply(call);
 521	if (ret < 0)
 522		return ret;
 523
 524	/* unmarshall the reply once we've received all of it */
 525	bp = call->buffer;
 526	xdr_decode_YFSFid(&bp, &op->file[1].fid);
 527	xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
 528	xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
 529	xdr_decode_YFSCallBack(&bp, call, &vp->scb);
 530	xdr_decode_YFSVolSync(&bp, &op->volsync);
 531
 532	_leave(" = 0 [done]");
 533	return 0;
 534}
 535
 536/*
 537 * FS.CreateFile and FS.MakeDir operation type
 538 */
 539static const struct afs_call_type afs_RXFSCreateFile = {
 540	.name		= "YFS.CreateFile",
 541	.op		= yfs_FS_CreateFile,
 542	.deliver	= yfs_deliver_fs_create_vnode,
 543	.destructor	= afs_flat_call_destructor,
 544};
 545
 546/*
 547 * Create a file.
 548 */
 549void yfs_fs_create_file(struct afs_operation *op)
 550{
 551	const struct qstr *name = &op->dentry->d_name;
 552	struct afs_vnode_param *dvp = &op->file[0];
 553	struct afs_call *call;
 554	size_t reqsz, rplsz;
 555	__be32 *bp;
 556
 557	_enter("");
 558
 559	reqsz = (sizeof(__be32) +
 560		 sizeof(__be32) +
 561		 sizeof(struct yfs_xdr_YFSFid) +
 562		 xdr_strlen(name->len) +
 563		 sizeof(struct yfs_xdr_YFSStoreStatus) +
 564		 sizeof(__be32));
 565	rplsz = (sizeof(struct yfs_xdr_YFSFid) +
 566		 sizeof(struct yfs_xdr_YFSFetchStatus) +
 567		 sizeof(struct yfs_xdr_YFSFetchStatus) +
 568		 sizeof(struct yfs_xdr_YFSCallBack) +
 569		 sizeof(struct yfs_xdr_YFSVolSync));
 570
 571	call = afs_alloc_flat_call(op->net, &afs_RXFSCreateFile, reqsz, rplsz);
 572	if (!call)
 573		return afs_op_nomem(op);
 574
 575	/* marshall the parameters */
 576	bp = call->request;
 577	bp = xdr_encode_u32(bp, YFSCREATEFILE);
 578	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 579	bp = xdr_encode_YFSFid(bp, &dvp->fid);
 580	bp = xdr_encode_name(bp, name);
 581	bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
 582	bp = xdr_encode_u32(bp, yfs_LockNone); /* ViceLockType */
 583	yfs_check_req(call, bp);
 584
 585	call->fid = dvp->fid;
 586	trace_afs_make_fs_call1(call, &dvp->fid, name);
 587	afs_make_op_call(op, call, GFP_NOFS);
 588}
 589
 590static const struct afs_call_type yfs_RXFSMakeDir = {
 591	.name		= "YFS.MakeDir",
 592	.op		= yfs_FS_MakeDir,
 593	.deliver	= yfs_deliver_fs_create_vnode,
 594	.destructor	= afs_flat_call_destructor,
 595};
 596
 597/*
 598 * Make a directory.
 599 */
 600void yfs_fs_make_dir(struct afs_operation *op)
 601{
 602	const struct qstr *name = &op->dentry->d_name;
 603	struct afs_vnode_param *dvp = &op->file[0];
 604	struct afs_call *call;
 605	size_t reqsz, rplsz;
 606	__be32 *bp;
 607
 608	_enter("");
 609
 610	reqsz = (sizeof(__be32) +
 611		 sizeof(struct yfs_xdr_RPCFlags) +
 612		 sizeof(struct yfs_xdr_YFSFid) +
 613		 xdr_strlen(name->len) +
 614		 sizeof(struct yfs_xdr_YFSStoreStatus));
 615	rplsz = (sizeof(struct yfs_xdr_YFSFid) +
 616		 sizeof(struct yfs_xdr_YFSFetchStatus) +
 617		 sizeof(struct yfs_xdr_YFSFetchStatus) +
 618		 sizeof(struct yfs_xdr_YFSCallBack) +
 619		 sizeof(struct yfs_xdr_YFSVolSync));
 620
 621	call = afs_alloc_flat_call(op->net, &yfs_RXFSMakeDir, reqsz, rplsz);
 622	if (!call)
 623		return afs_op_nomem(op);
 624
 625	/* marshall the parameters */
 626	bp = call->request;
 627	bp = xdr_encode_u32(bp, YFSMAKEDIR);
 628	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 629	bp = xdr_encode_YFSFid(bp, &dvp->fid);
 630	bp = xdr_encode_name(bp, name);
 631	bp = xdr_encode_YFSStoreStatus(bp, &op->create.mode, &op->mtime);
 632	yfs_check_req(call, bp);
 633
 634	call->fid = dvp->fid;
 635	trace_afs_make_fs_call1(call, &dvp->fid, name);
 636	afs_make_op_call(op, call, GFP_NOFS);
 637}
 638
 639/*
 640 * Deliver reply data to a YFS.RemoveFile2 operation.
 641 */
 642static int yfs_deliver_fs_remove_file2(struct afs_call *call)
 643{
 644	struct afs_operation *op = call->op;
 645	struct afs_vnode_param *dvp = &op->file[0];
 646	struct afs_vnode_param *vp = &op->file[1];
 647	struct afs_fid fid;
 648	const __be32 *bp;
 649	int ret;
 650
 651	_enter("{%u}", call->unmarshall);
 652
 653	ret = afs_transfer_reply(call);
 654	if (ret < 0)
 655		return ret;
 656
 657	bp = call->buffer;
 658	xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
 659	xdr_decode_YFSFid(&bp, &fid);
 660	xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
 661	/* Was deleted if vnode->status.abort_code == VNOVNODE. */
 662
 663	xdr_decode_YFSVolSync(&bp, &op->volsync);
 664	return 0;
 665}
 666
 667static void yfs_done_fs_remove_file2(struct afs_call *call)
 668{
 669	if (call->error == -ECONNABORTED &&
 670	    (call->abort_code == RX_INVALID_OPERATION ||
 671	     call->abort_code == RXGEN_OPCODE)) {
 672		set_bit(AFS_SERVER_FL_NO_RM2, &call->op->server->flags);
 673		call->op->flags |= AFS_OPERATION_DOWNGRADE;
 674	}
 675}
 676
 677/*
 678 * YFS.RemoveFile2 operation type.
 679 */
 680static const struct afs_call_type yfs_RXYFSRemoveFile2 = {
 681	.name		= "YFS.RemoveFile2",
 682	.op		= yfs_FS_RemoveFile2,
 683	.deliver	= yfs_deliver_fs_remove_file2,
 684	.done		= yfs_done_fs_remove_file2,
 685	.destructor	= afs_flat_call_destructor,
 686};
 687
 688/*
 689 * Remove a file and retrieve new file status.
 690 */
 691void yfs_fs_remove_file2(struct afs_operation *op)
 692{
 693	struct afs_vnode_param *dvp = &op->file[0];
 694	const struct qstr *name = &op->dentry->d_name;
 695	struct afs_call *call;
 696	__be32 *bp;
 697
 698	_enter("");
 699
 700	call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile2,
 701				   sizeof(__be32) +
 702				   sizeof(struct yfs_xdr_RPCFlags) +
 703				   sizeof(struct yfs_xdr_YFSFid) +
 704				   xdr_strlen(name->len),
 705				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 706				   sizeof(struct yfs_xdr_YFSFid) +
 707				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 708				   sizeof(struct yfs_xdr_YFSVolSync));
 709	if (!call)
 710		return afs_op_nomem(op);
 711
 712	/* marshall the parameters */
 713	bp = call->request;
 714	bp = xdr_encode_u32(bp, YFSREMOVEFILE2);
 715	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 716	bp = xdr_encode_YFSFid(bp, &dvp->fid);
 717	bp = xdr_encode_name(bp, name);
 718	yfs_check_req(call, bp);
 719
 720	call->fid = dvp->fid;
 721	trace_afs_make_fs_call1(call, &dvp->fid, name);
 722	afs_make_op_call(op, call, GFP_NOFS);
 723}
 724
 725/*
 726 * Deliver reply data to a YFS.RemoveFile or YFS.RemoveDir operation.
 727 */
 728static int yfs_deliver_fs_remove(struct afs_call *call)
 729{
 730	struct afs_operation *op = call->op;
 731	struct afs_vnode_param *dvp = &op->file[0];
 732	const __be32 *bp;
 733	int ret;
 734
 735	_enter("{%u}", call->unmarshall);
 736
 737	ret = afs_transfer_reply(call);
 738	if (ret < 0)
 739		return ret;
 740
 741	bp = call->buffer;
 742	xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
 743	xdr_decode_YFSVolSync(&bp, &op->volsync);
 744	return 0;
 745}
 746
 747/*
 748 * FS.RemoveDir and FS.RemoveFile operation types.
 749 */
 750static const struct afs_call_type yfs_RXYFSRemoveFile = {
 751	.name		= "YFS.RemoveFile",
 752	.op		= yfs_FS_RemoveFile,
 753	.deliver	= yfs_deliver_fs_remove,
 754	.destructor	= afs_flat_call_destructor,
 755};
 756
 757/*
 758 * Remove a file.
 759 */
 760void yfs_fs_remove_file(struct afs_operation *op)
 761{
 762	const struct qstr *name = &op->dentry->d_name;
 763	struct afs_vnode_param *dvp = &op->file[0];
 764	struct afs_call *call;
 765	__be32 *bp;
 766
 767	_enter("");
 768
 769	if (!test_bit(AFS_SERVER_FL_NO_RM2, &op->server->flags))
 770		return yfs_fs_remove_file2(op);
 771
 772	call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveFile,
 773				   sizeof(__be32) +
 774				   sizeof(struct yfs_xdr_RPCFlags) +
 775				   sizeof(struct yfs_xdr_YFSFid) +
 776				   xdr_strlen(name->len),
 777				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 778				   sizeof(struct yfs_xdr_YFSVolSync));
 779	if (!call)
 780		return afs_op_nomem(op);
 781
 782	/* marshall the parameters */
 783	bp = call->request;
 784	bp = xdr_encode_u32(bp, YFSREMOVEFILE);
 785	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 786	bp = xdr_encode_YFSFid(bp, &dvp->fid);
 787	bp = xdr_encode_name(bp, name);
 788	yfs_check_req(call, bp);
 789
 790	call->fid = dvp->fid;
 791	trace_afs_make_fs_call1(call, &dvp->fid, name);
 792	afs_make_op_call(op, call, GFP_NOFS);
 793}
 794
 795static const struct afs_call_type yfs_RXYFSRemoveDir = {
 796	.name		= "YFS.RemoveDir",
 797	.op		= yfs_FS_RemoveDir,
 798	.deliver	= yfs_deliver_fs_remove,
 799	.destructor	= afs_flat_call_destructor,
 800};
 801
 802/*
 803 * Remove a directory.
 804 */
 805void yfs_fs_remove_dir(struct afs_operation *op)
 806{
 807	const struct qstr *name = &op->dentry->d_name;
 808	struct afs_vnode_param *dvp = &op->file[0];
 809	struct afs_call *call;
 810	__be32 *bp;
 811
 812	_enter("");
 813
 814	call = afs_alloc_flat_call(op->net, &yfs_RXYFSRemoveDir,
 815				   sizeof(__be32) +
 816				   sizeof(struct yfs_xdr_RPCFlags) +
 817				   sizeof(struct yfs_xdr_YFSFid) +
 818				   xdr_strlen(name->len),
 819				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 820				   sizeof(struct yfs_xdr_YFSVolSync));
 821	if (!call)
 822		return afs_op_nomem(op);
 823
 824	/* marshall the parameters */
 825	bp = call->request;
 826	bp = xdr_encode_u32(bp, YFSREMOVEDIR);
 827	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 828	bp = xdr_encode_YFSFid(bp, &dvp->fid);
 829	bp = xdr_encode_name(bp, name);
 830	yfs_check_req(call, bp);
 831
 832	call->fid = dvp->fid;
 833	trace_afs_make_fs_call1(call, &dvp->fid, name);
 834	afs_make_op_call(op, call, GFP_NOFS);
 835}
 836
 837/*
 838 * Deliver reply data to a YFS.Link operation.
 839 */
 840static int yfs_deliver_fs_link(struct afs_call *call)
 841{
 842	struct afs_operation *op = call->op;
 843	struct afs_vnode_param *dvp = &op->file[0];
 844	struct afs_vnode_param *vp = &op->file[1];
 845	const __be32 *bp;
 846	int ret;
 847
 848	_enter("{%u}", call->unmarshall);
 849
 850	ret = afs_transfer_reply(call);
 851	if (ret < 0)
 852		return ret;
 853
 854	bp = call->buffer;
 855	xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
 856	xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
 857	xdr_decode_YFSVolSync(&bp, &op->volsync);
 858	_leave(" = 0 [done]");
 859	return 0;
 860}
 861
 862/*
 863 * YFS.Link operation type.
 864 */
 865static const struct afs_call_type yfs_RXYFSLink = {
 866	.name		= "YFS.Link",
 867	.op		= yfs_FS_Link,
 868	.deliver	= yfs_deliver_fs_link,
 869	.destructor	= afs_flat_call_destructor,
 870};
 871
 872/*
 873 * Make a hard link.
 874 */
 875void yfs_fs_link(struct afs_operation *op)
 876{
 877	const struct qstr *name = &op->dentry->d_name;
 878	struct afs_vnode_param *dvp = &op->file[0];
 879	struct afs_vnode_param *vp = &op->file[1];
 880	struct afs_call *call;
 881	__be32 *bp;
 882
 883	_enter("");
 884
 885	call = afs_alloc_flat_call(op->net, &yfs_RXYFSLink,
 886				   sizeof(__be32) +
 887				   sizeof(struct yfs_xdr_RPCFlags) +
 888				   sizeof(struct yfs_xdr_YFSFid) +
 889				   xdr_strlen(name->len) +
 890				   sizeof(struct yfs_xdr_YFSFid),
 891				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 892				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 893				   sizeof(struct yfs_xdr_YFSVolSync));
 894	if (!call)
 895		return afs_op_nomem(op);
 896
 897	/* marshall the parameters */
 898	bp = call->request;
 899	bp = xdr_encode_u32(bp, YFSLINK);
 900	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 901	bp = xdr_encode_YFSFid(bp, &dvp->fid);
 902	bp = xdr_encode_name(bp, name);
 903	bp = xdr_encode_YFSFid(bp, &vp->fid);
 904	yfs_check_req(call, bp);
 905
 906	call->fid = vp->fid;
 907	trace_afs_make_fs_call1(call, &vp->fid, name);
 908	afs_make_op_call(op, call, GFP_NOFS);
 909}
 910
 911/*
 912 * Deliver reply data to a YFS.Symlink operation.
 913 */
 914static int yfs_deliver_fs_symlink(struct afs_call *call)
 915{
 916	struct afs_operation *op = call->op;
 917	struct afs_vnode_param *dvp = &op->file[0];
 918	struct afs_vnode_param *vp = &op->file[1];
 919	const __be32 *bp;
 920	int ret;
 921
 922	_enter("{%u}", call->unmarshall);
 923
 924	ret = afs_transfer_reply(call);
 925	if (ret < 0)
 926		return ret;
 927
 928	/* unmarshall the reply once we've received all of it */
 929	bp = call->buffer;
 930	xdr_decode_YFSFid(&bp, &vp->fid);
 931	xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
 932	xdr_decode_YFSFetchStatus(&bp, call, &dvp->scb);
 933	xdr_decode_YFSVolSync(&bp, &op->volsync);
 934
 935	_leave(" = 0 [done]");
 936	return 0;
 937}
 938
 939/*
 940 * YFS.Symlink operation type
 941 */
 942static const struct afs_call_type yfs_RXYFSSymlink = {
 943	.name		= "YFS.Symlink",
 944	.op		= yfs_FS_Symlink,
 945	.deliver	= yfs_deliver_fs_symlink,
 946	.destructor	= afs_flat_call_destructor,
 947};
 948
 949/*
 950 * Create a symbolic link.
 951 */
 952void yfs_fs_symlink(struct afs_operation *op)
 953{
 954	const struct qstr *name = &op->dentry->d_name;
 955	struct afs_vnode_param *dvp = &op->file[0];
 956	struct afs_call *call;
 957	size_t contents_sz;
 958	mode_t mode = 0777;
 959	__be32 *bp;
 960
 961	_enter("");
 962
 963	contents_sz = strlen(op->create.symlink);
 964	call = afs_alloc_flat_call(op->net, &yfs_RXYFSSymlink,
 965				   sizeof(__be32) +
 966				   sizeof(struct yfs_xdr_RPCFlags) +
 967				   sizeof(struct yfs_xdr_YFSFid) +
 968				   xdr_strlen(name->len) +
 969				   xdr_strlen(contents_sz) +
 970				   sizeof(struct yfs_xdr_YFSStoreStatus),
 971				   sizeof(struct yfs_xdr_YFSFid) +
 972				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 973				   sizeof(struct yfs_xdr_YFSFetchStatus) +
 974				   sizeof(struct yfs_xdr_YFSVolSync));
 975	if (!call)
 976		return afs_op_nomem(op);
 977
 978	/* marshall the parameters */
 979	bp = call->request;
 980	bp = xdr_encode_u32(bp, YFSSYMLINK);
 981	bp = xdr_encode_u32(bp, 0); /* RPC flags */
 982	bp = xdr_encode_YFSFid(bp, &dvp->fid);
 983	bp = xdr_encode_name(bp, name);
 984	bp = xdr_encode_string(bp, op->create.symlink, contents_sz);
 985	bp = xdr_encode_YFSStoreStatus(bp, &mode, &op->mtime);
 986	yfs_check_req(call, bp);
 987
 988	call->fid = dvp->fid;
 989	trace_afs_make_fs_call1(call, &dvp->fid, name);
 990	afs_make_op_call(op, call, GFP_NOFS);
 991}
 992
 993/*
 994 * Deliver reply data to a YFS.Rename operation.
 995 */
 996static int yfs_deliver_fs_rename(struct afs_call *call)
 997{
 998	struct afs_operation *op = call->op;
 999	struct afs_vnode_param *orig_dvp = &op->file[0];
1000	struct afs_vnode_param *new_dvp = &op->file[1];
1001	const __be32 *bp;
1002	int ret;
1003
1004	_enter("{%u}", call->unmarshall);
1005
1006	ret = afs_transfer_reply(call);
1007	if (ret < 0)
1008		return ret;
1009
1010	bp = call->buffer;
1011	/* If the two dirs are the same, we have two copies of the same status
1012	 * report, so we just decode it twice.
1013	 */
1014	xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1015	xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1016	xdr_decode_YFSVolSync(&bp, &op->volsync);
1017	_leave(" = 0 [done]");
1018	return 0;
1019}
1020
1021/*
1022 * YFS.Rename operation type
1023 */
1024static const struct afs_call_type yfs_RXYFSRename = {
1025	.name		= "FS.Rename",
1026	.op		= yfs_FS_Rename,
1027	.deliver	= yfs_deliver_fs_rename,
1028	.destructor	= afs_flat_call_destructor,
1029};
1030
1031/*
1032 * Rename a file or directory.
1033 */
1034void yfs_fs_rename(struct afs_operation *op)
1035{
1036	struct afs_vnode_param *orig_dvp = &op->file[0];
1037	struct afs_vnode_param *new_dvp = &op->file[1];
1038	const struct qstr *orig_name = &op->dentry->d_name;
1039	const struct qstr *new_name = &op->dentry_2->d_name;
1040	struct afs_call *call;
1041	__be32 *bp;
1042
1043	_enter("");
1044
1045	if (!test_bit(AFS_SERVER_FL_NO_RENAME2, &op->server->flags))
1046		return yfs_fs_rename_replace(op);
1047
1048	call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename,
1049				   sizeof(__be32) +
1050				   sizeof(struct yfs_xdr_RPCFlags) +
1051				   sizeof(struct yfs_xdr_YFSFid) +
1052				   xdr_strlen(orig_name->len) +
1053				   sizeof(struct yfs_xdr_YFSFid) +
1054				   xdr_strlen(new_name->len),
1055				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1056				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1057				   sizeof(struct yfs_xdr_YFSVolSync));
1058	if (!call)
1059		return afs_op_nomem(op);
1060
1061	/* marshall the parameters */
1062	bp = call->request;
1063	bp = xdr_encode_u32(bp, YFSRENAME);
1064	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1065	bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1066	bp = xdr_encode_name(bp, orig_name);
1067	bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1068	bp = xdr_encode_name(bp, new_name);
1069	yfs_check_req(call, bp);
1070
1071	call->fid = orig_dvp->fid;
1072	trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1073	afs_make_op_call(op, call, GFP_NOFS);
1074}
1075
1076/*
1077 * Deliver reply data to a YFS.Rename_NoReplace operation.  This does not
1078 * return the status of a displaced target inode as there cannot be one.
1079 */
1080static int yfs_deliver_fs_rename_1(struct afs_call *call)
1081{
1082	struct afs_operation *op = call->op;
1083	struct afs_vnode_param *orig_dvp = &op->file[0];
1084	struct afs_vnode_param *new_dvp = &op->file[1];
1085	struct afs_vnode_param *old_vp = &op->more_files[0];
1086	const __be32 *bp;
1087	int ret;
1088
1089	_enter("{%u}", call->unmarshall);
1090
1091	ret = afs_transfer_reply(call);
1092	if (ret < 0)
1093		return ret;
1094
1095	bp = call->buffer;
1096	/* If the two dirs are the same, we have two copies of the same status
1097	 * report, so we just decode it twice.
1098	 */
1099	xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1100	xdr_decode_YFSFid(&bp, &old_vp->fid);
1101	xdr_decode_YFSFetchStatus(&bp, call, &old_vp->scb);
1102	xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1103	xdr_decode_YFSVolSync(&bp, &op->volsync);
1104	_leave(" = 0 [done]");
1105	return 0;
1106}
1107
1108/*
1109 * Deliver reply data to a YFS.Rename_Replace or a YFS.Rename_Exchange
1110 * operation.  These return the status of the displaced target inode if there
1111 * was one.
1112 */
1113static int yfs_deliver_fs_rename_2(struct afs_call *call)
1114{
1115	struct afs_operation *op = call->op;
1116	struct afs_vnode_param *orig_dvp = &op->file[0];
1117	struct afs_vnode_param *new_dvp = &op->file[1];
1118	struct afs_vnode_param *old_vp = &op->more_files[0];
1119	struct afs_vnode_param *new_vp = &op->more_files[1];
1120	const __be32 *bp;
1121	int ret;
1122
1123	_enter("{%u}", call->unmarshall);
1124
1125	ret = afs_transfer_reply(call);
1126	if (ret < 0)
1127		return ret;
1128
1129	bp = call->buffer;
1130	/* If the two dirs are the same, we have two copies of the same status
1131	 * report, so we just decode it twice.
1132	 */
1133	xdr_decode_YFSFetchStatus(&bp, call, &orig_dvp->scb);
1134	xdr_decode_YFSFid(&bp, &old_vp->fid);
1135	xdr_decode_YFSFetchStatus(&bp, call, &old_vp->scb);
1136	xdr_decode_YFSFetchStatus(&bp, call, &new_dvp->scb);
1137	xdr_decode_YFSFid(&bp, &new_vp->fid);
1138	xdr_decode_YFSFetchStatus(&bp, call, &new_vp->scb);
1139	xdr_decode_YFSVolSync(&bp, &op->volsync);
1140	_leave(" = 0 [done]");
1141	return 0;
1142}
1143
1144static void yfs_done_fs_rename_replace(struct afs_call *call)
1145{
1146	if (call->error == -ECONNABORTED &&
1147	    (call->abort_code == RX_INVALID_OPERATION ||
1148	     call->abort_code == RXGEN_OPCODE)) {
1149		set_bit(AFS_SERVER_FL_NO_RENAME2, &call->op->server->flags);
1150		call->op->flags |= AFS_OPERATION_DOWNGRADE;
1151	}
1152}
1153
1154/*
1155 * YFS.Rename_Replace operation type
1156 */
1157static const struct afs_call_type yfs_RXYFSRename_Replace = {
1158	.name		= "FS.Rename_Replace",
1159	.op		= yfs_FS_Rename_Replace,
1160	.deliver	= yfs_deliver_fs_rename_2,
1161	.done		= yfs_done_fs_rename_replace,
1162	.destructor	= afs_flat_call_destructor,
1163};
1164
1165/*
1166 * YFS.Rename_NoReplace operation type
1167 */
1168static const struct afs_call_type yfs_RXYFSRename_NoReplace = {
1169	.name		= "FS.Rename_NoReplace",
1170	.op		= yfs_FS_Rename_NoReplace,
1171	.deliver	= yfs_deliver_fs_rename_1,
1172	.destructor	= afs_flat_call_destructor,
1173};
1174
1175/*
1176 * YFS.Rename_Exchange operation type
1177 */
1178static const struct afs_call_type yfs_RXYFSRename_Exchange = {
1179	.name		= "FS.Rename_Exchange",
1180	.op		= yfs_FS_Rename_Exchange,
1181	.deliver	= yfs_deliver_fs_rename_2,
1182	.destructor	= afs_flat_call_destructor,
1183};
1184
1185/*
1186 * Rename a file or directory, replacing the target if it exists.  The status
1187 * of a displaced target is returned.
1188 */
1189void yfs_fs_rename_replace(struct afs_operation *op)
1190{
1191	struct afs_vnode_param *orig_dvp = &op->file[0];
1192	struct afs_vnode_param *new_dvp = &op->file[1];
1193	const struct qstr *orig_name = &op->dentry->d_name;
1194	const struct qstr *new_name = &op->dentry_2->d_name;
1195	struct afs_call *call;
1196	__be32 *bp;
1197
1198	_enter("");
1199
1200	call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename_Replace,
1201				   sizeof(__be32) +
1202				   sizeof(struct yfs_xdr_RPCFlags) +
1203				   sizeof(struct yfs_xdr_YFSFid) +
1204				   xdr_strlen(orig_name->len) +
1205				   sizeof(struct yfs_xdr_YFSFid) +
1206				   xdr_strlen(new_name->len),
1207				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1208				   sizeof(struct yfs_xdr_YFSFid) +
1209				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1210				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1211				   sizeof(struct yfs_xdr_YFSFid) +
1212				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1213				   sizeof(struct yfs_xdr_YFSVolSync));
1214	if (!call)
1215		return afs_op_nomem(op);
1216
1217	/* Marshall the parameters. */
1218	bp = call->request;
1219	bp = xdr_encode_u32(bp, YFSRENAME_REPLACE);
1220	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1221	bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1222	bp = xdr_encode_name(bp, orig_name);
1223	bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1224	bp = xdr_encode_name(bp, new_name);
1225	yfs_check_req(call, bp);
1226
1227	call->fid = orig_dvp->fid;
1228	trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1229	afs_make_op_call(op, call, GFP_NOFS);
1230}
1231
1232/*
1233 * Rename a file or directory, failing if the target dirent exists.
1234 */
1235void yfs_fs_rename_noreplace(struct afs_operation *op)
1236{
1237	struct afs_vnode_param *orig_dvp = &op->file[0];
1238	struct afs_vnode_param *new_dvp = &op->file[1];
1239	const struct qstr *orig_name = &op->dentry->d_name;
1240	const struct qstr *new_name = &op->dentry_2->d_name;
1241	struct afs_call *call;
1242	__be32 *bp;
1243
1244	_enter("");
1245
1246	call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename_NoReplace,
1247				   sizeof(__be32) +
1248				   sizeof(struct yfs_xdr_RPCFlags) +
1249				   sizeof(struct yfs_xdr_YFSFid) +
1250				   xdr_strlen(orig_name->len) +
1251				   sizeof(struct yfs_xdr_YFSFid) +
1252				   xdr_strlen(new_name->len),
1253				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1254				   sizeof(struct yfs_xdr_YFSFid) +
1255				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1256				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1257				   sizeof(struct yfs_xdr_YFSVolSync));
1258	if (!call)
1259		return afs_op_nomem(op);
1260
1261	/* Marshall the parameters. */
1262	bp = call->request;
1263	bp = xdr_encode_u32(bp, YFSRENAME_NOREPLACE);
1264	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1265	bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1266	bp = xdr_encode_name(bp, orig_name);
1267	bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1268	bp = xdr_encode_name(bp, new_name);
1269	yfs_check_req(call, bp);
1270
1271	call->fid = orig_dvp->fid;
1272	trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1273	afs_make_op_call(op, call, GFP_NOFS);
1274}
1275
1276/*
1277 * Exchange a pair of files directories.
1278 */
1279void yfs_fs_rename_exchange(struct afs_operation *op)
1280{
1281	struct afs_vnode_param *orig_dvp = &op->file[0];
1282	struct afs_vnode_param *new_dvp = &op->file[1];
1283	const struct qstr *orig_name = &op->dentry->d_name;
1284	const struct qstr *new_name = &op->dentry_2->d_name;
1285	struct afs_call *call;
1286	__be32 *bp;
1287
1288	_enter("");
1289
1290	call = afs_alloc_flat_call(op->net, &yfs_RXYFSRename_Exchange,
1291				   sizeof(__be32) +
1292				   sizeof(struct yfs_xdr_RPCFlags) +
1293				   sizeof(struct yfs_xdr_YFSFid) +
1294				   xdr_strlen(orig_name->len) +
1295				   sizeof(struct yfs_xdr_YFSFid) +
1296				   xdr_strlen(new_name->len),
1297				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1298				   sizeof(struct yfs_xdr_YFSFid) +
1299				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1300				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1301				   sizeof(struct yfs_xdr_YFSFid) +
1302				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1303				   sizeof(struct yfs_xdr_YFSVolSync));
1304	if (!call)
1305		return afs_op_nomem(op);
1306
1307	/* Marshall the parameters. */
1308	bp = call->request;
1309	bp = xdr_encode_u32(bp, YFSRENAME_EXCHANGE);
1310	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1311	bp = xdr_encode_YFSFid(bp, &orig_dvp->fid);
1312	bp = xdr_encode_name(bp, orig_name);
1313	bp = xdr_encode_YFSFid(bp, &new_dvp->fid);
1314	bp = xdr_encode_name(bp, new_name);
1315	yfs_check_req(call, bp);
1316
1317	call->fid = orig_dvp->fid;
1318	trace_afs_make_fs_call2(call, &orig_dvp->fid, orig_name, new_name);
1319	afs_make_op_call(op, call, GFP_NOFS);
1320}
1321
1322/*
1323 * YFS.StoreData64 operation type.
1324 */
1325static const struct afs_call_type yfs_RXYFSStoreData64 = {
1326	.name		= "YFS.StoreData64",
1327	.op		= yfs_FS_StoreData64,
1328	.deliver	= yfs_deliver_status_and_volsync,
1329	.destructor	= afs_flat_call_destructor,
1330};
1331
1332/*
1333 * Store a set of pages to a large file.
1334 */
1335void yfs_fs_store_data(struct afs_operation *op)
1336{
1337	struct afs_vnode_param *vp = &op->file[0];
1338	struct afs_call *call;
1339	__be32 *bp;
1340
1341	_enter(",%x,{%llx:%llu},,",
1342	       key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1343
1344	_debug("size %llx, at %llx, i_size %llx",
1345	       (unsigned long long)op->store.size,
1346	       (unsigned long long)op->store.pos,
1347	       (unsigned long long)op->store.i_size);
1348
1349	call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64,
1350				   sizeof(__be32) +
1351				   sizeof(__be32) +
1352				   sizeof(struct yfs_xdr_YFSFid) +
1353				   sizeof(struct yfs_xdr_YFSStoreStatus) +
1354				   sizeof(struct yfs_xdr_u64) * 3,
1355				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1356				   sizeof(struct yfs_xdr_YFSVolSync));
1357	if (!call)
1358		return afs_op_nomem(op);
1359
1360	call->write_iter = op->store.write_iter;
1361
1362	/* marshall the parameters */
1363	bp = call->request;
1364	bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1365	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1366	bp = xdr_encode_YFSFid(bp, &vp->fid);
1367	bp = xdr_encode_YFSStoreStatus(bp, NULL, &op->mtime);
1368	bp = xdr_encode_u64(bp, op->store.pos);
1369	bp = xdr_encode_u64(bp, op->store.size);
1370	bp = xdr_encode_u64(bp, op->store.i_size);
1371	yfs_check_req(call, bp);
1372
1373	call->fid = vp->fid;
1374	trace_afs_make_fs_call(call, &vp->fid);
1375	afs_make_op_call(op, call, GFP_NOFS);
1376}
1377
1378/*
1379 * YFS.StoreStatus operation type
1380 */
1381static const struct afs_call_type yfs_RXYFSStoreStatus = {
1382	.name		= "YFS.StoreStatus",
1383	.op		= yfs_FS_StoreStatus,
1384	.deliver	= yfs_deliver_status_and_volsync,
1385	.destructor	= afs_flat_call_destructor,
1386};
1387
1388static const struct afs_call_type yfs_RXYFSStoreData64_as_Status = {
1389	.name		= "YFS.StoreData64",
1390	.op		= yfs_FS_StoreData64,
1391	.deliver	= yfs_deliver_status_and_volsync,
1392	.destructor	= afs_flat_call_destructor,
1393};
1394
1395/*
1396 * Set the attributes on a file, using YFS.StoreData64 rather than
1397 * YFS.StoreStatus so as to alter the file size also.
1398 */
1399static void yfs_fs_setattr_size(struct afs_operation *op)
1400{
1401	struct afs_vnode_param *vp = &op->file[0];
1402	struct afs_call *call;
1403	struct iattr *attr = op->setattr.attr;
1404	__be32 *bp;
1405
1406	_enter(",%x,{%llx:%llu},,",
1407	       key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1408
1409	call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreData64_as_Status,
1410				   sizeof(__be32) * 2 +
1411				   sizeof(struct yfs_xdr_YFSFid) +
1412				   sizeof(struct yfs_xdr_YFSStoreStatus) +
1413				   sizeof(struct yfs_xdr_u64) * 3,
1414				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1415				   sizeof(struct yfs_xdr_YFSVolSync));
1416	if (!call)
1417		return afs_op_nomem(op);
1418
1419	/* marshall the parameters */
1420	bp = call->request;
1421	bp = xdr_encode_u32(bp, YFSSTOREDATA64);
1422	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1423	bp = xdr_encode_YFSFid(bp, &vp->fid);
1424	bp = xdr_encode_YFS_StoreStatus(bp, attr);
1425	bp = xdr_encode_u64(bp, attr->ia_size);	/* position of start of write */
1426	bp = xdr_encode_u64(bp, 0);		/* size of write */
1427	bp = xdr_encode_u64(bp, attr->ia_size);	/* new file length */
1428	yfs_check_req(call, bp);
1429
1430	call->fid = vp->fid;
1431	trace_afs_make_fs_call(call, &vp->fid);
1432	afs_make_op_call(op, call, GFP_NOFS);
1433}
1434
1435/*
1436 * Set the attributes on a file, using YFS.StoreData64 if there's a change in
1437 * file size, and YFS.StoreStatus otherwise.
1438 */
1439void yfs_fs_setattr(struct afs_operation *op)
1440{
1441	struct afs_vnode_param *vp = &op->file[0];
1442	struct afs_call *call;
1443	struct iattr *attr = op->setattr.attr;
1444	__be32 *bp;
1445
1446	if (attr->ia_valid & ATTR_SIZE)
1447		return yfs_fs_setattr_size(op);
1448
1449	_enter(",%x,{%llx:%llu},,",
1450	       key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1451
1452	call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreStatus,
1453				   sizeof(__be32) * 2 +
1454				   sizeof(struct yfs_xdr_YFSFid) +
1455				   sizeof(struct yfs_xdr_YFSStoreStatus),
1456				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1457				   sizeof(struct yfs_xdr_YFSVolSync));
1458	if (!call)
1459		return afs_op_nomem(op);
1460
1461	/* marshall the parameters */
1462	bp = call->request;
1463	bp = xdr_encode_u32(bp, YFSSTORESTATUS);
1464	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1465	bp = xdr_encode_YFSFid(bp, &vp->fid);
1466	bp = xdr_encode_YFS_StoreStatus(bp, attr);
1467	yfs_check_req(call, bp);
1468
1469	call->fid = vp->fid;
1470	trace_afs_make_fs_call(call, &vp->fid);
1471	afs_make_op_call(op, call, GFP_NOFS);
1472}
1473
1474/*
1475 * Deliver reply data to a YFS.GetVolumeStatus operation.
1476 */
1477static int yfs_deliver_fs_get_volume_status(struct afs_call *call)
1478{
1479	struct afs_operation *op = call->op;
1480	const __be32 *bp;
1481	char *p;
1482	u32 size;
1483	int ret;
1484
1485	_enter("{%u}", call->unmarshall);
1486
1487	switch (call->unmarshall) {
1488	case 0:
1489		call->unmarshall++;
1490		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchVolumeStatus));
1491		fallthrough;
1492
1493		/* extract the returned status record */
1494	case 1:
1495		_debug("extract status");
1496		ret = afs_extract_data(call, true);
1497		if (ret < 0)
1498			return ret;
1499
1500		bp = call->buffer;
1501		xdr_decode_YFSFetchVolumeStatus(&bp, &op->volstatus.vs);
1502		call->unmarshall++;
1503		afs_extract_to_tmp(call);
1504		fallthrough;
1505
1506		/* extract the volume name length */
1507	case 2:
1508		ret = afs_extract_data(call, true);
1509		if (ret < 0)
1510			return ret;
1511
1512		call->count = ntohl(call->tmp);
1513		_debug("volname length: %u", call->count);
1514		if (call->count >= AFSNAMEMAX)
1515			return afs_protocol_error(call, afs_eproto_volname_len);
1516		size = (call->count + 3) & ~3; /* It's padded */
1517		afs_extract_to_buf(call, size);
1518		call->unmarshall++;
1519		fallthrough;
1520
1521		/* extract the volume name */
1522	case 3:
1523		_debug("extract volname");
1524		ret = afs_extract_data(call, true);
1525		if (ret < 0)
1526			return ret;
1527
1528		p = call->buffer;
1529		p[call->count] = 0;
1530		_debug("volname '%s'", p);
1531		afs_extract_to_tmp(call);
1532		call->unmarshall++;
1533		fallthrough;
1534
1535		/* extract the offline message length */
1536	case 4:
1537		ret = afs_extract_data(call, true);
1538		if (ret < 0)
1539			return ret;
1540
1541		call->count = ntohl(call->tmp);
1542		_debug("offline msg length: %u", call->count);
1543		if (call->count >= AFSNAMEMAX)
1544			return afs_protocol_error(call, afs_eproto_offline_msg_len);
1545		size = (call->count + 3) & ~3; /* It's padded */
1546		afs_extract_to_buf(call, size);
1547		call->unmarshall++;
1548		fallthrough;
1549
1550		/* extract the offline message */
1551	case 5:
1552		_debug("extract offline");
1553		ret = afs_extract_data(call, true);
1554		if (ret < 0)
1555			return ret;
1556
1557		p = call->buffer;
1558		p[call->count] = 0;
1559		_debug("offline '%s'", p);
1560
1561		afs_extract_to_tmp(call);
1562		call->unmarshall++;
1563		fallthrough;
1564
1565		/* extract the message of the day length */
1566	case 6:
1567		ret = afs_extract_data(call, true);
1568		if (ret < 0)
1569			return ret;
1570
1571		call->count = ntohl(call->tmp);
1572		_debug("motd length: %u", call->count);
1573		if (call->count >= AFSNAMEMAX)
1574			return afs_protocol_error(call, afs_eproto_motd_len);
1575		size = (call->count + 3) & ~3; /* It's padded */
1576		afs_extract_to_buf(call, size);
1577		call->unmarshall++;
1578		fallthrough;
1579
1580		/* extract the message of the day */
1581	case 7:
1582		_debug("extract motd");
1583		ret = afs_extract_data(call, false);
1584		if (ret < 0)
1585			return ret;
1586
1587		p = call->buffer;
1588		p[call->count] = 0;
1589		_debug("motd '%s'", p);
1590
1591		call->unmarshall++;
1592		fallthrough;
1593
1594	case 8:
1595		break;
1596	}
1597
1598	_leave(" = 0 [done]");
1599	return 0;
1600}
1601
1602/*
1603 * YFS.GetVolumeStatus operation type
1604 */
1605static const struct afs_call_type yfs_RXYFSGetVolumeStatus = {
1606	.name		= "YFS.GetVolumeStatus",
1607	.op		= yfs_FS_GetVolumeStatus,
1608	.deliver	= yfs_deliver_fs_get_volume_status,
1609	.destructor	= afs_flat_call_destructor,
1610};
1611
1612/*
1613 * fetch the status of a volume
1614 */
1615void yfs_fs_get_volume_status(struct afs_operation *op)
1616{
1617	struct afs_vnode_param *vp = &op->file[0];
1618	struct afs_call *call;
1619	__be32 *bp;
1620
1621	_enter("");
1622
1623	call = afs_alloc_flat_call(op->net, &yfs_RXYFSGetVolumeStatus,
1624				   sizeof(__be32) * 2 +
1625				   sizeof(struct yfs_xdr_u64),
1626				   max_t(size_t,
1627					 sizeof(struct yfs_xdr_YFSFetchVolumeStatus) +
1628					 sizeof(__be32),
1629					 AFSOPAQUEMAX + 1));
1630	if (!call)
1631		return afs_op_nomem(op);
1632
1633	/* marshall the parameters */
1634	bp = call->request;
1635	bp = xdr_encode_u32(bp, YFSGETVOLUMESTATUS);
1636	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1637	bp = xdr_encode_u64(bp, vp->fid.vid);
1638	yfs_check_req(call, bp);
1639
1640	call->fid = vp->fid;
1641	trace_afs_make_fs_call(call, &vp->fid);
1642	afs_make_op_call(op, call, GFP_NOFS);
1643}
1644
1645/*
1646 * YFS.SetLock operation type
1647 */
1648static const struct afs_call_type yfs_RXYFSSetLock = {
1649	.name		= "YFS.SetLock",
1650	.op		= yfs_FS_SetLock,
1651	.deliver	= yfs_deliver_status_and_volsync,
1652	.done		= afs_lock_op_done,
1653	.destructor	= afs_flat_call_destructor,
1654};
1655
1656/*
1657 * YFS.ExtendLock operation type
1658 */
1659static const struct afs_call_type yfs_RXYFSExtendLock = {
1660	.name		= "YFS.ExtendLock",
1661	.op		= yfs_FS_ExtendLock,
1662	.deliver	= yfs_deliver_status_and_volsync,
1663	.done		= afs_lock_op_done,
1664	.destructor	= afs_flat_call_destructor,
1665};
1666
1667/*
1668 * YFS.ReleaseLock operation type
1669 */
1670static const struct afs_call_type yfs_RXYFSReleaseLock = {
1671	.name		= "YFS.ReleaseLock",
1672	.op		= yfs_FS_ReleaseLock,
1673	.deliver	= yfs_deliver_status_and_volsync,
1674	.destructor	= afs_flat_call_destructor,
1675};
1676
1677/*
1678 * Set a lock on a file
1679 */
1680void yfs_fs_set_lock(struct afs_operation *op)
1681{
1682	struct afs_vnode_param *vp = &op->file[0];
1683	struct afs_call *call;
1684	__be32 *bp;
1685
1686	_enter("");
1687
1688	call = afs_alloc_flat_call(op->net, &yfs_RXYFSSetLock,
1689				   sizeof(__be32) * 2 +
1690				   sizeof(struct yfs_xdr_YFSFid) +
1691				   sizeof(__be32),
1692				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1693				   sizeof(struct yfs_xdr_YFSVolSync));
1694	if (!call)
1695		return afs_op_nomem(op);
1696
1697	/* marshall the parameters */
1698	bp = call->request;
1699	bp = xdr_encode_u32(bp, YFSSETLOCK);
1700	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1701	bp = xdr_encode_YFSFid(bp, &vp->fid);
1702	bp = xdr_encode_u32(bp, op->lock.type);
1703	yfs_check_req(call, bp);
1704
1705	call->fid = vp->fid;
1706	trace_afs_make_fs_calli(call, &vp->fid, op->lock.type);
1707	afs_make_op_call(op, call, GFP_NOFS);
1708}
1709
1710/*
1711 * extend a lock on a file
1712 */
1713void yfs_fs_extend_lock(struct afs_operation *op)
1714{
1715	struct afs_vnode_param *vp = &op->file[0];
1716	struct afs_call *call;
1717	__be32 *bp;
1718
1719	_enter("");
1720
1721	call = afs_alloc_flat_call(op->net, &yfs_RXYFSExtendLock,
1722				   sizeof(__be32) * 2 +
1723				   sizeof(struct yfs_xdr_YFSFid),
1724				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1725				   sizeof(struct yfs_xdr_YFSVolSync));
1726	if (!call)
1727		return afs_op_nomem(op);
1728
1729	/* marshall the parameters */
1730	bp = call->request;
1731	bp = xdr_encode_u32(bp, YFSEXTENDLOCK);
1732	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1733	bp = xdr_encode_YFSFid(bp, &vp->fid);
1734	yfs_check_req(call, bp);
1735
1736	call->fid = vp->fid;
1737	trace_afs_make_fs_call(call, &vp->fid);
1738	afs_make_op_call(op, call, GFP_NOFS);
1739}
1740
1741/*
1742 * release a lock on a file
1743 */
1744void yfs_fs_release_lock(struct afs_operation *op)
1745{
1746	struct afs_vnode_param *vp = &op->file[0];
1747	struct afs_call *call;
1748	__be32 *bp;
1749
1750	_enter("");
1751
1752	call = afs_alloc_flat_call(op->net, &yfs_RXYFSReleaseLock,
1753				   sizeof(__be32) * 2 +
1754				   sizeof(struct yfs_xdr_YFSFid),
1755				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1756				   sizeof(struct yfs_xdr_YFSVolSync));
1757	if (!call)
1758		return afs_op_nomem(op);
1759
1760	/* marshall the parameters */
1761	bp = call->request;
1762	bp = xdr_encode_u32(bp, YFSRELEASELOCK);
1763	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1764	bp = xdr_encode_YFSFid(bp, &vp->fid);
1765	yfs_check_req(call, bp);
1766
1767	call->fid = vp->fid;
1768	trace_afs_make_fs_call(call, &vp->fid);
1769	afs_make_op_call(op, call, GFP_NOFS);
1770}
1771
1772/*
1773 * Deliver a reply to YFS.FetchStatus
1774 */
1775static int yfs_deliver_fs_fetch_status(struct afs_call *call)
1776{
1777	struct afs_operation *op = call->op;
1778	struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1779	const __be32 *bp;
1780	int ret;
1781
1782	ret = afs_transfer_reply(call);
1783	if (ret < 0)
1784		return ret;
1785
1786	/* unmarshall the reply once we've received all of it */
1787	bp = call->buffer;
1788	xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
1789	xdr_decode_YFSCallBack(&bp, call, &vp->scb);
1790	xdr_decode_YFSVolSync(&bp, &op->volsync);
1791
1792	_leave(" = 0 [done]");
1793	return 0;
1794}
1795
1796/*
1797 * YFS.FetchStatus operation type
1798 */
1799static const struct afs_call_type yfs_RXYFSFetchStatus = {
1800	.name		= "YFS.FetchStatus",
1801	.op		= yfs_FS_FetchStatus,
1802	.deliver	= yfs_deliver_fs_fetch_status,
1803	.destructor	= afs_flat_call_destructor,
1804};
1805
1806/*
1807 * Fetch the status information for a fid without needing a vnode handle.
1808 */
1809void yfs_fs_fetch_status(struct afs_operation *op)
1810{
1811	struct afs_vnode_param *vp = &op->file[op->fetch_status.which];
1812	struct afs_call *call;
1813	__be32 *bp;
1814
1815	_enter(",%x,{%llx:%llu},,",
1816	       key_serial(op->key), vp->fid.vid, vp->fid.vnode);
1817
1818	call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchStatus,
1819				   sizeof(__be32) * 2 +
1820				   sizeof(struct yfs_xdr_YFSFid),
1821				   sizeof(struct yfs_xdr_YFSFetchStatus) +
1822				   sizeof(struct yfs_xdr_YFSCallBack) +
1823				   sizeof(struct yfs_xdr_YFSVolSync));
1824	if (!call)
1825		return afs_op_nomem(op);
1826
1827	/* marshall the parameters */
1828	bp = call->request;
1829	bp = xdr_encode_u32(bp, YFSFETCHSTATUS);
1830	bp = xdr_encode_u32(bp, 0); /* RPC flags */
1831	bp = xdr_encode_YFSFid(bp, &vp->fid);
1832	yfs_check_req(call, bp);
1833
1834	call->fid = vp->fid;
1835	trace_afs_make_fs_call(call, &vp->fid);
1836	afs_make_op_call(op, call, GFP_NOFS);
1837}
1838
1839/*
1840 * Deliver reply data to an YFS.InlineBulkStatus call
1841 */
1842static int yfs_deliver_fs_inline_bulk_status(struct afs_call *call)
1843{
1844	struct afs_operation *op = call->op;
1845	struct afs_status_cb *scb;
1846	const __be32 *bp;
1847	u32 tmp;
1848	int ret;
1849
1850	_enter("{%u}", call->unmarshall);
1851
1852	switch (call->unmarshall) {
1853	case 0:
1854		afs_extract_to_tmp(call);
1855		call->unmarshall++;
1856		fallthrough;
1857
1858		/* Extract the file status count and array in two steps */
1859	case 1:
1860		_debug("extract status count");
1861		ret = afs_extract_data(call, true);
1862		if (ret < 0)
1863			return ret;
1864
1865		tmp = ntohl(call->tmp);
1866		_debug("status count: %u/%u", tmp, op->nr_files);
1867		if (tmp != op->nr_files)
1868			return afs_protocol_error(call, afs_eproto_ibulkst_count);
1869
1870		call->count = 0;
1871		call->unmarshall++;
1872	more_counts:
1873		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSFetchStatus));
1874		fallthrough;
1875
1876	case 2:
1877		_debug("extract status array %u", call->count);
1878		ret = afs_extract_data(call, true);
1879		if (ret < 0)
1880			return ret;
1881
1882		switch (call->count) {
1883		case 0:
1884			scb = &op->file[0].scb;
1885			break;
1886		case 1:
1887			scb = &op->file[1].scb;
1888			break;
1889		default:
1890			scb = &op->more_files[call->count - 2].scb;
1891			break;
1892		}
1893
1894		bp = call->buffer;
1895		xdr_decode_YFSFetchStatus(&bp, call, scb);
1896
1897		call->count++;
1898		if (call->count < op->nr_files)
1899			goto more_counts;
1900
1901		call->count = 0;
1902		call->unmarshall++;
1903		afs_extract_to_tmp(call);
1904		fallthrough;
1905
1906		/* Extract the callback count and array in two steps */
1907	case 3:
1908		_debug("extract CB count");
1909		ret = afs_extract_data(call, true);
1910		if (ret < 0)
1911			return ret;
1912
1913		tmp = ntohl(call->tmp);
1914		_debug("CB count: %u", tmp);
1915		if (tmp != op->nr_files)
1916			return afs_protocol_error(call, afs_eproto_ibulkst_cb_count);
1917		call->count = 0;
1918		call->unmarshall++;
1919	more_cbs:
1920		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSCallBack));
1921		fallthrough;
1922
1923	case 4:
1924		_debug("extract CB array");
1925		ret = afs_extract_data(call, true);
1926		if (ret < 0)
1927			return ret;
1928
1929		_debug("unmarshall CB array");
1930		switch (call->count) {
1931		case 0:
1932			scb = &op->file[0].scb;
1933			break;
1934		case 1:
1935			scb = &op->file[1].scb;
1936			break;
1937		default:
1938			scb = &op->more_files[call->count - 2].scb;
1939			break;
1940		}
1941
1942		bp = call->buffer;
1943		xdr_decode_YFSCallBack(&bp, call, scb);
1944		call->count++;
1945		if (call->count < op->nr_files)
1946			goto more_cbs;
1947
1948		afs_extract_to_buf(call, sizeof(struct yfs_xdr_YFSVolSync));
1949		call->unmarshall++;
1950		fallthrough;
1951
1952	case 5:
1953		ret = afs_extract_data(call, false);
1954		if (ret < 0)
1955			return ret;
1956
1957		bp = call->buffer;
1958		xdr_decode_YFSVolSync(&bp, &op->volsync);
1959
1960		call->unmarshall++;
1961		fallthrough;
1962
1963	case 6:
1964		break;
1965	}
1966
1967	_leave(" = 0 [done]");
1968	return 0;
1969}
1970
1971/*
1972 * FS.InlineBulkStatus operation type
1973 */
1974static const struct afs_call_type yfs_RXYFSInlineBulkStatus = {
1975	.name		= "YFS.InlineBulkStatus",
1976	.op		= yfs_FS_InlineBulkStatus,
1977	.deliver	= yfs_deliver_fs_inline_bulk_status,
1978	.destructor	= afs_flat_call_destructor,
1979};
1980
1981/*
1982 * Fetch the status information for up to 1024 files
1983 */
1984void yfs_fs_inline_bulk_status(struct afs_operation *op)
1985{
1986	struct afs_vnode_param *dvp = &op->file[0];
1987	struct afs_vnode_param *vp = &op->file[1];
1988	struct afs_call *call;
1989	__be32 *bp;
1990	int i;
1991
1992	_enter(",%x,{%llx:%llu},%u",
1993	       key_serial(op->key), vp->fid.vid, vp->fid.vnode, op->nr_files);
1994
1995	call = afs_alloc_flat_call(op->net, &yfs_RXYFSInlineBulkStatus,
1996				   sizeof(__be32) +
1997				   sizeof(__be32) +
1998				   sizeof(__be32) +
1999				   sizeof(struct yfs_xdr_YFSFid) * op->nr_files,
2000				   sizeof(struct yfs_xdr_YFSFetchStatus));
2001	if (!call)
2002		return afs_op_nomem(op);
2003
2004	/* marshall the parameters */
2005	bp = call->request;
2006	bp = xdr_encode_u32(bp, YFSINLINEBULKSTATUS);
2007	bp = xdr_encode_u32(bp, 0); /* RPCFlags */
2008	bp = xdr_encode_u32(bp, op->nr_files);
2009	bp = xdr_encode_YFSFid(bp, &dvp->fid);
2010	bp = xdr_encode_YFSFid(bp, &vp->fid);
2011	for (i = 0; i < op->nr_files - 2; i++)
2012		bp = xdr_encode_YFSFid(bp, &op->more_files[i].fid);
2013	yfs_check_req(call, bp);
2014
2015	call->fid = vp->fid;
2016	trace_afs_make_fs_call(call, &vp->fid);
2017	afs_make_op_call(op, call, GFP_NOFS);
2018}
2019
2020/*
2021 * Deliver reply data to an YFS.FetchOpaqueACL.
2022 */
2023static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call)
2024{
2025	struct afs_operation *op = call->op;
2026	struct afs_vnode_param *vp = &op->file[0];
2027	struct yfs_acl *yacl = op->yacl;
2028	struct afs_acl *acl;
2029	const __be32 *bp;
2030	unsigned int size;
2031	int ret;
2032
2033	_enter("{%u}", call->unmarshall);
2034
2035	switch (call->unmarshall) {
2036	case 0:
2037		afs_extract_to_tmp(call);
2038		call->unmarshall++;
2039		fallthrough;
2040
2041		/* Extract the file ACL length */
2042	case 1:
2043		ret = afs_extract_data(call, true);
2044		if (ret < 0)
2045			return ret;
2046
2047		size = call->count2 = ntohl(call->tmp);
2048		size = round_up(size, 4);
2049
2050		if (yacl->flags & YFS_ACL_WANT_ACL) {
2051			acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2052			if (!acl)
2053				return -ENOMEM;
2054			yacl->acl = acl;
2055			acl->size = call->count2;
2056			afs_extract_begin(call, acl->data, size);
2057		} else {
2058			afs_extract_discard(call, size);
2059		}
2060		call->unmarshall++;
2061		fallthrough;
2062
2063		/* Extract the file ACL */
2064	case 2:
2065		ret = afs_extract_data(call, true);
2066		if (ret < 0)
2067			return ret;
2068
2069		afs_extract_to_tmp(call);
2070		call->unmarshall++;
2071		fallthrough;
2072
2073		/* Extract the volume ACL length */
2074	case 3:
2075		ret = afs_extract_data(call, true);
2076		if (ret < 0)
2077			return ret;
2078
2079		size = call->count2 = ntohl(call->tmp);
2080		size = round_up(size, 4);
2081
2082		if (yacl->flags & YFS_ACL_WANT_VOL_ACL) {
2083			acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL);
2084			if (!acl)
2085				return -ENOMEM;
2086			yacl->vol_acl = acl;
2087			acl->size = call->count2;
2088			afs_extract_begin(call, acl->data, size);
2089		} else {
2090			afs_extract_discard(call, size);
2091		}
2092		call->unmarshall++;
2093		fallthrough;
2094
2095		/* Extract the volume ACL */
2096	case 4:
2097		ret = afs_extract_data(call, true);
2098		if (ret < 0)
2099			return ret;
2100
2101		afs_extract_to_buf(call,
2102				   sizeof(__be32) * 2 +
2103				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2104				   sizeof(struct yfs_xdr_YFSVolSync));
2105		call->unmarshall++;
2106		fallthrough;
2107
2108		/* extract the metadata */
2109	case 5:
2110		ret = afs_extract_data(call, false);
2111		if (ret < 0)
2112			return ret;
2113
2114		bp = call->buffer;
2115		yacl->inherit_flag = ntohl(*bp++);
2116		yacl->num_cleaned = ntohl(*bp++);
2117		xdr_decode_YFSFetchStatus(&bp, call, &vp->scb);
2118		xdr_decode_YFSVolSync(&bp, &op->volsync);
2119
2120		call->unmarshall++;
2121		fallthrough;
2122
2123	case 6:
2124		break;
2125	}
2126
2127	_leave(" = 0 [done]");
2128	return 0;
2129}
2130
2131void yfs_free_opaque_acl(struct yfs_acl *yacl)
2132{
2133	if (yacl) {
2134		kfree(yacl->acl);
2135		kfree(yacl->vol_acl);
2136		kfree(yacl);
2137	}
2138}
2139
2140/*
2141 * YFS.FetchOpaqueACL operation type
2142 */
2143static const struct afs_call_type yfs_RXYFSFetchOpaqueACL = {
2144	.name		= "YFS.FetchOpaqueACL",
2145	.op		= yfs_FS_FetchOpaqueACL,
2146	.deliver	= yfs_deliver_fs_fetch_opaque_acl,
2147	.destructor	= afs_flat_call_destructor,
2148};
2149
2150/*
2151 * Fetch the YFS advanced ACLs for a file.
2152 */
2153void yfs_fs_fetch_opaque_acl(struct afs_operation *op)
2154{
2155	struct afs_vnode_param *vp = &op->file[0];
2156	struct afs_call *call;
2157	__be32 *bp;
2158
2159	_enter(",%x,{%llx:%llu},,",
2160	       key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2161
2162	call = afs_alloc_flat_call(op->net, &yfs_RXYFSFetchOpaqueACL,
2163				   sizeof(__be32) * 2 +
2164				   sizeof(struct yfs_xdr_YFSFid),
2165				   sizeof(__be32) * 2 +
2166				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2167				   sizeof(struct yfs_xdr_YFSVolSync));
2168	if (!call)
2169		return afs_op_nomem(op);
2170
2171	/* marshall the parameters */
2172	bp = call->request;
2173	bp = xdr_encode_u32(bp, YFSFETCHOPAQUEACL);
2174	bp = xdr_encode_u32(bp, 0); /* RPC flags */
2175	bp = xdr_encode_YFSFid(bp, &vp->fid);
2176	yfs_check_req(call, bp);
2177
2178	call->fid = vp->fid;
2179	trace_afs_make_fs_call(call, &vp->fid);
2180	afs_make_op_call(op, call, GFP_KERNEL);
2181}
2182
2183/*
2184 * YFS.StoreOpaqueACL2 operation type
2185 */
2186static const struct afs_call_type yfs_RXYFSStoreOpaqueACL2 = {
2187	.name		= "YFS.StoreOpaqueACL2",
2188	.op		= yfs_FS_StoreOpaqueACL2,
2189	.deliver	= yfs_deliver_status_and_volsync,
2190	.destructor	= afs_flat_call_destructor,
2191};
2192
2193/*
2194 * Fetch the YFS ACL for a file.
2195 */
2196void yfs_fs_store_opaque_acl2(struct afs_operation *op)
2197{
2198	struct afs_vnode_param *vp = &op->file[0];
2199	struct afs_call *call;
2200	struct afs_acl *acl = op->acl;
2201	size_t size;
2202	__be32 *bp;
2203
2204	_enter(",%x,{%llx:%llu},,",
2205	       key_serial(op->key), vp->fid.vid, vp->fid.vnode);
2206
2207	size = round_up(acl->size, 4);
2208	call = afs_alloc_flat_call(op->net, &yfs_RXYFSStoreOpaqueACL2,
2209				   sizeof(__be32) * 2 +
2210				   sizeof(struct yfs_xdr_YFSFid) +
2211				   sizeof(__be32) + size,
2212				   sizeof(struct yfs_xdr_YFSFetchStatus) +
2213				   sizeof(struct yfs_xdr_YFSVolSync));
2214	if (!call)
2215		return afs_op_nomem(op);
2216
2217	/* marshall the parameters */
2218	bp = call->request;
2219	bp = xdr_encode_u32(bp, YFSSTOREOPAQUEACL2);
2220	bp = xdr_encode_u32(bp, 0); /* RPC flags */
2221	bp = xdr_encode_YFSFid(bp, &vp->fid);
2222	bp = xdr_encode_u32(bp, acl->size);
2223	memcpy(bp, acl->data, acl->size);
2224	if (acl->size != size)
2225		memset((void *)bp + acl->size, 0, size - acl->size);
2226	bp += size / sizeof(__be32);
2227	yfs_check_req(call, bp);
2228
2229	call->fid = vp->fid;
2230	trace_afs_make_fs_call(call, &vp->fid);
2231	afs_make_op_call(op, call, GFP_KERNEL);
2232}
~/ Read-only file preview.