// SPDX-License-Identifier: GPL-2.0-or-later
/* AFS cell and server record management
 *
 * Copyright (C) 2002, 2017 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/slab.h>
#include <linux/key.h>
#include <linux/ctype.h>
#include <linux/dns_resolver.h>
#include <linux/sched.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <keys/rxrpc-type.h>
#include "internal.h"

static unsigned __read_mostly afs_cell_gc_delay = 10;
static unsigned __read_mostly afs_cell_min_ttl = 10 * 60;
static unsigned __read_mostly afs_cell_max_ttl = 24 * 60 * 60;
static atomic_t cell_debug_id;

static void afs_cell_timer(struct timer_list *timer);
static void afs_destroy_cell_work(struct work_struct *work);
static void afs_manage_cell_work(struct work_struct *work);

static void afs_dec_cells_outstanding(struct afs_net *net)
{
	if (atomic_dec_and_test(&net->cells_outstanding))
		wake_up_var(&net->cells_outstanding);
}

static void afs_set_cell_state(struct afs_cell *cell, enum afs_cell_state state)
{
	smp_store_release(&cell->state, state); /* Commit cell changes before state */
	smp_wmb(); /* Set cell state before task state */
	wake_up_var(&cell->state);
}

/*
 * Look up and get an activation reference on a cell record.  The caller must
 * hold net->cells_lock at least read-locked.
 */
static struct afs_cell *afs_find_cell_locked(struct afs_net *net,
					     const char *name, unsigned int namesz,
					     enum afs_cell_trace reason)
{
	struct afs_cell *cell = NULL;
	struct rb_node *p;
	int n;

	_enter("%*.*s", namesz, namesz, name);

	if (name && namesz == 0)
		return ERR_PTR(-EINVAL);
	if (namesz > AFS_MAXCELLNAME)
		return ERR_PTR(-ENAMETOOLONG);

	if (!name) {
		cell = rcu_dereference_protected(net->ws_cell,
						 lockdep_is_held(&net->cells_lock));
		if (!cell)
			return ERR_PTR(-EDESTADDRREQ);
		goto found;
	}

	p = net->cells.rb_node;
	while (p) {
		cell = rb_entry(p, struct afs_cell, net_node);

		n = strncasecmp(cell->name, name,
				min_t(size_t, cell->name_len, namesz));
		if (n == 0)
			n = cell->name_len - namesz;
		if (n < 0)
			p = p->rb_left;
		else if (n > 0)
			p = p->rb_right;
		else
			goto found;
	}

	return ERR_PTR(-ENOENT);

found:
	return afs_use_cell(cell, reason);
}

/*
 * Look up and get an activation reference on a cell record.
 */
struct afs_cell *afs_find_cell(struct afs_net *net,
			       const char *name, unsigned int namesz,
			       enum afs_cell_trace reason)
{
	struct afs_cell *cell;

	down_read(&net->cells_lock);
	cell = afs_find_cell_locked(net, name, namesz, reason);
	up_read(&net->cells_lock);
	return cell;
}

/*
 * Set up a cell record and fill in its name, VL server address list and
 * allocate an anonymous key
 */
static struct afs_cell *afs_alloc_cell(struct afs_net *net,
				       const char *name, unsigned int namelen,
				       const char *addresses)
{
	struct afs_vlserver_list *vllist = NULL;
	struct afs_cell *cell;
	int i, ret;

	ASSERT(name);
	if (namelen == 0)
		return ERR_PTR(-EINVAL);
	if (namelen > AFS_MAXCELLNAME) {
		_leave(" = -ENAMETOOLONG");
		return ERR_PTR(-ENAMETOOLONG);
	}

	/* Prohibit cell names that contain unprintable chars, '/' and '@' or
	 * that begin with a dot.  This also precludes "@cell".
	 */
	if (name[0] == '.')
		return ERR_PTR(-EINVAL);
	for (i = 0; i < namelen; i++) {
		char ch = name[i];
		if (!isprint(ch) || ch == '/' || ch == '@')
			return ERR_PTR(-EINVAL);
	}

	_enter("%*.*s,%s", namelen, namelen, name, addresses);

	cell = kzalloc_obj(struct afs_cell);
	if (!cell) {
		_leave(" = -ENOMEM");
		return ERR_PTR(-ENOMEM);
	}

	/* Allocate the cell name and the key name in one go. */
	cell->name = kmalloc(1 + namelen + 1 +
			     4 + namelen + 1, GFP_KERNEL);
	if (!cell->name) {
		kfree(cell);
		return ERR_PTR(-ENOMEM);
	}

	cell->name[0] = '.';
	cell->name++;
	cell->name_len = namelen;
	for (i = 0; i < namelen; i++)
		cell->name[i] = tolower(name[i]);
	cell->name[i++] = 0;

	cell->key_desc = cell->name + i;
	memcpy(cell->key_desc, "afs@", 4);
	memcpy(cell->key_desc + 4, cell->name, cell->name_len + 1);

	cell->net = net;
	refcount_set(&cell->ref, 1);
	atomic_set(&cell->active, 0);
	INIT_WORK(&cell->destroyer, afs_destroy_cell_work);
	INIT_WORK(&cell->manager, afs_manage_cell_work);
	timer_setup(&cell->management_timer, afs_cell_timer, 0);
	init_rwsem(&cell->vs_lock);
	cell->volumes = RB_ROOT;
	INIT_HLIST_HEAD(&cell->proc_volumes);
	seqlock_init(&cell->volume_lock);
	cell->fs_servers = RB_ROOT;
	init_rwsem(&cell->fs_lock);
	rwlock_init(&cell->vl_servers_lock);
	cell->flags = (1 << AFS_CELL_FL_CHECK_ALIAS);

	/* Provide a VL server list, filling it in if we were given a list of
	 * addresses to use.
	 */
	if (addresses) {
		vllist = afs_parse_text_addrs(net,
					      addresses, strlen(addresses), ':',
					      VL_SERVICE, AFS_VL_PORT);
		if (IS_ERR(vllist)) {
			ret = PTR_ERR(vllist);
			vllist = NULL;
			goto parse_failed;
		}

		vllist->source = DNS_RECORD_FROM_CONFIG;
		vllist->status = DNS_LOOKUP_NOT_DONE;
		cell->dns_expiry = TIME64_MAX;
	} else {
		ret = -ENOMEM;
		vllist = afs_alloc_vlserver_list(0);
		if (!vllist)
			goto error;
		vllist->source = DNS_RECORD_UNAVAILABLE;
		vllist->status = DNS_LOOKUP_NOT_DONE;
		cell->dns_expiry = ktime_get_real_seconds();
	}

	rcu_assign_pointer(cell->vl_servers, vllist);

	cell->dns_source = vllist->source;
	cell->dns_status = vllist->status;
	smp_store_release(&cell->dns_lookup_count, 1); /* vs source/status */
	atomic_inc(&net->cells_outstanding);
	ret = idr_alloc_cyclic(&net->cells_dyn_ino, cell,
			       2, INT_MAX / 2, GFP_KERNEL);
	if (ret < 0)
		goto error;
	cell->dynroot_ino = ret;
	cell->debug_id = atomic_inc_return(&cell_debug_id);

	trace_afs_cell(cell->debug_id, 1, 0, afs_cell_trace_alloc);

	_leave(" = %p", cell);
	return cell;

parse_failed:
	if (ret == -EINVAL)
		printk(KERN_ERR "kAFS: bad VL server IP address\n");
error:
	afs_put_vlserverlist(cell->net, vllist);
	kfree(cell->name - 1);
	kfree(cell);
	_leave(" = %d", ret);
	return ERR_PTR(ret);
}

/*
 * afs_lookup_cell - Look up or create a cell record.
 * @net:	The network namespace
 * @name:	The name of the cell.
 * @namesz:	The strlen of the cell name.
 * @vllist:	A colon/comma separated list of numeric IP addresses or NULL.
 * @reason:	The reason we're doing the lookup
 * @trace:	The reason to be logged if the lookup is successful.
 *
 * Look up a cell record by name and query the DNS for VL server addresses if
 * needed.  Note that that actual DNS query is punted off to the manager thread
 * so that this function can return immediately if interrupted whilst allowing
 * cell records to be shared even if not yet fully constructed.
 */
struct afs_cell *afs_lookup_cell(struct afs_net *net,
				 const char *name, unsigned int namesz,
				 const char *vllist,
				 enum afs_lookup_cell_for reason,
				 enum afs_cell_trace trace)
{
	struct afs_cell *cell, *candidate, *cursor;
	struct rb_node *parent, **pp;
	enum afs_cell_state state;
	int ret, n;

	_enter("%s,%s,%u", name, vllist, reason);

	if (reason != AFS_LOOKUP_CELL_PRELOAD) {
		cell = afs_find_cell(net, name, namesz, trace);
		if (!IS_ERR(cell)) {
			if (reason == AFS_LOOKUP_CELL_DYNROOT)
				goto no_wait;
			if (cell->state == AFS_CELL_SETTING_UP ||
			    cell->state == AFS_CELL_UNLOOKED)
				goto lookup_cell;
			goto wait_for_cell;
		}
	}

	/* Assume we're probably going to create a cell and preallocate and
	 * mostly set up a candidate record.  We can then use this to stash the
	 * name, the net namespace and VL server addresses.
	 *
	 * We also want to do this before we hold any locks as it may involve
	 * upcalling to userspace to make DNS queries.
	 */
	candidate = afs_alloc_cell(net, name, namesz, vllist);
	if (IS_ERR(candidate)) {
		_leave(" = %ld", PTR_ERR(candidate));
		return candidate;
	}

	/* Find the insertion point and check to see if someone else added a
	 * cell whilst we were allocating.
	 */
	down_write(&net->cells_lock);

	pp = &net->cells.rb_node;
	parent = NULL;
	while (*pp) {
		parent = *pp;
		cursor = rb_entry(parent, struct afs_cell, net_node);

		n = strncasecmp(cursor->name, name,
				min_t(size_t, cursor->name_len, namesz));
		if (n == 0)
			n = cursor->name_len - namesz;
		if (n < 0)
			pp = &(*pp)->rb_left;
		else if (n > 0)
			pp = &(*pp)->rb_right;
		else
			goto cell_already_exists;
	}

	cell = candidate;
	candidate = NULL;
	afs_use_cell(cell, trace);
	rb_link_node_rcu(&cell->net_node, parent, pp);
	rb_insert_color(&cell->net_node, &net->cells);
	up_write(&net->cells_lock);

lookup_cell:
	if (reason != AFS_LOOKUP_CELL_PRELOAD &&
	    reason != AFS_LOOKUP_CELL_ROOTCELL) {
		set_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags);
		afs_queue_cell(cell, afs_cell_trace_queue_new);
	}

wait_for_cell:
	state = smp_load_acquire(&cell->state); /* vs error */
	switch (state) {
	case AFS_CELL_ACTIVE:
	case AFS_CELL_DEAD:
		break;
	case AFS_CELL_UNLOOKED:
	default:
		if (reason == AFS_LOOKUP_CELL_PRELOAD ||
		    reason == AFS_LOOKUP_CELL_ROOTCELL)
			break;
		_debug("wait_for_cell");
		afs_see_cell(cell, afs_cell_trace_wait);
		wait_var_event(&cell->state,
			       ({
				       state = smp_load_acquire(&cell->state); /* vs error */
				       state == AFS_CELL_ACTIVE || state == AFS_CELL_DEAD;
			       }));
		_debug("waited_for_cell %d %d", cell->state, cell->error);
	}

no_wait:
	/* Check the state obtained from the wait check. */
	state = smp_load_acquire(&cell->state); /* vs error */
	if (state == AFS_CELL_DEAD) {
		ret = cell->error;
		goto error;
	}
	if (state == AFS_CELL_ACTIVE) {
		switch (cell->dns_status) {
		case DNS_LOOKUP_NOT_DONE:
			if (cell->dns_source == DNS_RECORD_FROM_CONFIG) {
				ret = 0;
				break;
			}
			fallthrough;
		default:
			ret = -EIO;
			goto error;
		case DNS_LOOKUP_GOOD:
		case DNS_LOOKUP_GOOD_WITH_BAD:
			ret = 0;
			break;
		case DNS_LOOKUP_GOT_NOT_FOUND:
			ret = -ENOENT;
			goto error;
		case DNS_LOOKUP_BAD:
			ret = -EREMOTEIO;
			goto error;
		case DNS_LOOKUP_GOT_LOCAL_FAILURE:
		case DNS_LOOKUP_GOT_TEMP_FAILURE:
		case DNS_LOOKUP_GOT_NS_FAILURE:
			ret = -EDESTADDRREQ;
			goto error;
		}
	}

	_leave(" = %p [cell]", cell);
	return cell;

cell_already_exists:
	_debug("cell exists");
	cell = cursor;
	if (reason == AFS_LOOKUP_CELL_PRELOAD) {
		ret = -EEXIST;
	} else {
		afs_use_cell(cursor, trace);
		ret = 0;
	}
	up_write(&net->cells_lock);
	if (candidate)
		afs_put_cell(candidate, afs_cell_trace_put_candidate);
	if (ret == 0)
		goto wait_for_cell;
	goto error_noput;
error:
	afs_unuse_cell(cell, afs_cell_trace_unuse_lookup_error);
error_noput:
	_leave(" = %d [error]", ret);
	return ERR_PTR(ret);
}

/*
 * set the root cell information
 * - can be called with a module parameter string
 * - can be called from a write to /proc/fs/afs/rootcell
 */
int afs_cell_init(struct afs_net *net, const char *rootcell)
{
	struct afs_cell *old_root, *new_root;
	const char *cp, *vllist;
	size_t len;

	_enter("");

	if (!rootcell) {
		/* module is loaded with no parameters, or built statically.
		 * - in the future we might initialize cell DB here.
		 */
		_leave(" = 0 [no root]");
		return 0;
	}

	cp = strchr(rootcell, ':');
	if (!cp) {
		_debug("kAFS: no VL server IP addresses specified");
		vllist = NULL;
		len = strlen(rootcell);
	} else {
		vllist = cp + 1;
		len = cp - rootcell;
	}

	if (len == 0 || !rootcell[0] || rootcell[0] == '.' || rootcell[len - 1] == '.')
		return -EINVAL;
	if (memchr(rootcell, '/', len))
		return -EINVAL;
	cp = strstr(rootcell, "..");
	if (cp && cp < rootcell + len)
		return -EINVAL;

	/* allocate a cell record for the root/workstation cell */
	new_root = afs_lookup_cell(net, rootcell, len, vllist,
				   AFS_LOOKUP_CELL_ROOTCELL,
				   afs_cell_trace_use_lookup_ws);
	if (IS_ERR(new_root)) {
		_leave(" = %ld", PTR_ERR(new_root));
		return PTR_ERR(new_root);
	}

	if (!test_and_set_bit(AFS_CELL_FL_NO_GC, &new_root->flags))
		afs_use_cell(new_root, afs_cell_trace_use_pin);

	/* install the new cell */
	down_write(&net->cells_lock);
	old_root = rcu_replace_pointer(net->ws_cell, new_root,
				       lockdep_is_held(&net->cells_lock));
	up_write(&net->cells_lock);

	afs_unuse_cell(old_root, afs_cell_trace_unuse_ws);
	_leave(" = 0");
	return 0;
}

/*
 * Update a cell's VL server address list from the DNS.
 */
static int afs_update_cell(struct afs_cell *cell)
{
	struct afs_vlserver_list *vllist, *old = NULL, *p;
	unsigned int min_ttl = READ_ONCE(afs_cell_min_ttl);
	unsigned int max_ttl = READ_ONCE(afs_cell_max_ttl);
	time64_t now, expiry = 0;
	int ret = 0;

	_enter("%s", cell->name);

	vllist = afs_dns_query(cell, &expiry);
	if (IS_ERR(vllist)) {
		ret = PTR_ERR(vllist);

		_debug("%s: fail %d", cell->name, ret);
		if (ret == -ENOMEM)
			goto out_wake;

		vllist = afs_alloc_vlserver_list(0);
		if (!vllist) {
			if (ret >= 0)
				ret = -ENOMEM;
			goto out_wake;
		}

		switch (ret) {
		case -ENODATA:
		case -EDESTADDRREQ:
			vllist->status = DNS_LOOKUP_GOT_NOT_FOUND;
			break;
		case -EAGAIN:
		case -ECONNREFUSED:
			vllist->status = DNS_LOOKUP_GOT_TEMP_FAILURE;
			break;
		default:
			vllist->status = DNS_LOOKUP_GOT_LOCAL_FAILURE;
			break;
		}
	}

	_debug("%s: got list %d %d", cell->name, vllist->source, vllist->status);
	cell->dns_status = vllist->status;

	now = ktime_get_real_seconds();
	if (min_ttl > max_ttl)
		max_ttl = min_ttl;
	if (expiry < now + min_ttl)
		expiry = now + min_ttl;
	else if (expiry > now + max_ttl)
		expiry = now + max_ttl;

	_debug("%s: status %d", cell->name, vllist->status);
	if (vllist->source == DNS_RECORD_UNAVAILABLE) {
		switch (vllist->status) {
		case DNS_LOOKUP_GOT_NOT_FOUND:
			/* The DNS said that the cell does not exist or there
			 * weren't any addresses to be had.
			 */
			cell->dns_expiry = expiry;
			break;

		case DNS_LOOKUP_BAD:
		case DNS_LOOKUP_GOT_LOCAL_FAILURE:
		case DNS_LOOKUP_GOT_TEMP_FAILURE:
		case DNS_LOOKUP_GOT_NS_FAILURE:
		default:
			cell->dns_expiry = now + 10;
			break;
		}
	} else {
		cell->dns_expiry = expiry;
	}

	/* Replace the VL server list if the new record has servers or the old
	 * record doesn't.
	 */
	write_lock(&cell->vl_servers_lock);
	p = rcu_dereference_protected(cell->vl_servers, true);
	if (vllist->nr_servers > 0 || p->nr_servers == 0) {
		rcu_assign_pointer(cell->vl_servers, vllist);
		cell->dns_source = vllist->source;
		old = p;
	}
	write_unlock(&cell->vl_servers_lock);
	afs_put_vlserverlist(cell->net, old);

out_wake:
	smp_store_release(&cell->dns_lookup_count,
			  cell->dns_lookup_count + 1); /* vs source/status */
	wake_up_var(&cell->dns_lookup_count);
	_leave(" = %d", ret);
	return ret;
}

/*
 * Destroy a cell record
 */
static void afs_cell_destroy(struct rcu_head *rcu)
{
	struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu);
	struct afs_net *net = cell->net;
	int r;

	_enter("%p{%s}", cell, cell->name);

	r = refcount_read(&cell->ref);
	ASSERTCMP(r, ==, 0);
	trace_afs_cell(cell->debug_id, r, atomic_read(&cell->active), afs_cell_trace_free);

	afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers));
	afs_unuse_cell(cell->alias_of, afs_cell_trace_unuse_alias);
	key_put(cell->anonymous_key);
	idr_remove(&net->cells_dyn_ino, cell->dynroot_ino);
	kfree(cell->name - 1);
	kfree(cell);

	afs_dec_cells_outstanding(net);
	_leave(" [destroyed]");
}

static void afs_destroy_cell_work(struct work_struct *work)
{
	struct afs_cell *cell = container_of(work, struct afs_cell, destroyer);

	afs_see_cell(cell, afs_cell_trace_destroy);
	timer_delete_sync(&cell->management_timer);
	cancel_work_sync(&cell->manager);
	call_rcu(&cell->rcu, afs_cell_destroy);
}

/*
 * Get a reference on a cell record.
 */
struct afs_cell *afs_get_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	int r;

	__refcount_inc(&cell->ref, &r);
	trace_afs_cell(cell->debug_id, r + 1, atomic_read(&cell->active), reason);
	return cell;
}

/*
 * Drop a reference on a cell record.
 */
void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	if (cell) {
		unsigned int debug_id = cell->debug_id;
		unsigned int a;
		bool zero;
		int r;

		a = atomic_read(&cell->active);
		zero = __refcount_dec_and_test(&cell->ref, &r);
		trace_afs_cell(debug_id, r - 1, a, reason);
		if (zero) {
			a = atomic_read(&cell->active);
			WARN(a != 0, "Cell active count %u > 0\n", a);
			WARN_ON(!queue_work(afs_wq, &cell->destroyer));
		}
	}
}

/*
 * Note a cell becoming more active.
 */
struct afs_cell *afs_use_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	int r, a;

	__refcount_inc(&cell->ref, &r);
	a = atomic_inc_return(&cell->active);
	trace_afs_cell(cell->debug_id, r + 1, a, reason);
	return cell;
}

/*
 * Record a cell becoming less active.  When the active counter reaches 1, it
 * is scheduled for destruction, but may get reactivated.
 */
void afs_unuse_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	unsigned int debug_id;
	time64_t now, expire_delay;
	bool zero;
	int r, a;

	if (!cell)
		return;

	_enter("%s", cell->name);

	now = ktime_get_real_seconds();
	cell->last_inactive = now;
	expire_delay = 0;
	if (cell->vl_servers->nr_servers)
		expire_delay = afs_cell_gc_delay;

	debug_id = cell->debug_id;
	a = atomic_dec_return(&cell->active);
	if (!a)
		/* 'cell' may now be garbage collected. */
		afs_set_cell_timer(cell, expire_delay);

	zero = __refcount_dec_and_test(&cell->ref, &r);
	trace_afs_cell(debug_id, r - 1, a, reason);
	if (zero)
		WARN_ON(!queue_work(afs_wq, &cell->destroyer));
}

/*
 * Note that a cell has been seen.
 */
void afs_see_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	int r, a;

	r = refcount_read(&cell->ref);
	a = atomic_read(&cell->active);
	trace_afs_cell(cell->debug_id, r, a, reason);
}

/*
 * Queue a cell for management, giving the workqueue a ref to hold.
 */
void afs_queue_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	queue_work(afs_wq, &cell->manager);
}

/*
 * Cell-specific management timer.
 */
static void afs_cell_timer(struct timer_list *timer)
{
	struct afs_cell *cell = container_of(timer, struct afs_cell, management_timer);

	afs_see_cell(cell, afs_cell_trace_see_mgmt_timer);
	if (refcount_read(&cell->ref) > 0 && cell->net->live)
		queue_work(afs_wq, &cell->manager);
}

/*
 * Set/reduce the cell timer.
 */
void afs_set_cell_timer(struct afs_cell *cell, unsigned int delay_secs)
{
	timer_reduce(&cell->management_timer, jiffies + delay_secs * HZ);
}

/*
 * Activate a cell.
 */
static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
{
	struct hlist_node **p;
	struct afs_cell *pcell;
	int ret;

	ret = afs_proc_cell_setup(cell);
	if (ret < 0)
		return ret;

	mutex_lock(&net->proc_cells_lock);
	for (p = &net->proc_cells.first; *p; p = &(*p)->next) {
		pcell = hlist_entry(*p, struct afs_cell, proc_link);
		if (strcmp(cell->name, pcell->name) < 0)
			break;
	}

	cell->proc_link.pprev = p;
	cell->proc_link.next = *p;
	rcu_assign_pointer(*p, &cell->proc_link.next);
	if (cell->proc_link.next)
		cell->proc_link.next->pprev = &cell->proc_link.next;

	mutex_unlock(&net->proc_cells_lock);
	return 0;
}

/*
 * Deactivate a cell.
 */
static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
{
	_enter("%s", cell->name);

	afs_proc_cell_remove(cell);

	mutex_lock(&net->proc_cells_lock);
	if (!hlist_unhashed(&cell->proc_link))
		hlist_del_rcu(&cell->proc_link);
	mutex_unlock(&net->proc_cells_lock);

	_leave("");
}

static bool afs_has_cell_expired(struct afs_cell *cell, time64_t *_next_manage)
{
	const struct afs_vlserver_list *vllist;
	time64_t expire_at = cell->last_inactive;
	time64_t now = ktime_get_real_seconds();

	if (atomic_read(&cell->active))
		return false;
	if (!cell->net->live)
		return true;

	vllist = rcu_dereference_protected(cell->vl_servers, true);
	if (vllist && vllist->nr_servers > 0)
		expire_at += afs_cell_gc_delay;

	if (expire_at <= now)
		return true;
	if (expire_at < *_next_manage)
		*_next_manage = expire_at;
	return false;
}

/*
 * Manage a cell record, initialising and destroying it, maintaining its DNS
 * records.
 */
