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 cell and 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, 2017 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/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/dns_resolver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <keys/rxrpc-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static unsigned __read_mostly afs_cell_gc_delay = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static unsigned __read_mostly afs_cell_min_ttl = 10 * 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) static unsigned __read_mostly afs_cell_max_ttl = 24 * 60 * 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static atomic_t cell_debug_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static void afs_queue_cell_manager(struct afs_net *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static void afs_manage_cell_work(struct work_struct *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static void afs_dec_cells_outstanding(struct afs_net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	if (atomic_dec_and_test(&net->cells_outstanding))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		wake_up_var(&net->cells_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * Set the cell timer to fire after a given delay, assuming it's not already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * set for an earlier time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static void afs_set_cell_timer(struct afs_net *net, time64_t delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	if (net->live) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		atomic_inc(&net->cells_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		if (timer_reduce(&net->cells_timer, jiffies + delay * HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 			afs_dec_cells_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		afs_queue_cell_manager(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * Look up and get an activation reference on a cell record.  The caller must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * hold net->cells_lock at least read-locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static struct afs_cell *afs_find_cell_locked(struct afs_net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 					     const char *name, unsigned int namesz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 					     enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct afs_cell *cell = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	struct rb_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	_enter("%*.*s", namesz, namesz, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (name && namesz == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (namesz > AFS_MAXCELLNAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		cell = net->ws_cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		if (!cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			return ERR_PTR(-EDESTADDRREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		goto found;
^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) 	p = net->cells.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	while (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		cell = rb_entry(p, struct afs_cell, net_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		n = strncasecmp(cell->name, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				min_t(size_t, cell->name_len, namesz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		if (n == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			n = cell->name_len - namesz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			p = p->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		else if (n > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			p = p->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	return ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	return afs_use_cell(cell, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * Look up and get an activation reference on a cell record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) struct afs_cell *afs_find_cell(struct afs_net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			       const char *name, unsigned int namesz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			       enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct afs_cell *cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	down_read(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	cell = afs_find_cell_locked(net, name, namesz, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	up_read(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	return cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * Set up a cell record and fill in its name, VL server address list and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * allocate an anonymous key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static struct afs_cell *afs_alloc_cell(struct afs_net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 				       const char *name, unsigned int namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				       const char *addresses)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct afs_vlserver_list *vllist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	struct afs_cell *cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	ASSERT(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (namelen == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (namelen > AFS_MAXCELLNAME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		_leave(" = -ENAMETOOLONG");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		return ERR_PTR(-ENAMETOOLONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	/* Prohibit cell names that contain unprintable chars, '/' and '@' or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 * that begin with a dot.  This also precludes "@cell".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (name[0] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	for (i = 0; i < namelen; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		char ch = name[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		if (!isprint(ch) || ch == '/' || ch == '@')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	_enter("%*.*s,%s", namelen, namelen, name, addresses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	if (!cell) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		_leave(" = -ENOMEM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	cell->name = kmalloc(namelen + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (!cell->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		kfree(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	cell->net = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	cell->name_len = namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	for (i = 0; i < namelen; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		cell->name[i] = tolower(name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	cell->name[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	atomic_set(&cell->ref, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	atomic_set(&cell->active, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	INIT_WORK(&cell->manager, afs_manage_cell_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	cell->volumes = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	INIT_HLIST_HEAD(&cell->proc_volumes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	seqlock_init(&cell->volume_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	cell->fs_servers = RB_ROOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	seqlock_init(&cell->fs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	rwlock_init(&cell->vl_servers_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	/* Provide a VL server list, filling it in if we were given a list of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	 * addresses to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (addresses) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		vllist = afs_parse_text_addrs(net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 					      addresses, strlen(addresses), ':',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 					      VL_SERVICE, AFS_VL_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		if (IS_ERR(vllist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			ret = PTR_ERR(vllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			goto parse_failed;
^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) 		vllist->source = DNS_RECORD_FROM_CONFIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		vllist->status = DNS_LOOKUP_NOT_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		cell->dns_expiry = TIME64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		vllist = afs_alloc_vlserver_list(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		if (!vllist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		vllist->source = DNS_RECORD_UNAVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		vllist->status = DNS_LOOKUP_NOT_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		cell->dns_expiry = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	rcu_assign_pointer(cell->vl_servers, vllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	cell->dns_source = vllist->source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	cell->dns_status = vllist->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	smp_store_release(&cell->dns_lookup_count, 1); /* vs source/status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	atomic_inc(&net->cells_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	cell->debug_id = atomic_inc_return(&cell_debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	trace_afs_cell(cell->debug_id, 1, 0, afs_cell_trace_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	_leave(" = %p", cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) parse_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (ret == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		printk(KERN_ERR "kAFS: bad VL server IP address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	kfree(cell->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	kfree(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	_leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * afs_lookup_cell - Look up or create a cell record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * @net:	The network namespace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  * @name:	The name of the cell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)  * @namesz:	The strlen of the cell name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)  * @vllist:	A colon/comma separated list of numeric IP addresses or NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)  * @excl:	T if an error should be given if the cell name already exists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)  * Look up a cell record by name and query the DNS for VL server addresses if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * needed.  Note that that actual DNS query is punted off to the manager thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * so that this function can return immediately if interrupted whilst allowing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * cell records to be shared even if not yet fully constructed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct afs_cell *afs_lookup_cell(struct afs_net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 				 const char *name, unsigned int namesz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 				 const char *vllist, bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	struct afs_cell *cell, *candidate, *cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	struct rb_node *parent, **pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	enum afs_cell_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	int ret, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	_enter("%s,%s", name, vllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (!excl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		cell = afs_find_cell(net, name, namesz, afs_cell_trace_use_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (!IS_ERR(cell))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			goto wait_for_cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	/* Assume we're probably going to create a cell and preallocate and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	 * mostly set up a candidate record.  We can then use this to stash the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	 * name, the net namespace and VL server addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	 * We also want to do this before we hold any locks as it may involve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	 * upcalling to userspace to make DNS queries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	candidate = afs_alloc_cell(net, name, namesz, vllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	if (IS_ERR(candidate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		_leave(" = %ld", PTR_ERR(candidate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		return candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	/* Find the insertion point and check to see if someone else added a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	 * cell whilst we were allocating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	down_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	pp = &net->cells.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	while (*pp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		parent = *pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		cursor = rb_entry(parent, struct afs_cell, net_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		n = strncasecmp(cursor->name, name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				min_t(size_t, cursor->name_len, namesz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		if (n == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			n = cursor->name_len - namesz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		if (n < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			pp = &(*pp)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		else if (n > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			pp = &(*pp)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			goto cell_already_exists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	cell = candidate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	candidate = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	atomic_set(&cell->active, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	trace_afs_cell(cell->debug_id, atomic_read(&cell->ref), 2, afs_cell_trace_insert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	rb_link_node_rcu(&cell->net_node, parent, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	rb_insert_color(&cell->net_node, &net->cells);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	up_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	afs_queue_cell(cell, afs_cell_trace_get_queue_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) wait_for_cell:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	trace_afs_cell(cell->debug_id, atomic_read(&cell->ref), atomic_read(&cell->active),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		       afs_cell_trace_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	_debug("wait_for_cell");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	wait_var_event(&cell->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		       ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			       state = smp_load_acquire(&cell->state); /* vs error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			       state == AFS_CELL_ACTIVE || state == AFS_CELL_REMOVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		       }));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	/* Check the state obtained from the wait check. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	if (state == AFS_CELL_REMOVED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		ret = cell->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	_leave(" = %p [cell]", cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	return cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) cell_already_exists:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	_debug("cell exists");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	cell = cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (excl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		afs_use_cell(cursor, afs_cell_trace_use_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	up_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (candidate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		afs_put_cell(candidate, afs_cell_trace_put_candidate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		goto wait_for_cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	goto error_noput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	afs_unuse_cell(net, cell, afs_cell_trace_unuse_lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) error_noput:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	_leave(" = %d [error]", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	return ERR_PTR(ret);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  * set the root cell information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  * - can be called with a module parameter string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  * - can be called from a write to /proc/fs/afs/rootcell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) int afs_cell_init(struct afs_net *net, const char *rootcell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	struct afs_cell *old_root, *new_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	const char *cp, *vllist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	if (!rootcell) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		/* module is loaded with no parameters, or built statically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		 * - in the future we might initialize cell DB here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		_leave(" = 0 [no root]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	cp = strchr(rootcell, ':');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (!cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		_debug("kAFS: no VL server IP addresses specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		vllist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		len = strlen(rootcell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		vllist = cp + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		len = cp - rootcell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	/* allocate a cell record for the root cell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	new_root = afs_lookup_cell(net, rootcell, len, vllist, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	if (IS_ERR(new_root)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		_leave(" = %ld", PTR_ERR(new_root));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		return PTR_ERR(new_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (!test_and_set_bit(AFS_CELL_FL_NO_GC, &new_root->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		afs_use_cell(new_root, afs_cell_trace_use_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	/* install the new cell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	down_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	afs_see_cell(new_root, afs_cell_trace_see_ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	old_root = net->ws_cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	net->ws_cell = new_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	up_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	afs_unuse_cell(net, old_root, afs_cell_trace_unuse_ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	_leave(" = 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return 0;
^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)  * Update a cell's VL server address list from the DNS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int afs_update_cell(struct afs_cell *cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	struct afs_vlserver_list *vllist, *old = NULL, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	unsigned int min_ttl = READ_ONCE(afs_cell_min_ttl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	unsigned int max_ttl = READ_ONCE(afs_cell_max_ttl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	time64_t now, expiry = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	_enter("%s", cell->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	vllist = afs_dns_query(cell, &expiry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	if (IS_ERR(vllist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		ret = PTR_ERR(vllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		_debug("%s: fail %d", cell->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		if (ret == -ENOMEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			goto out_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		vllist = afs_alloc_vlserver_list(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		if (!vllist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			goto out_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		switch (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		case -ENODATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		case -EDESTADDRREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			vllist->status = DNS_LOOKUP_GOT_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		case -ECONNREFUSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			vllist->status = DNS_LOOKUP_GOT_TEMP_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			vllist->status = DNS_LOOKUP_GOT_LOCAL_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	_debug("%s: got list %d %d", cell->name, vllist->source, vllist->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	cell->dns_status = vllist->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	now = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	if (min_ttl > max_ttl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		max_ttl = min_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	if (expiry < now + min_ttl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		expiry = now + min_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	else if (expiry > now + max_ttl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		expiry = now + max_ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	_debug("%s: status %d", cell->name, vllist->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (vllist->source == DNS_RECORD_UNAVAILABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		switch (vllist->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		case DNS_LOOKUP_GOT_NOT_FOUND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 			/* The DNS said that the cell does not exist or there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 			 * weren't any addresses to be had.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 			cell->dns_expiry = expiry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		case DNS_LOOKUP_BAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		case DNS_LOOKUP_GOT_LOCAL_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		case DNS_LOOKUP_GOT_TEMP_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		case DNS_LOOKUP_GOT_NS_FAILURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			cell->dns_expiry = now + 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		cell->dns_expiry = expiry;
^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) 	/* Replace the VL server list if the new record has servers or the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	 * record doesn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	write_lock(&cell->vl_servers_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	p = rcu_dereference_protected(cell->vl_servers, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	if (vllist->nr_servers > 0 || p->nr_servers == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		rcu_assign_pointer(cell->vl_servers, vllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		cell->dns_source = vllist->source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		old = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	write_unlock(&cell->vl_servers_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	afs_put_vlserverlist(cell->net, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) out_wake:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	smp_store_release(&cell->dns_lookup_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			  cell->dns_lookup_count + 1); /* vs source/status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	wake_up_var(&cell->dns_lookup_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	_leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)  * Destroy a cell record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static void afs_cell_destroy(struct rcu_head *rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	struct afs_net *net = cell->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	int u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	_enter("%p{%s}", cell, cell->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	u = atomic_read(&cell->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	ASSERTCMP(u, ==, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	trace_afs_cell(cell->debug_id, u, atomic_read(&cell->active), afs_cell_trace_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	afs_unuse_cell(net, cell->alias_of, afs_cell_trace_unuse_alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	key_put(cell->anonymous_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	kfree(cell->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	kfree(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	afs_dec_cells_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	_leave(" [destroyed]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^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)  * Queue the cell manager.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static void afs_queue_cell_manager(struct afs_net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	int outstanding = atomic_inc_return(&net->cells_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	_enter("%d", outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (!queue_work(afs_wq, &net->cells_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		afs_dec_cells_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^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)  * Cell management timer.  We have an increment on cells_outstanding that we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)  * need to pass along to the work item.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) void afs_cells_timer(struct timer_list *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	struct afs_net *net = container_of(timer, struct afs_net, cells_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	if (!queue_work(afs_wq, &net->cells_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		afs_dec_cells_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)  * Get a reference on a cell record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct afs_cell *afs_get_cell(struct afs_cell *cell, enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	int u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	if (atomic_read(&cell->ref) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	u = atomic_inc_return(&cell->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	trace_afs_cell(cell->debug_id, u, atomic_read(&cell->active), reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	return cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)  * Drop a reference on a cell record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (cell) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		unsigned int debug_id = cell->debug_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		unsigned int u, a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		a = atomic_read(&cell->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		u = atomic_dec_return(&cell->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		trace_afs_cell(debug_id, u, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		if (u == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 			a = atomic_read(&cell->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 			WARN(a != 0, "Cell active count %u > 0\n", a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 			call_rcu(&cell->rcu, afs_cell_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)  * Note a cell becoming more active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct afs_cell *afs_use_cell(struct afs_cell *cell, enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	int u, a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	if (atomic_read(&cell->ref) <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	u = atomic_read(&cell->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	a = atomic_inc_return(&cell->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	trace_afs_cell(cell->debug_id, u, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	return cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)  * Record a cell becoming less active.  When the active counter reaches 1, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)  * is scheduled for destruction, but may get reactivated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) void afs_unuse_cell(struct afs_net *net, struct afs_cell *cell, enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	unsigned int debug_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	time64_t now, expire_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	int u, a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	if (!cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	_enter("%s", cell->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	now = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	cell->last_inactive = now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	expire_delay = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	if (cell->vl_servers->nr_servers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		expire_delay = afs_cell_gc_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	debug_id = cell->debug_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	u = atomic_read(&cell->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	a = atomic_dec_return(&cell->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	trace_afs_cell(debug_id, u, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	WARN_ON(a == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	if (a == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		/* 'cell' may now be garbage collected. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		afs_set_cell_timer(net, expire_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  * Note that a cell has been seen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) void afs_see_cell(struct afs_cell *cell, enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	int u, a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	u = atomic_read(&cell->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	a = atomic_read(&cell->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	trace_afs_cell(cell->debug_id, u, a, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)  * Queue a cell for management, giving the workqueue a ref to hold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) void afs_queue_cell(struct afs_cell *cell, enum afs_cell_trace reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	afs_get_cell(cell, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (!queue_work(afs_wq, &cell->manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		afs_put_cell(cell, afs_cell_trace_put_queue_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)  * Allocate a key to use as a placeholder for anonymous user security.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int afs_alloc_anon_key(struct afs_cell *cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	struct key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	/* Create a key to represent an anonymous user. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	memcpy(keyname, "afs@", 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	dp = keyname + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	cp = cell->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		*dp++ = tolower(*cp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	} while (*cp++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	key = rxrpc_get_null_key(keyname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	if (IS_ERR(key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		return PTR_ERR(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	cell->anonymous_key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	_debug("anon key %p{%x}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	       cell->anonymous_key, key_serial(cell->anonymous_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	return 0;
^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)  * Activate a cell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	struct hlist_node **p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	struct afs_cell *pcell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	if (!cell->anonymous_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		ret = afs_alloc_anon_key(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #ifdef CONFIG_AFS_FSCACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 					     &afs_cell_cache_index_def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 					     cell->name, strlen(cell->name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 					     NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 					     cell, 0, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	ret = afs_proc_cell_setup(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	mutex_lock(&net->proc_cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	for (p = &net->proc_cells.first; *p; p = &(*p)->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		pcell = hlist_entry(*p, struct afs_cell, proc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		if (strcmp(cell->name, pcell->name) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	cell->proc_link.pprev = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	cell->proc_link.next = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	rcu_assign_pointer(*p, &cell->proc_link.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	if (cell->proc_link.next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		cell->proc_link.next->pprev = &cell->proc_link.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	afs_dynroot_mkdir(net, cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	mutex_unlock(&net->proc_cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)  * Deactivate a cell.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	_enter("%s", cell->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	afs_proc_cell_remove(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	mutex_lock(&net->proc_cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	hlist_del_rcu(&cell->proc_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	afs_dynroot_rmdir(net, cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	mutex_unlock(&net->proc_cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) #ifdef CONFIG_AFS_FSCACHE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	fscache_relinquish_cookie(cell->cache, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	cell->cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	_leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)  * Manage a cell record, initialising and destroying it, maintaining its DNS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)  * records.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static void afs_manage_cell(struct afs_cell *cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	struct afs_net *net = cell->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	int ret, active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	_enter("%s", cell->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	_debug("state %u", cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	switch (cell->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	case AFS_CELL_INACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	case AFS_CELL_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		down_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		if (atomic_try_cmpxchg_relaxed(&cell->active, &active, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 			rb_erase(&cell->net_node, &net->cells);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 			trace_afs_cell(cell->debug_id, atomic_read(&cell->ref), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 				       afs_cell_trace_unuse_delete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 			smp_store_release(&cell->state, AFS_CELL_REMOVED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		up_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		if (cell->state == AFS_CELL_REMOVED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 			wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 			goto final_destruction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 		if (cell->state == AFS_CELL_FAILED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		smp_store_release(&cell->state, AFS_CELL_UNSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	case AFS_CELL_UNSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		smp_store_release(&cell->state, AFS_CELL_ACTIVATING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 		wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	case AFS_CELL_ACTIVATING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		ret = afs_activate_cell(net, cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 			goto activation_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		smp_store_release(&cell->state, AFS_CELL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	case AFS_CELL_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		if (atomic_read(&cell->active) > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 			if (test_and_clear_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 				ret = afs_update_cell(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 				if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 					cell->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 		smp_store_release(&cell->state, AFS_CELL_DEACTIVATING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 		wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	case AFS_CELL_DEACTIVATING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 		if (atomic_read(&cell->active) > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			goto reverse_deactivation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 		afs_deactivate_cell(net, cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 		smp_store_release(&cell->state, AFS_CELL_INACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	case AFS_CELL_REMOVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	_debug("bad state %u", cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	BUG(); /* Unhandled state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) activation_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	cell->error = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	afs_deactivate_cell(net, cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	smp_store_release(&cell->state, AFS_CELL_FAILED); /* vs error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) reverse_deactivation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	smp_store_release(&cell->state, AFS_CELL_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	wake_up_var(&cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	_leave(" [deact->act]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	_leave(" [done %u]", cell->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) final_destruction:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	/* The root volume is pinning the cell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	afs_put_volume(cell->net, cell->root_volume, afs_volume_trace_put_cell_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	cell->root_volume = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	afs_put_cell(cell, afs_cell_trace_put_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static void afs_manage_cell_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	struct afs_cell *cell = container_of(work, struct afs_cell, manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	afs_manage_cell(cell);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	afs_put_cell(cell, afs_cell_trace_put_queue_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)  * Manage the records of cells known to a network namespace.  This includes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)  * updating the DNS records and garbage collecting unused cells that were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)  * automatically added.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)  * Note that constructed cell records may only be removed from net->cells by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)  * this work item, so it is safe for this work item to stash a cursor pointing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)  * into the tree and then return to caller (provided it skips cells that are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)  * still under construction).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)  * Note also that we were given an increment on net->cells_outstanding by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)  * whoever queued us that we need to deal with before returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) void afs_manage_cells(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	struct afs_net *net = container_of(work, struct afs_net, cells_manager);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	struct rb_node *cursor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	time64_t now = ktime_get_real_seconds(), next_manage = TIME64_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	bool purging = !net->live;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	/* Trawl the cell database looking for cells that have expired from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	 * lack of use and cells whose DNS results have expired and dispatch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	 * their managers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	down_read(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	for (cursor = rb_first(&net->cells); cursor; cursor = rb_next(cursor)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		struct afs_cell *cell =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 			rb_entry(cursor, struct afs_cell, net_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 		unsigned active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 		bool sched_cell = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 		active = atomic_read(&cell->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 		trace_afs_cell(cell->debug_id, atomic_read(&cell->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 			       active, afs_cell_trace_manage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 		ASSERTCMP(active, >=, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 		if (purging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 			if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 				active = atomic_dec_return(&cell->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 				trace_afs_cell(cell->debug_id, atomic_read(&cell->ref),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 					       active, afs_cell_trace_unuse_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 		if (active == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 			struct afs_vlserver_list *vllist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 			time64_t expire_at = cell->last_inactive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 			read_lock(&cell->vl_servers_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 			vllist = rcu_dereference_protected(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 				cell->vl_servers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 				lockdep_is_held(&cell->vl_servers_lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 			if (vllist->nr_servers > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 				expire_at += afs_cell_gc_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 			read_unlock(&cell->vl_servers_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 			if (purging || expire_at <= now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 				sched_cell = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 			else if (expire_at < next_manage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 				next_manage = expire_at;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		if (!purging) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 			if (test_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 				sched_cell = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		if (sched_cell)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 			afs_queue_cell(cell, afs_cell_trace_get_queue_manage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	up_read(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	/* Update the timer on the way out.  We have to pass an increment on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	 * cells_outstanding in the namespace that we are in to the timer or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 	 * the work scheduler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 	if (!purging && next_manage < TIME64_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 		now = ktime_get_real_seconds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 		if (next_manage - now <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 			if (queue_work(afs_wq, &net->cells_manager))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 				atomic_inc(&net->cells_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 			afs_set_cell_timer(net, next_manage - now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 	afs_dec_cells_outstanding(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	_leave(" [%d]", atomic_read(&net->cells_outstanding));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)  * Purge in-memory cell database.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) void afs_cell_purge(struct afs_net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	struct afs_cell *ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 	down_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 	ws = net->ws_cell;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 	net->ws_cell = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 	up_write(&net->cells_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 	afs_unuse_cell(net, ws, afs_cell_trace_unuse_ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 	_debug("del timer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 	if (del_timer_sync(&net->cells_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 		atomic_dec(&net->cells_outstanding);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 	_debug("kick mgr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 	afs_queue_cell_manager(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 	_debug("wait");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 	wait_var_event(&net->cells_outstanding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 		       !atomic_read(&net->cells_outstanding));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 	_leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }