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