VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

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