Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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