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 server record management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2002, 2007 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/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "afs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include "protocol_yfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) static unsigned afs_server_gc_delay = 10;	/* Server record timeout in seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) static atomic_t afs_server_debug_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static struct afs_server *afs_maybe_use_server(struct afs_server *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 					       enum afs_server_trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static void __afs_put_server(struct afs_net *, struct afs_server *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * Find a server by one of its addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) struct afs_server *afs_find_server(struct afs_net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 				   const struct sockaddr_rxrpc *srx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	const struct afs_addr_list *alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct afs_server *server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	int seq = 0, diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		if (server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 			afs_unuse_server_notime(net, server, afs_server_trace_put_find_rsq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		read_seqbegin_or_lock(&net->fs_addr_lock, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		if (srx->transport.family == AF_INET6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 			const struct sockaddr_in6 *a = &srx->transport.sin6, *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			hlist_for_each_entry_rcu(server, &net->fs_addresses6, addr6_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 				alist = rcu_dereference(server->addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 				for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 					b = &alist->addrs[i].transport.sin6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 					diff = ((u16 __force)a->sin6_port -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 						(u16 __force)b->sin6_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 					if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 						diff = memcmp(&a->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 							      &b->sin6_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 							      sizeof(struct in6_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 					if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 						goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			const struct sockaddr_in *a = &srx->transport.sin, *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			hlist_for_each_entry_rcu(server, &net->fs_addresses4, addr4_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				alist = rcu_dereference(server->addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 				for (i = 0; i < alist->nr_ipv4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 					b = &alist->addrs[i].transport.sin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 					diff = ((u16 __force)a->sin_port -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 						(u16 __force)b->sin_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 					if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 						diff = ((u32 __force)a->sin_addr.s_addr -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 							(u32 __force)b->sin_addr.s_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 					if (diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 						goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		server = afs_maybe_use_server(server, afs_server_trace_get_by_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	} while (need_seqretry(&net->fs_addr_lock, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	done_seqretry(&net->fs_addr_lock, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * Look up a server by its UUID and mark it active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) struct afs_server *afs_find_server_by_uuid(struct afs_net *net, const uuid_t *uuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct afs_server *server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct rb_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	int diff, seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	_enter("%pU", uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		/* Unfortunately, rbtree walking doesn't give reliable results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		 * under just the RCU read lock, so we have to check for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		 * changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		if (server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			afs_unuse_server(net, server, afs_server_trace_put_uuid_rsq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		read_seqbegin_or_lock(&net->fs_lock, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		p = net->fs_servers.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		while (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 			server = rb_entry(p, struct afs_server, uuid_rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 			diff = memcmp(uuid, &server->uuid, sizeof(*uuid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			if (diff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 				p = p->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			} else if (diff > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				p = p->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				afs_use_server(server, afs_server_trace_get_by_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			server = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	} while (need_seqretry(&net->fs_lock, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	done_seqretry(&net->fs_lock, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	_leave(" = %p", server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * Install a server record in the namespace tree.  If there's a clash, we stick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * it into a list anchored on whichever afs_server struct is actually in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct afs_server *afs_install_server(struct afs_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 					     struct afs_server *candidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	const struct afs_addr_list *alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct afs_server *server, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct afs_net *net = cell->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct rb_node **pp, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	int diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	_enter("%p", candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	write_seqlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	/* Firstly install the server in the UUID lookup tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	pp = &net->fs_servers.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	while (*pp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		p = *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		_debug("- consider %p", p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		server = rb_entry(p, struct afs_server, uuid_rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		diff = memcmp(&candidate->uuid, &server->uuid, sizeof(uuid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		if (diff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			pp = &(*pp)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		} else if (diff > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			pp = &(*pp)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			if (server->cell == cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				goto exists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			/* We have the same UUID representing servers in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			 * different cells.  Append the new server to the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 				next = rcu_dereference_protected(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 					server->uuid_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 					lockdep_is_held(&net->fs_lock.lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 				if (!next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				server = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			rcu_assign_pointer(server->uuid_next, candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			candidate->uuid_prev = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			server = candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			goto added_dup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	server = candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	rb_link_node(&server->uuid_rb, p, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	rb_insert_color(&server->uuid_rb, &net->fs_servers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	hlist_add_head_rcu(&server->proc_link, &net->fs_proc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) added_dup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	write_seqlock(&net->fs_addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	alist = rcu_dereference_protected(server->addresses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 					  lockdep_is_held(&net->fs_addr_lock.lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/* Secondly, if the server has any IPv4 and/or IPv6 addresses, install
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	 * it in the IPv4 and/or IPv6 reverse-map lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	 * TODO: For speed we want to use something other than a flat list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	 * here; even sorting the list in terms of lowest address would help a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	 * bit, but anything we might want to do gets messy and memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	 * intensive.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	if (alist->nr_ipv4 > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		hlist_add_head_rcu(&server->addr4_link, &net->fs_addresses4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (alist->nr_addrs > alist->nr_ipv4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		hlist_add_head_rcu(&server->addr6_link, &net->fs_addresses6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	write_sequnlock(&net->fs_addr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) exists:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	afs_get_server(server, afs_server_trace_get_install);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	write_sequnlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * Allocate a new server record and mark it active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static struct afs_server *afs_alloc_server(struct afs_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 					   const uuid_t *uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 					   struct afs_addr_list *alist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct afs_server *server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	struct afs_net *net = cell->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	server = kzalloc(sizeof(struct afs_server), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (!server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		goto enomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	atomic_set(&server->ref, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	atomic_set(&server->active, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	server->debug_id = atomic_inc_return(&afs_server_debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	RCU_INIT_POINTER(server->addresses, alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	server->addr_version = alist->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	server->uuid = *uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	rwlock_init(&server->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	init_waitqueue_head(&server->probe_wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	INIT_LIST_HEAD(&server->probe_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	spin_lock_init(&server->probe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	server->cell = cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	server->rtt = UINT_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	trace_afs_server(server, 1, 1, afs_server_trace_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	_leave(" = %p", server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) enomem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	_leave(" = NULL [nomem]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return NULL;
^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)  * Look up an address record for a server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static struct afs_addr_list *afs_vl_lookup_addrs(struct afs_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 						 struct key *key, const uuid_t *uuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	struct afs_vl_cursor vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	struct afs_addr_list *alist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	ret = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (afs_begin_vlserver_operation(&vc, cell, key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		while (afs_select_vlserver(&vc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			if (test_bit(AFS_VLSERVER_FL_IS_YFS, &vc.server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 				alist = afs_yfsvl_get_endpoints(&vc, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				alist = afs_vl_get_addrs_u(&vc, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		ret = afs_end_vlserver_operation(&vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return ret < 0 ? ERR_PTR(ret) : alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  * Get or create a fileserver record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct afs_server *afs_lookup_server(struct afs_cell *cell, struct key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 				     const uuid_t *uuid, u32 addr_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	struct afs_addr_list *alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	struct afs_server *server, *candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	_enter("%p,%pU", cell->net, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	server = afs_find_server_by_uuid(cell->net, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	if (server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		if (server->addr_version != addr_version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			set_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	alist = afs_vl_lookup_addrs(cell, key, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (IS_ERR(alist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		return ERR_CAST(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	candidate = afs_alloc_server(cell, uuid, alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (!candidate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		afs_put_addrlist(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	server = afs_install_server(cell, candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (server != candidate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		afs_put_addrlist(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		kfree(candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		/* Immediately dispatch an asynchronous probe to each interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		 * on the fileserver.  This will make sure the repeat-probing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		 * service is started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		afs_fs_probe_fileserver(cell->net, server, key, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  * Set the server timer to fire after a given delay, assuming it's not already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)  * set for an earlier time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static void afs_set_server_timer(struct afs_net *net, time64_t delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	if (net->live) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		if (timer_reduce(&net->fs_timer, jiffies + delay * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 			afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  * Server management timer.  We have an increment on fs_outstanding that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  * need to pass along to the work item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) void afs_servers_timer(struct timer_list *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	struct afs_net *net = container_of(timer, struct afs_net, fs_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (!queue_work(afs_wq, &net->fs_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)  * Get a reference on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct afs_server *afs_get_server(struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 				  enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	unsigned int u = atomic_inc_return(&server->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	trace_afs_server(server, u, atomic_read(&server->active), reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)  * Try to get a reference on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static struct afs_server *afs_maybe_use_server(struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 					       enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	unsigned int r = atomic_fetch_add_unless(&server->ref, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	unsigned int a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (r == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	a = atomic_inc_return(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	trace_afs_server(server, r, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)  * Get an active count on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct afs_server *afs_use_server(struct afs_server *server, enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	unsigned int r = atomic_inc_return(&server->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	unsigned int a = atomic_inc_return(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	trace_afs_server(server, r, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * Release a reference on a server record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) void afs_put_server(struct afs_net *net, struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		    enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	unsigned int usage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	if (!server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	usage = atomic_dec_return(&server->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	trace_afs_server(server, usage, atomic_read(&server->active), reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	if (unlikely(usage == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		__afs_put_server(net, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  * Drop an active count on a server object without updating the last-unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  * time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) void afs_unuse_server_notime(struct afs_net *net, struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			     enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	if (server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		unsigned int active = atomic_dec_return(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		if (active == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			afs_set_server_timer(net, afs_server_gc_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		afs_put_server(net, server, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  * Drop an active count on a server object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) void afs_unuse_server(struct afs_net *net, struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		      enum afs_server_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	if (server) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		server->unuse_time = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		afs_unuse_server_notime(net, server, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static void afs_server_rcu(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	struct afs_server *server = container_of(rcu, struct afs_server, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	trace_afs_server(server, atomic_read(&server->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			 atomic_read(&server->active), afs_server_trace_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	afs_put_addrlist(rcu_access_pointer(server->addresses));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	kfree(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static void __afs_put_server(struct afs_net *net, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	call_rcu(&server->rcu, afs_server_rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static void afs_give_up_callbacks(struct afs_net *net, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	struct afs_addr_list *alist = rcu_access_pointer(server->addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	struct afs_addr_cursor ac = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		.alist	= alist,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		.index	= alist->preferred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		.error	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	afs_fs_give_up_all_callbacks(net, server, &ac, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)  * destroy a dead server
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static void afs_destroy_server(struct afs_net *net, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (test_bit(AFS_SERVER_FL_MAY_HAVE_CB, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		afs_give_up_callbacks(net, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	afs_put_server(net, server, afs_server_trace_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^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)  * Garbage collect any expired servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static void afs_gc_servers(struct afs_net *net, struct afs_server *gc_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	struct afs_server *server, *next, *prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	int active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	while ((server = gc_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		gc_list = server->gc_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		write_seqlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		active = atomic_read(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		if (active == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 			trace_afs_server(server, atomic_read(&server->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 					 active, afs_server_trace_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			next = rcu_dereference_protected(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 				server->uuid_next, lockdep_is_held(&net->fs_lock.lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			prev = server->uuid_prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 			if (!prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 				/* The one at the front is in the tree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				if (!next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 					rb_erase(&server->uuid_rb, &net->fs_servers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 					rb_replace_node_rcu(&server->uuid_rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 							    &next->uuid_rb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 							    &net->fs_servers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 					next->uuid_prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 				/* This server is not at the front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 				rcu_assign_pointer(prev->uuid_next, next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 				if (next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 					next->uuid_prev = prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			list_del(&server->probe_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			hlist_del_rcu(&server->proc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			if (!hlist_unhashed(&server->addr4_link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 				hlist_del_rcu(&server->addr4_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 			if (!hlist_unhashed(&server->addr6_link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 				hlist_del_rcu(&server->addr6_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		write_sequnlock(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		if (active == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			afs_destroy_server(net, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)  * Manage the records of servers known to be within a network namespace.  This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)  * includes garbage collecting unused servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)  * Note also that we were given an increment on net->servers_outstanding by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)  * whoever queued us that we need to deal with before returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) void afs_manage_servers(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	struct afs_net *net = container_of(work, struct afs_net, fs_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	struct afs_server *gc_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	struct rb_node *cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	bool purging = !net->live;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	/* Trawl the server list looking for servers that have expired from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	 * lack of use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	read_seqlock_excl(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	for (cursor = rb_first(&net->fs_servers); cursor; cursor = rb_next(cursor)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		struct afs_server *server =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 			rb_entry(cursor, struct afs_server, uuid_rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		int active = atomic_read(&server->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		_debug("manage %pU %u", &server->uuid, active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		if (purging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 			trace_afs_server(server, atomic_read(&server->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 					 active, afs_server_trace_purging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 			if (active != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 				pr_notice("Can't purge s=%08x\n", server->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		if (active == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 			time64_t expire_at = server->unuse_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			if (!test_bit(AFS_SERVER_FL_VL_FAIL, &server->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			    !test_bit(AFS_SERVER_FL_NOT_FOUND, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 				expire_at += afs_server_gc_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			if (purging || expire_at <= now) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 				server->gc_next = gc_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 				gc_list = server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			} else if (expire_at < next_manage) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 				next_manage = expire_at;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	read_sequnlock_excl(&net->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	/* Update the timer on the way out.  We have to pass an increment on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	 * servers_outstanding in the namespace that we are in to the timer or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	 * the work scheduler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	if (!purging && next_manage < TIME64_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		now = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		if (next_manage - now <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			if (queue_work(afs_wq, &net->fs_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 				afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 			afs_set_server_timer(net, next_manage - now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	afs_gc_servers(net, gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	_leave(" [%d]", atomic_read(&net->servers_outstanding));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static void afs_queue_server_manager(struct afs_net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	afs_inc_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	if (!queue_work(afs_wq, &net->fs_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		afs_dec_servers_outstanding(net);
^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)  * Purge list of servers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) void afs_purge_servers(struct afs_net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	if (del_timer_sync(&net->fs_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		afs_dec_servers_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	afs_queue_server_manager(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	_debug("wait");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	atomic_dec(&net->servers_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	wait_var_event(&net->servers_outstanding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		       !atomic_read(&net->servers_outstanding));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	_leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)  * Get an update for a server's address list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static noinline bool afs_update_server_record(struct afs_operation *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 					      struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	struct afs_addr_list *alist, *discard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	trace_afs_server(server, atomic_read(&server->ref), atomic_read(&server->active),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 			 afs_server_trace_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	alist = afs_vl_lookup_addrs(op->volume->cell, op->key, &server->uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	if (IS_ERR(alist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		if ((PTR_ERR(alist) == -ERESTARTSYS ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		     PTR_ERR(alist) == -EINTR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		    (op->flags & AFS_OPERATION_UNINTR) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 		    server->addresses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 			_leave(" = t [intr]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		op->error = PTR_ERR(alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		_leave(" = f [%d]", op->error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	discard = alist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	if (server->addr_version != alist->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		write_lock(&server->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		discard = rcu_dereference_protected(server->addresses,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 						    lockdep_is_held(&server->fs_lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		rcu_assign_pointer(server->addresses, alist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		server->addr_version = alist->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		write_unlock(&server->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	afs_put_addrlist(discard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	_leave(" = t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)  * See if a server's address list needs updating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) bool afs_check_server_record(struct afs_operation *op, struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	bool success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	int ret, retries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	ASSERT(server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	if (test_bit(AFS_SERVER_FL_UPDATING, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		goto wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	if (test_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		goto update;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	_leave(" = t [good]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) update:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	if (!test_and_set_bit_lock(AFS_SERVER_FL_UPDATING, &server->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		clear_bit(AFS_SERVER_FL_NEEDS_UPDATE, &server->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		success = afs_update_server_record(op, server);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		clear_bit_unlock(AFS_SERVER_FL_UPDATING, &server->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		wake_up_bit(&server->flags, AFS_SERVER_FL_UPDATING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		_leave(" = %d", success);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		return success;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) wait:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	ret = wait_on_bit(&server->flags, AFS_SERVER_FL_UPDATING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 			  (op->flags & AFS_OPERATION_UNINTR) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 			  TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	if (ret == -ERESTARTSYS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		op->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		_leave(" = f [intr]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	retries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	if (retries == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		_leave(" = f [stale]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		ret = -ESTALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }