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
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   2) /* AFS fileserver list management.
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   3)  *
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   4)  * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   5)  * Written by David Howells (dhowells@redhat.com)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   6)  */
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   7) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   8) #include <linux/kernel.h>
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000   9) #include <linux/slab.h>
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  10) #include "internal.h"
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  11) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  12) void afs_put_serverlist(struct afs_net *net, struct afs_server_list *slist)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  13) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  14) 	int i;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  15) 
0fafdc9f888b4 (David Howells       2017-11-13 16:59:50 +0000  16) 	if (slist && refcount_dec_and_test(&slist->usage)) {
20325960f8750 (David Howells       2020-04-30 01:03:49 +0100  17) 		for (i = 0; i < slist->nr_servers; i++)
977e5f8ed0ab2 (David Howells       2020-04-17 17:31:26 +0100  18) 			afs_unuse_server(net, slist->servers[i].server,
977e5f8ed0ab2 (David Howells       2020-04-17 17:31:26 +0100  19) 					 afs_server_trace_put_slist);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  20) 		kfree(slist);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  21) 	}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  22) }
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  23) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  24) /*
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  25)  * Build a server list from a VLDB record.
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  26)  */
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  27) struct afs_server_list *afs_alloc_server_list(struct afs_cell *cell,
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  28) 					      struct key *key,
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  29) 					      struct afs_vldb_entry *vldb,
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  30) 					      u8 type_mask)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  31) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  32) 	struct afs_server_list *slist;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  33) 	struct afs_server *server;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  34) 	int ret = -ENOMEM, nr_servers = 0, i, j;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  35) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  36) 	for (i = 0; i < vldb->nr_servers; i++)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  37) 		if (vldb->fs_mask[i] & type_mask)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  38) 			nr_servers++;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  39) 
c2b8bd49d35a7 (Gustavo A. R. Silva 2019-01-09 17:23:54 +0000  40) 	slist = kzalloc(struct_size(slist, servers, nr_servers), GFP_KERNEL);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  41) 	if (!slist)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  42) 		goto error;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  43) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  44) 	refcount_set(&slist->usage, 1);
d4a96bec7a736 (David Howells       2018-05-10 08:43:04 +0100  45) 	rwlock_init(&slist->lock);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  46) 
194d28cf197ca (David Howells       2020-04-27 13:42:53 +0100  47) 	for (i = 0; i < AFS_MAXTYPES; i++)
194d28cf197ca (David Howells       2020-04-27 13:42:53 +0100  48) 		slist->vids[i] = vldb->vid[i];
194d28cf197ca (David Howells       2020-04-27 13:42:53 +0100  49) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  50) 	/* Make sure a records exists for each server in the list. */
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  51) 	for (i = 0; i < vldb->nr_servers; i++) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  52) 		if (!(vldb->fs_mask[i] & type_mask))
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  53) 			continue;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  54) 
8100680592345 (David Howells       2020-04-16 17:05:28 +0100  55) 		server = afs_lookup_server(cell, key, &vldb->fs_server[i],
8100680592345 (David Howells       2020-04-16 17:05:28 +0100  56) 					   vldb->addr_version[i]);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  57) 		if (IS_ERR(server)) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  58) 			ret = PTR_ERR(server);
45df8462730d2 (David Howells       2018-02-06 14:12:32 +0000  59) 			if (ret == -ENOENT ||
45df8462730d2 (David Howells       2018-02-06 14:12:32 +0000  60) 			    ret == -ENOMEDIUM)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  61) 				continue;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  62) 			goto error_2;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  63) 		}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  64) 
d4a96bec7a736 (David Howells       2018-05-10 08:43:04 +0100  65) 		/* Insertion-sort by UUID */
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  66) 		for (j = 0; j < slist->nr_servers; j++)
d4a96bec7a736 (David Howells       2018-05-10 08:43:04 +0100  67) 			if (memcmp(&slist->servers[j].server->uuid,
d4a96bec7a736 (David Howells       2018-05-10 08:43:04 +0100  68) 				   &server->uuid,
d4a96bec7a736 (David Howells       2018-05-10 08:43:04 +0100  69) 				   sizeof(server->uuid)) >= 0)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  70) 				break;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  71) 		if (j < slist->nr_servers) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  72) 			if (slist->servers[j].server == server) {
452181936931f (David Howells       2019-06-20 18:12:17 +0100  73) 				afs_put_server(cell->net, server,
452181936931f (David Howells       2019-06-20 18:12:17 +0100  74) 					       afs_server_trace_put_slist_isort);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  75) 				continue;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  76) 			}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  77) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  78) 			memmove(slist->servers + j + 1,
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  79) 				slist->servers + j,
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  80) 				(slist->nr_servers - j) * sizeof(struct afs_server_entry));
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  81) 		}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  82) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  83) 		slist->servers[j].server = server;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  84) 		slist->nr_servers++;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  85) 	}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  86) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  87) 	if (slist->nr_servers == 0) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  88) 		ret = -EDESTADDRREQ;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  89) 		goto error_2;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  90) 	}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  91) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  92) 	return slist;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  93) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  94) error_2:
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  95) 	afs_put_serverlist(cell->net, slist);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  96) error:
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  97) 	return ERR_PTR(ret);
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  98) }
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000  99) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 100) /*
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 101)  * Copy the annotations from an old server list to its potential replacement.
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 102)  */
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 103) bool afs_annotate_server_list(struct afs_server_list *new,
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 104) 			      struct afs_server_list *old)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 105) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 106) 	struct afs_server *cur;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 107) 	int i, j;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 108) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 109) 	if (old->nr_servers != new->nr_servers)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 110) 		goto changed;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 111) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 112) 	for (i = 0; i < old->nr_servers; i++)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 113) 		if (old->servers[i].server != new->servers[i].server)
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 114) 			goto changed;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 115) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 116) 	return false;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 117) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 118) changed:
3bf0fb6f33dd5 (David Howells       2018-10-20 00:57:59 +0100 119) 	/* Maintain the same preferred server as before if possible. */
3bf0fb6f33dd5 (David Howells       2018-10-20 00:57:59 +0100 120) 	cur = old->servers[old->preferred].server;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 121) 	for (j = 0; j < new->nr_servers; j++) {
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 122) 		if (new->servers[j].server == cur) {
3bf0fb6f33dd5 (David Howells       2018-10-20 00:57:59 +0100 123) 			new->preferred = j;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 124) 			break;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 125) 		}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 126) 	}
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 127) 
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 128) 	return true;
d2ddc776a4581 (David Howells       2017-11-02 15:27:50 +0000 129) }