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

vlclient.c (18847B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* AFS Volume Location Service client
      3 *
      4 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
      5 * Written by David Howells (dhowells@redhat.com)
      6 */
      7
      8#include <linux/gfp.h>
      9#include <linux/init.h>
     10#include <linux/sched.h>
     11#include "afs_fs.h"
     12#include "internal.h"
     13
     14/*
     15 * Deliver reply data to a VL.GetEntryByNameU call.
     16 */
     17static int afs_deliver_vl_get_entry_by_name_u(struct afs_call *call)
     18{
     19	struct afs_uvldbentry__xdr *uvldb;
     20	struct afs_vldb_entry *entry;
     21	bool new_only = false;
     22	u32 tmp, nr_servers, vlflags;
     23	int i, ret;
     24
     25	_enter("");
     26
     27	ret = afs_transfer_reply(call);
     28	if (ret < 0)
     29		return ret;
     30
     31	/* unmarshall the reply once we've received all of it */
     32	uvldb = call->buffer;
     33	entry = call->ret_vldb;
     34
     35	nr_servers = ntohl(uvldb->nServers);
     36	if (nr_servers > AFS_NMAXNSERVERS)
     37		nr_servers = AFS_NMAXNSERVERS;
     38
     39	for (i = 0; i < ARRAY_SIZE(uvldb->name) - 1; i++)
     40		entry->name[i] = (u8)ntohl(uvldb->name[i]);
     41	entry->name[i] = 0;
     42	entry->name_len = strlen(entry->name);
     43
     44	/* If there is a new replication site that we can use, ignore all the
     45	 * sites that aren't marked as new.
     46	 */
     47	for (i = 0; i < nr_servers; i++) {
     48		tmp = ntohl(uvldb->serverFlags[i]);
     49		if (!(tmp & AFS_VLSF_DONTUSE) &&
     50		    (tmp & AFS_VLSF_NEWREPSITE))
     51			new_only = true;
     52	}
     53
     54	vlflags = ntohl(uvldb->flags);
     55	for (i = 0; i < nr_servers; i++) {
     56		struct afs_uuid__xdr *xdr;
     57		struct afs_uuid *uuid;
     58		int j;
     59		int n = entry->nr_servers;
     60
     61		tmp = ntohl(uvldb->serverFlags[i]);
     62		if (tmp & AFS_VLSF_DONTUSE ||
     63		    (new_only && !(tmp & AFS_VLSF_NEWREPSITE)))
     64			continue;
     65		if (tmp & AFS_VLSF_RWVOL) {
     66			entry->fs_mask[n] |= AFS_VOL_VTM_RW;
     67			if (vlflags & AFS_VLF_BACKEXISTS)
     68				entry->fs_mask[n] |= AFS_VOL_VTM_BAK;
     69		}
     70		if (tmp & AFS_VLSF_ROVOL)
     71			entry->fs_mask[n] |= AFS_VOL_VTM_RO;
     72		if (!entry->fs_mask[n])
     73			continue;
     74
     75		xdr = &uvldb->serverNumber[i];
     76		uuid = (struct afs_uuid *)&entry->fs_server[n];
     77		uuid->time_low			= xdr->time_low;
     78		uuid->time_mid			= htons(ntohl(xdr->time_mid));
     79		uuid->time_hi_and_version	= htons(ntohl(xdr->time_hi_and_version));
     80		uuid->clock_seq_hi_and_reserved	= (u8)ntohl(xdr->clock_seq_hi_and_reserved);
     81		uuid->clock_seq_low		= (u8)ntohl(xdr->clock_seq_low);
     82		for (j = 0; j < 6; j++)
     83			uuid->node[j] = (u8)ntohl(xdr->node[j]);
     84
     85		entry->addr_version[n] = ntohl(uvldb->serverUnique[i]);
     86		entry->nr_servers++;
     87	}
     88
     89	for (i = 0; i < AFS_MAXTYPES; i++)
     90		entry->vid[i] = ntohl(uvldb->volumeId[i]);
     91
     92	if (vlflags & AFS_VLF_RWEXISTS)
     93		__set_bit(AFS_VLDB_HAS_RW, &entry->flags);
     94	if (vlflags & AFS_VLF_ROEXISTS)
     95		__set_bit(AFS_VLDB_HAS_RO, &entry->flags);
     96	if (vlflags & AFS_VLF_BACKEXISTS)
     97		__set_bit(AFS_VLDB_HAS_BAK, &entry->flags);
     98
     99	if (!(vlflags & (AFS_VLF_RWEXISTS | AFS_VLF_ROEXISTS | AFS_VLF_BACKEXISTS))) {
    100		entry->error = -ENOMEDIUM;
    101		__set_bit(AFS_VLDB_QUERY_ERROR, &entry->flags);
    102	}
    103
    104	__set_bit(AFS_VLDB_QUERY_VALID, &entry->flags);
    105	_leave(" = 0 [done]");
    106	return 0;
    107}
    108
    109static void afs_destroy_vl_get_entry_by_name_u(struct afs_call *call)
    110{
    111	kfree(call->ret_vldb);
    112	afs_flat_call_destructor(call);
    113}
    114
    115/*
    116 * VL.GetEntryByNameU operation type.
    117 */
    118static const struct afs_call_type afs_RXVLGetEntryByNameU = {
    119	.name		= "VL.GetEntryByNameU",
    120	.op		= afs_VL_GetEntryByNameU,
    121	.deliver	= afs_deliver_vl_get_entry_by_name_u,
    122	.destructor	= afs_destroy_vl_get_entry_by_name_u,
    123};
    124
    125/*
    126 * Dispatch a get volume entry by name or ID operation (uuid variant).  If the
    127 * volname is a decimal number then it's a volume ID not a volume name.
    128 */
    129struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc,
    130						  const char *volname,
    131						  int volnamesz)
    132{
    133	struct afs_vldb_entry *entry;
    134	struct afs_call *call;
    135	struct afs_net *net = vc->cell->net;
    136	size_t reqsz, padsz;
    137	__be32 *bp;
    138
    139	_enter("");
    140
    141	padsz = (4 - (volnamesz & 3)) & 3;
    142	reqsz = 8 + volnamesz + padsz;
    143
    144	entry = kzalloc(sizeof(struct afs_vldb_entry), GFP_KERNEL);
    145	if (!entry)
    146		return ERR_PTR(-ENOMEM);
    147
    148	call = afs_alloc_flat_call(net, &afs_RXVLGetEntryByNameU, reqsz,
    149				   sizeof(struct afs_uvldbentry__xdr));
    150	if (!call) {
    151		kfree(entry);
    152		return ERR_PTR(-ENOMEM);
    153	}
    154
    155	call->key = vc->key;
    156	call->ret_vldb = entry;
    157	call->max_lifespan = AFS_VL_MAX_LIFESPAN;
    158
    159	/* Marshall the parameters */
    160	bp = call->request;
    161	*bp++ = htonl(VLGETENTRYBYNAMEU);
    162	*bp++ = htonl(volnamesz);
    163	memcpy(bp, volname, volnamesz);
    164	if (padsz > 0)
    165		memset((void *)bp + volnamesz, 0, padsz);
    166
    167	trace_afs_make_vl_call(call);
    168	afs_make_call(&vc->ac, call, GFP_KERNEL);
    169	return (struct afs_vldb_entry *)afs_wait_for_call_to_complete(call, &vc->ac);
    170}
    171
    172/*
    173 * Deliver reply data to a VL.GetAddrsU call.
    174 *
    175 *	GetAddrsU(IN ListAddrByAttributes *inaddr,
    176 *		  OUT afsUUID *uuidp1,
    177 *		  OUT uint32_t *uniquifier,
    178 *		  OUT uint32_t *nentries,
    179 *		  OUT bulkaddrs *blkaddrs);
    180 */
    181static int afs_deliver_vl_get_addrs_u(struct afs_call *call)
    182{
    183	struct afs_addr_list *alist;
    184	__be32 *bp;
    185	u32 uniquifier, nentries, count;
    186	int i, ret;
    187
    188	_enter("{%u,%zu/%u}",
    189	       call->unmarshall, iov_iter_count(call->iter), call->count);
    190
    191	switch (call->unmarshall) {
    192	case 0:
    193		afs_extract_to_buf(call,
    194				   sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32));
    195		call->unmarshall++;
    196
    197		/* Extract the returned uuid, uniquifier, nentries and
    198		 * blkaddrs size */
    199		fallthrough;
    200	case 1:
    201		ret = afs_extract_data(call, true);
    202		if (ret < 0)
    203			return ret;
    204
    205		bp = call->buffer + sizeof(struct afs_uuid__xdr);
    206		uniquifier	= ntohl(*bp++);
    207		nentries	= ntohl(*bp++);
    208		count		= ntohl(*bp);
    209
    210		nentries = min(nentries, count);
    211		alist = afs_alloc_addrlist(nentries, FS_SERVICE, AFS_FS_PORT);
    212		if (!alist)
    213			return -ENOMEM;
    214		alist->version = uniquifier;
    215		call->ret_alist = alist;
    216		call->count = count;
    217		call->count2 = nentries;
    218		call->unmarshall++;
    219
    220	more_entries:
    221		count = min(call->count, 4U);
    222		afs_extract_to_buf(call, count * sizeof(__be32));
    223
    224		fallthrough;	/* and extract entries */
    225	case 2:
    226		ret = afs_extract_data(call, call->count > 4);
    227		if (ret < 0)
    228			return ret;
    229
    230		alist = call->ret_alist;
    231		bp = call->buffer;
    232		count = min(call->count, 4U);
    233		for (i = 0; i < count; i++)
    234			if (alist->nr_addrs < call->count2)
    235				afs_merge_fs_addr4(alist, *bp++, AFS_FS_PORT);
    236
    237		call->count -= count;
    238		if (call->count > 0)
    239			goto more_entries;
    240		call->unmarshall++;
    241		break;
    242	}
    243
    244	_leave(" = 0 [done]");
    245	return 0;
    246}
    247
    248static void afs_vl_get_addrs_u_destructor(struct afs_call *call)
    249{
    250	afs_put_addrlist(call->ret_alist);
    251	return afs_flat_call_destructor(call);
    252}
    253
    254/*
    255 * VL.GetAddrsU operation type.
    256 */
    257static const struct afs_call_type afs_RXVLGetAddrsU = {
    258	.name		= "VL.GetAddrsU",
    259	.op		= afs_VL_GetAddrsU,
    260	.deliver	= afs_deliver_vl_get_addrs_u,
    261	.destructor	= afs_vl_get_addrs_u_destructor,
    262};
    263
    264/*
    265 * Dispatch an operation to get the addresses for a server, where the server is
    266 * nominated by UUID.
    267 */
    268struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *vc,
    269					 const uuid_t *uuid)
    270{
    271	struct afs_ListAddrByAttributes__xdr *r;
    272	const struct afs_uuid *u = (const struct afs_uuid *)uuid;
    273	struct afs_call *call;
    274	struct afs_net *net = vc->cell->net;
    275	__be32 *bp;
    276	int i;
    277
    278	_enter("");
    279
    280	call = afs_alloc_flat_call(net, &afs_RXVLGetAddrsU,
    281				   sizeof(__be32) + sizeof(struct afs_ListAddrByAttributes__xdr),
    282				   sizeof(struct afs_uuid__xdr) + 3 * sizeof(__be32));
    283	if (!call)
    284		return ERR_PTR(-ENOMEM);
    285
    286	call->key = vc->key;
    287	call->ret_alist = NULL;
    288	call->max_lifespan = AFS_VL_MAX_LIFESPAN;
    289
    290	/* Marshall the parameters */
    291	bp = call->request;
    292	*bp++ = htonl(VLGETADDRSU);
    293	r = (struct afs_ListAddrByAttributes__xdr *)bp;
    294	r->Mask		= htonl(AFS_VLADDR_UUID);
    295	r->ipaddr	= 0;
    296	r->index	= 0;
    297	r->spare	= 0;
    298	r->uuid.time_low			= u->time_low;
    299	r->uuid.time_mid			= htonl(ntohs(u->time_mid));
    300	r->uuid.time_hi_and_version		= htonl(ntohs(u->time_hi_and_version));
    301	r->uuid.clock_seq_hi_and_reserved 	= htonl(u->clock_seq_hi_and_reserved);
    302	r->uuid.clock_seq_low			= htonl(u->clock_seq_low);
    303	for (i = 0; i < 6; i++)
    304		r->uuid.node[i] = htonl(u->node[i]);
    305
    306	trace_afs_make_vl_call(call);
    307	afs_make_call(&vc->ac, call, GFP_KERNEL);
    308	return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
    309}
    310
    311/*
    312 * Deliver reply data to an VL.GetCapabilities operation.
    313 */
    314static int afs_deliver_vl_get_capabilities(struct afs_call *call)
    315{
    316	u32 count;
    317	int ret;
    318
    319	_enter("{%u,%zu/%u}",
    320	       call->unmarshall, iov_iter_count(call->iter), call->count);
    321
    322	switch (call->unmarshall) {
    323	case 0:
    324		afs_extract_to_tmp(call);
    325		call->unmarshall++;
    326
    327		fallthrough;	/* and extract the capabilities word count */
    328	case 1:
    329		ret = afs_extract_data(call, true);
    330		if (ret < 0)
    331			return ret;
    332
    333		count = ntohl(call->tmp);
    334		call->count = count;
    335		call->count2 = count;
    336
    337		call->unmarshall++;
    338		afs_extract_discard(call, count * sizeof(__be32));
    339
    340		fallthrough;	/* and extract capabilities words */
    341	case 2:
    342		ret = afs_extract_data(call, false);
    343		if (ret < 0)
    344			return ret;
    345
    346		/* TODO: Examine capabilities */
    347
    348		call->unmarshall++;
    349		break;
    350	}
    351
    352	_leave(" = 0 [done]");
    353	return 0;
    354}
    355
    356static void afs_destroy_vl_get_capabilities(struct afs_call *call)
    357{
    358	afs_put_vlserver(call->net, call->vlserver);
    359	afs_flat_call_destructor(call);
    360}
    361
    362/*
    363 * VL.GetCapabilities operation type
    364 */
    365static const struct afs_call_type afs_RXVLGetCapabilities = {
    366	.name		= "VL.GetCapabilities",
    367	.op		= afs_VL_GetCapabilities,
    368	.deliver	= afs_deliver_vl_get_capabilities,
    369	.done		= afs_vlserver_probe_result,
    370	.destructor	= afs_destroy_vl_get_capabilities,
    371};
    372
    373/*
    374 * Probe a volume server for the capabilities that it supports.  This can
    375 * return up to 196 words.
    376 *
    377 * We use this to probe for service upgrade to determine what the server at the
    378 * other end supports.
    379 */
    380struct afs_call *afs_vl_get_capabilities(struct afs_net *net,
    381					 struct afs_addr_cursor *ac,
    382					 struct key *key,
    383					 struct afs_vlserver *server,
    384					 unsigned int server_index)
    385{
    386	struct afs_call *call;
    387	__be32 *bp;
    388
    389	_enter("");
    390
    391	call = afs_alloc_flat_call(net, &afs_RXVLGetCapabilities, 1 * 4, 16 * 4);
    392	if (!call)
    393		return ERR_PTR(-ENOMEM);
    394
    395	call->key = key;
    396	call->vlserver = afs_get_vlserver(server);
    397	call->server_index = server_index;
    398	call->upgrade = true;
    399	call->async = true;
    400	call->max_lifespan = AFS_PROBE_MAX_LIFESPAN;
    401
    402	/* marshall the parameters */
    403	bp = call->request;
    404	*bp++ = htonl(VLGETCAPABILITIES);
    405
    406	/* Can't take a ref on server */
    407	trace_afs_make_vl_call(call);
    408	afs_make_call(ac, call, GFP_KERNEL);
    409	return call;
    410}
    411
    412/*
    413 * Deliver reply data to a YFSVL.GetEndpoints call.
    414 *
    415 *	GetEndpoints(IN yfsServerAttributes *attr,
    416 *		     OUT opr_uuid *uuid,
    417 *		     OUT afs_int32 *uniquifier,
    418 *		     OUT endpoints *fsEndpoints,
    419 *		     OUT endpoints *volEndpoints)
    420 */
    421static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
    422{
    423	struct afs_addr_list *alist;
    424	__be32 *bp;
    425	u32 uniquifier, size;
    426	int ret;
    427
    428	_enter("{%u,%zu,%u}",
    429	       call->unmarshall, iov_iter_count(call->iter), call->count2);
    430
    431	switch (call->unmarshall) {
    432	case 0:
    433		afs_extract_to_buf(call, sizeof(uuid_t) + 3 * sizeof(__be32));
    434		call->unmarshall = 1;
    435
    436		/* Extract the returned uuid, uniquifier, fsEndpoints count and
    437		 * either the first fsEndpoint type or the volEndpoints
    438		 * count if there are no fsEndpoints. */
    439		fallthrough;
    440	case 1:
    441		ret = afs_extract_data(call, true);
    442		if (ret < 0)
    443			return ret;
    444
    445		bp = call->buffer + sizeof(uuid_t);
    446		uniquifier	= ntohl(*bp++);
    447		call->count	= ntohl(*bp++);
    448		call->count2	= ntohl(*bp); /* Type or next count */
    449
    450		if (call->count > YFS_MAXENDPOINTS)
    451			return afs_protocol_error(call, afs_eproto_yvl_fsendpt_num);
    452
    453		alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT);
    454		if (!alist)
    455			return -ENOMEM;
    456		alist->version = uniquifier;
    457		call->ret_alist = alist;
    458
    459		if (call->count == 0)
    460			goto extract_volendpoints;
    461
    462	next_fsendpoint:
    463		switch (call->count2) {
    464		case YFS_ENDPOINT_IPV4:
    465			size = sizeof(__be32) * (1 + 1 + 1);
    466			break;
    467		case YFS_ENDPOINT_IPV6:
    468			size = sizeof(__be32) * (1 + 4 + 1);
    469			break;
    470		default:
    471			return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
    472		}
    473
    474		size += sizeof(__be32);
    475		afs_extract_to_buf(call, size);
    476		call->unmarshall = 2;
    477
    478		fallthrough;	/* and extract fsEndpoints[] entries */
    479	case 2:
    480		ret = afs_extract_data(call, true);
    481		if (ret < 0)
    482			return ret;
    483
    484		alist = call->ret_alist;
    485		bp = call->buffer;
    486		switch (call->count2) {
    487		case YFS_ENDPOINT_IPV4:
    488			if (ntohl(bp[0]) != sizeof(__be32) * 2)
    489				return afs_protocol_error(
    490					call, afs_eproto_yvl_fsendpt4_len);
    491			afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2]));
    492			bp += 3;
    493			break;
    494		case YFS_ENDPOINT_IPV6:
    495			if (ntohl(bp[0]) != sizeof(__be32) * 5)
    496				return afs_protocol_error(
    497					call, afs_eproto_yvl_fsendpt6_len);
    498			afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5]));
    499			bp += 6;
    500			break;
    501		default:
    502			return afs_protocol_error(call, afs_eproto_yvl_fsendpt_type);
    503		}
    504
    505		/* Got either the type of the next entry or the count of
    506		 * volEndpoints if no more fsEndpoints.
    507		 */
    508		call->count2 = ntohl(*bp++);
    509
    510		call->count--;
    511		if (call->count > 0)
    512			goto next_fsendpoint;
    513
    514	extract_volendpoints:
    515		/* Extract the list of volEndpoints. */
    516		call->count = call->count2;
    517		if (!call->count)
    518			goto end;
    519		if (call->count > YFS_MAXENDPOINTS)
    520			return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
    521
    522		afs_extract_to_buf(call, 1 * sizeof(__be32));
    523		call->unmarshall = 3;
    524
    525		/* Extract the type of volEndpoints[0].  Normally we would
    526		 * extract the type of the next endpoint when we extract the
    527		 * data of the current one, but this is the first...
    528		 */
    529		fallthrough;
    530	case 3:
    531		ret = afs_extract_data(call, true);
    532		if (ret < 0)
    533			return ret;
    534
    535		bp = call->buffer;
    536
    537	next_volendpoint:
    538		call->count2 = ntohl(*bp++);
    539		switch (call->count2) {
    540		case YFS_ENDPOINT_IPV4:
    541			size = sizeof(__be32) * (1 + 1 + 1);
    542			break;
    543		case YFS_ENDPOINT_IPV6:
    544			size = sizeof(__be32) * (1 + 4 + 1);
    545			break;
    546		default:
    547			return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
    548		}
    549
    550		if (call->count > 1)
    551			size += sizeof(__be32); /* Get next type too */
    552		afs_extract_to_buf(call, size);
    553		call->unmarshall = 4;
    554
    555		fallthrough;	/* and extract volEndpoints[] entries */
    556	case 4:
    557		ret = afs_extract_data(call, true);
    558		if (ret < 0)
    559			return ret;
    560
    561		bp = call->buffer;
    562		switch (call->count2) {
    563		case YFS_ENDPOINT_IPV4:
    564			if (ntohl(bp[0]) != sizeof(__be32) * 2)
    565				return afs_protocol_error(
    566					call, afs_eproto_yvl_vlendpt4_len);
    567			bp += 3;
    568			break;
    569		case YFS_ENDPOINT_IPV6:
    570			if (ntohl(bp[0]) != sizeof(__be32) * 5)
    571				return afs_protocol_error(
    572					call, afs_eproto_yvl_vlendpt6_len);
    573			bp += 6;
    574			break;
    575		default:
    576			return afs_protocol_error(call, afs_eproto_yvl_vlendpt_type);
    577		}
    578
    579		/* Got either the type of the next entry or the count of
    580		 * volEndpoints if no more fsEndpoints.
    581		 */
    582		call->count--;
    583		if (call->count > 0)
    584			goto next_volendpoint;
    585
    586	end:
    587		afs_extract_discard(call, 0);
    588		call->unmarshall = 5;
    589
    590		fallthrough;	/* Done */
    591	case 5:
    592		ret = afs_extract_data(call, false);
    593		if (ret < 0)
    594			return ret;
    595		call->unmarshall = 6;
    596		fallthrough;
    597
    598	case 6:
    599		break;
    600	}
    601
    602	_leave(" = 0 [done]");
    603	return 0;
    604}
    605
    606/*
    607 * YFSVL.GetEndpoints operation type.
    608 */
    609static const struct afs_call_type afs_YFSVLGetEndpoints = {
    610	.name		= "YFSVL.GetEndpoints",
    611	.op		= afs_YFSVL_GetEndpoints,
    612	.deliver	= afs_deliver_yfsvl_get_endpoints,
    613	.destructor	= afs_vl_get_addrs_u_destructor,
    614};
    615
    616/*
    617 * Dispatch an operation to get the addresses for a server, where the server is
    618 * nominated by UUID.
    619 */
    620struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
    621					      const uuid_t *uuid)
    622{
    623	struct afs_call *call;
    624	struct afs_net *net = vc->cell->net;
    625	__be32 *bp;
    626
    627	_enter("");
    628
    629	call = afs_alloc_flat_call(net, &afs_YFSVLGetEndpoints,
    630				   sizeof(__be32) * 2 + sizeof(*uuid),
    631				   sizeof(struct in6_addr) + sizeof(__be32) * 3);
    632	if (!call)
    633		return ERR_PTR(-ENOMEM);
    634
    635	call->key = vc->key;
    636	call->ret_alist = NULL;
    637	call->max_lifespan = AFS_VL_MAX_LIFESPAN;
    638
    639	/* Marshall the parameters */
    640	bp = call->request;
    641	*bp++ = htonl(YVLGETENDPOINTS);
    642	*bp++ = htonl(YFS_SERVER_UUID);
    643	memcpy(bp, uuid, sizeof(*uuid)); /* Type opr_uuid */
    644
    645	trace_afs_make_vl_call(call);
    646	afs_make_call(&vc->ac, call, GFP_KERNEL);
    647	return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
    648}
    649
    650/*
    651 * Deliver reply data to a YFSVL.GetCellName operation.
    652 */
    653static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
    654{
    655	char *cell_name;
    656	u32 namesz, paddedsz;
    657	int ret;
    658
    659	_enter("{%u,%zu/%u}",
    660	       call->unmarshall, iov_iter_count(call->iter), call->count);
    661
    662	switch (call->unmarshall) {
    663	case 0:
    664		afs_extract_to_tmp(call);
    665		call->unmarshall++;
    666
    667		fallthrough;	/* and extract the cell name length */
    668	case 1:
    669		ret = afs_extract_data(call, true);
    670		if (ret < 0)
    671			return ret;
    672
    673		namesz = ntohl(call->tmp);
    674		if (namesz > AFS_MAXCELLNAME)
    675			return afs_protocol_error(call, afs_eproto_cellname_len);
    676		paddedsz = (namesz + 3) & ~3;
    677		call->count = namesz;
    678		call->count2 = paddedsz - namesz;
    679
    680		cell_name = kmalloc(namesz + 1, GFP_KERNEL);
    681		if (!cell_name)
    682			return -ENOMEM;
    683		cell_name[namesz] = 0;
    684		call->ret_str = cell_name;
    685
    686		afs_extract_begin(call, cell_name, namesz);
    687		call->unmarshall++;
    688
    689		fallthrough;	/* and extract cell name */
    690	case 2:
    691		ret = afs_extract_data(call, true);
    692		if (ret < 0)
    693			return ret;
    694
    695		afs_extract_discard(call, call->count2);
    696		call->unmarshall++;
    697
    698		fallthrough;	/* and extract padding */
    699	case 3:
    700		ret = afs_extract_data(call, false);
    701		if (ret < 0)
    702			return ret;
    703
    704		call->unmarshall++;
    705		break;
    706	}
    707
    708	_leave(" = 0 [done]");
    709	return 0;
    710}
    711
    712static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call)
    713{
    714	kfree(call->ret_str);
    715	afs_flat_call_destructor(call);
    716}
    717
    718/*
    719 * VL.GetCapabilities operation type
    720 */
    721static const struct afs_call_type afs_YFSVLGetCellName = {
    722	.name		= "YFSVL.GetCellName",
    723	.op		= afs_YFSVL_GetCellName,
    724	.deliver	= afs_deliver_yfsvl_get_cell_name,
    725	.destructor	= afs_destroy_yfsvl_get_cell_name,
    726};
    727
    728/*
    729 * Probe a volume server for the capabilities that it supports.  This can
    730 * return up to 196 words.
    731 *
    732 * We use this to probe for service upgrade to determine what the server at the
    733 * other end supports.
    734 */
    735char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
    736{
    737	struct afs_call *call;
    738	struct afs_net *net = vc->cell->net;
    739	__be32 *bp;
    740
    741	_enter("");
    742
    743	call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0);
    744	if (!call)
    745		return ERR_PTR(-ENOMEM);
    746
    747	call->key = vc->key;
    748	call->ret_str = NULL;
    749	call->max_lifespan = AFS_VL_MAX_LIFESPAN;
    750
    751	/* marshall the parameters */
    752	bp = call->request;
    753	*bp++ = htonl(YVLGETCELLNAME);
    754
    755	/* Can't take a ref on server */
    756	trace_afs_make_vl_call(call);
    757	afs_make_call(&vc->ac, call, GFP_KERNEL);
    758	return (char *)afs_wait_for_call_to_complete(call, &vc->ac);
    759}