static bool afs_manage_cell(struct afs_cell *cell)
{
	struct afs_net *net = cell->net;
	time64_t next_manage = TIME64_MAX;
	int ret;

	_enter("%s", cell->name);

	_debug("state %u", cell->state);
	switch (cell->state) {
	case AFS_CELL_SETTING_UP:
		goto set_up_cell;
	case AFS_CELL_UNLOOKED:
	case AFS_CELL_ACTIVE:
		goto cell_is_active;
	case AFS_CELL_REMOVING:
		WARN_ON_ONCE(1);
		return false;
	case AFS_CELL_DEAD:
		return false;
	default:
		_debug("bad state %u", cell->state);
		WARN_ON_ONCE(1); /* Unhandled state */
		return false;
	}

set_up_cell:
	ret = afs_activate_cell(net, cell);
	if (ret < 0) {
		cell->error = ret;
		goto remove_cell;
	}

	afs_set_cell_state(cell, AFS_CELL_UNLOOKED);

cell_is_active:
	if (afs_has_cell_expired(cell, &next_manage))
		goto remove_cell;

	if (test_and_clear_bit(AFS_CELL_FL_DO_LOOKUP, &cell->flags)) {
		ret = afs_update_cell(cell);
		if (ret < 0)
			cell->error = ret;
		if (cell->state == AFS_CELL_UNLOOKED)
			afs_set_cell_state(cell, AFS_CELL_ACTIVE);
	}

	if (next_manage < TIME64_MAX && cell->net->live) {
		time64_t now = ktime_get_real_seconds();

		if (next_manage - now <= 0)
			afs_queue_cell(cell, afs_cell_trace_queue_again);
		else
			afs_set_cell_timer(cell, next_manage - now);
	}
	_leave(" [done %u]", cell->state);
	return false;

remove_cell:
	down_write(&net->cells_lock);

	if (atomic_read(&cell->active)) {
		up_write(&net->cells_lock);
		goto cell_is_active;
	}

	/* Make sure that the expiring server records are going to see the fact
	 * that the cell is caput.
	 */
	afs_set_cell_state(cell, AFS_CELL_REMOVING);

	afs_deactivate_cell(net, cell);
	afs_purge_servers(cell);

	rb_erase(&cell->net_node, &net->cells);
	afs_see_cell(cell, afs_cell_trace_unuse_delete);
	up_write(&net->cells_lock);

	/* The root volume is pinning the cell */
	afs_put_volume(cell->root_volume, afs_volume_trace_put_cell_root);
	cell->root_volume = NULL;

	afs_set_cell_state(cell, AFS_CELL_DEAD);
	return true;
}

static void afs_manage_cell_work(struct work_struct *work)
{
	struct afs_cell *cell = container_of(work, struct afs_cell, manager);
	bool final_put;

	afs_see_cell(cell, afs_cell_trace_manage);
	final_put = afs_manage_cell(cell);
	afs_see_cell(cell, afs_cell_trace_managed);
	if (final_put)
		afs_put_cell(cell, afs_cell_trace_put_final);
}

/*
 * Purge in-memory cell database.
 */
void afs_cell_purge(struct afs_net *net)
{
	struct afs_cell *ws;
	struct rb_node *cursor;

	_enter("");

	down_write(&net->cells_lock);
	ws = rcu_replace_pointer(net->ws_cell, NULL,
				 lockdep_is_held(&net->cells_lock));
	up_write(&net->cells_lock);
	afs_unuse_cell(ws, afs_cell_trace_unuse_ws);

	_debug("kick cells");
	down_read(&net->cells_lock);
	for (cursor = rb_first(&net->cells); cursor; cursor = rb_next(cursor)) {
		struct afs_cell *cell = rb_entry(cursor, struct afs_cell, net_node);

		afs_see_cell(cell, afs_cell_trace_purge);

		if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags))
			afs_unuse_cell(cell, afs_cell_trace_unuse_pin);

		afs_queue_cell(cell, afs_cell_trace_queue_purge);
	}
	up_read(&net->cells_lock);

	_debug("wait");
	wait_var_event(&net->cells_outstanding,
		       !atomic_read(&net->cells_outstanding));
	_leave("");
}
