/* Copyright (c) 2018 Google Inc
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * tree_file: structs and helpers for a tree-based filesystem for 9ns devices.
 */

#include <tree_file.h>
#include <kmalloc.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>

/* Adds to the LRU if it was not on it.
 *
 * Caller holds the TF lock or o/w knows it has the only ref to tf. */
static void __add_to_lru(struct tree_file *tf)
{
	struct walk_cache *wc = &tf->tfs->wc;

	if (tf->flags & TF_F_ON_LRU)
		return;
	tf->flags |= TF_F_ON_LRU;
	spin_lock(&wc->lru_lock);
	list_add_tail(&tf->lru, &wc->lru);
	spin_unlock(&wc->lru_lock);
}

/* Removes from the LRU if it was on it.
 *
 * Caller holds the TF lock or o/w knows it has the only ref to tf. */
static void __remove_from_lru(struct tree_file *tf)
{
	struct walk_cache *wc = &tf->tfs->wc;

	if (!(tf->flags & TF_F_ON_LRU))
		return;
	assert(kref_refcnt(&tf->kref) == 0);
	tf->flags &= ~TF_F_ON_LRU;
	spin_lock(&wc->lru_lock);
	list_del(&tf->lru);
	spin_unlock(&wc->lru_lock);
}

/* Caller holds the parent's qlock.  Separate helpers here in case we track
 * nr_children. */
static void __add_to_parent_list(struct tree_file *parent,
                                 struct tree_file *child)
{
	list_add(&child->siblings, &parent->children);
}

/* Caller holds the parent's qlock */
static void __remove_from_parent_list(struct tree_file *parent,
                                      struct tree_file *child)
{
	list_del(&child->siblings);
}

/* Safely grabs a kref on TF, possibly resurrecting from 0, at which point the
 * file would be on an LRU list.  This syncs with tree removers, including
 * unlinking from the tree on remove and LRU cache pruners.  Returns true if we
 * got the ref, false if we lost and the file was disconnected. */
bool tf_kref_get(struct tree_file *tf)
{
	spin_lock(&tf->lifetime);
	if (tf->flags & TF_F_DISCONNECTED) {
		spin_unlock(&tf->lifetime);
		return false;
	}
	__remove_from_lru(tf);
	__kref_get(&tf->kref, 1);
	tf->flags |= TF_F_HAS_BEEN_USED;
	spin_unlock(&tf->lifetime);
	return true;
}

void tf_kref_put(struct tree_file *tf)
{
	kref_put(&tf->kref);
}

static void __tf_free(struct tree_file *tf)
{
	struct tree_file *parent = tf->parent;
	struct tree_filesystem *tfs = tf->tfs;

	tf->tfs->tf_ops.free(tf);
	if (tf->flags & TF_F_IS_ROOT) {
		assert(tfs->root == tf);
		assert(!parent);
	}
	cleanup_fs_file((struct fs_file*)tf);
	kfree(tf);
	/* the reason for decreffing the parent now is for convenience on releasing.
	 * When we unlink the child from the LRU pruner, we don't want to release
	 * the parent immediately while we hold the parent's qlock (and other
	 * locks). */
	if (parent)
		tf_kref_put(parent);
}

static void __tf_free_rcu(struct rcu_head *head)
{
	struct tree_file *tf = container_of(head, struct tree_file, rcu);

	__tf_free(tf);
}

static void tf_release(struct kref *kref)
{
	struct tree_file *tf = container_of(kref, struct tree_file, kref);

	assert(!(tf->flags & TF_F_NEGATIVE));

	spin_lock(&tf->lifetime);
	if (kref_refcnt(&tf->kref) > 0) {
		/* Someone resurrected after we decreffed to 0. */
		assert(!(tf->flags & TF_F_ON_LRU));
		spin_unlock(&tf->lifetime);
		return;
	}
	if (!(tf->flags & (TF_F_DISCONNECTED | TF_F_IS_ROOT))) {
		/* It's possible that we paused before locking, then another thread
		 * upped, downed, and put it on the LRU list already.  The helper deals
		 * with that. */
		__add_to_lru(tf);
		spin_unlock(&tf->lifetime);
		return;
	}
	spin_unlock(&tf->lifetime);
	/* Need RCU, since we could have had a reader who saw the object and still
	 * needs to try to kref (and fail).  call_rcu, since we can't block. */
	call_rcu(&tf->rcu, __tf_free_rcu);
}

static unsigned long hash_string(const char *name)
{
	unsigned long hash = 5381;

	for (const char *p = name; *p; p++) {
		/* hash * 33 + c, djb2's technique */
		hash = ((hash << 5) + hash) + *p;
	}
	return hash;
}

static void wc_init(struct walk_cache *wc)
{
	spinlock_init(&wc->lru_lock);
	INIT_LIST_HEAD(&wc->lru);
	spinlock_init(&wc->ht_lock);
	wc->ht = wc->static_ht;
	hash_init_hh(&wc->hh);
	for (int i = 0; i < wc->hh.nr_hash_lists; i++)
		INIT_HLIST_HEAD(&wc->ht[i]);
}

static void wc_destroy(struct walk_cache *wc)
{
	assert(list_empty(&wc->lru));
	for (int i = 0; i < wc->hh.nr_hash_lists; i++)
		assert(hlist_empty(&wc->ht[i]));
	if (wc->ht != wc->static_ht)
		kfree(wc->ht);
}

/* Looks up the child of parent named 'name' in the walk cache hash table.
 * Caller needs to hold an rcu read lock. */
static struct tree_file *wc_lookup_child(struct tree_file *parent,
                                         const char *name)
{
	struct walk_cache *wc = &parent->tfs->wc;
	unsigned long hash_val = hash_string(name);
	struct hlist_head *bucket;
	struct tree_file *i;

	bucket = &wc->ht[hash_val % wc->hh.nr_hash_bits];
	hlist_for_each_entry_rcu(i, bucket, hash) {
		/* Note 'i' is an rcu protected pointer.  That deref is safe.  i->parent
		 * is also a pointer that in general we want to protect.  In this case,
		 * even though we don't dereference it, we want a pointer that is good
		 * enough to dereference so we can do the comparison. */
		if (rcu_dereference(i->parent) != parent)
			continue;
		/* The file's name should never change while it is in the table, so no
		 * need for a seq-reader.  Can't assert though, since there are valid
		 * reasons for other seq lockers. */
		if (!strcmp(tree_file_to_name(i), name))
			return i;
	}
	return NULL;
}

/* Caller should hold the parent's qlock */
static void wc_insert_child(struct tree_file *parent, struct tree_file *child)
{
	struct walk_cache *wc = &parent->tfs->wc;
	unsigned long hash_val = hash_string(tree_file_to_name(child));
	struct hlist_head *bucket;

	assert(child->parent == parent);	/* catch bugs from our callers */
	/* TODO: consider bucket locks and/or growing the HT.  Prob need a seq_ctr
	 * in the WC, used on the read side during resizing.  Removal probably would
	 * need something other than the bucket lock too (confusion about which
	 * bucket during the op). */
	spin_lock(&wc->ht_lock);
	bucket = &wc->ht[hash_val % wc->hh.nr_hash_bits];
	hlist_add_head_rcu(&child->hash, bucket);
	spin_unlock(&wc->ht_lock);
}

/* Caller should hold the parent's qlock */
static void wc_remove_child(struct tree_file *parent, struct tree_file *child)
{
	struct walk_cache *wc = &parent->tfs->wc;

	assert(child->parent == parent);	/* catch bugs from our callers */
	spin_lock(&wc->ht_lock);
	hlist_del_rcu(&child->hash);
	spin_unlock(&wc->ht_lock);
}

/* Helper: returns a refcounted pointer to the potential parent.  May return 0.
 *
 * Caller needs to qlock the parent and recheck tf->parent.  Callers always need
 * to get a kref on the parent.  We can rcu-read the parent and *attempt* to
 * qlock under rcu, but we might block.  Then, say, the TF and the parent got
 * removed, and *then* we get the qlock.  We're too late. */
static struct tree_file *__tf_get_potential_parent(struct tree_file *tf)
{
	struct tree_file *parent;

	rcu_read_lock();
	parent = rcu_dereference(tf->parent);
	if (!parent) {
		/* the root of the tree has no parent */
		rcu_read_unlock();
		return NULL;
	}
	if (!tf_kref_get(parent))
		parent = NULL;
	rcu_read_unlock();
	return parent;
}

/* Returns a refcounted and qlocked parent for child.  NULL on failure. */
static struct tree_file *get_locked_and_kreffed_parent(struct tree_file *child)
{
	struct tree_file *parent;

	parent = __tf_get_potential_parent(child);
	if (!parent)
		return NULL;
	qlock(&parent->file.qlock);
	if (parent != child->parent) {
		qunlock(&parent->file.qlock);
		tf_kref_put(parent);
		return NULL;
	}
	return parent;
}

static bool __mark_disconnected(struct tree_file *tf)
{
	bool need_to_free;

	spin_lock(&tf->lifetime);
	tf->flags |= TF_F_DISCONNECTED;
	__remove_from_lru(tf);
	need_to_free = kref_refcnt(&tf->kref) == 0;
	spin_unlock(&tf->lifetime);
	return need_to_free;
}

/* Disconnects child from the in-memory tree structure (i.e. only the front
 * end).  Caller holds the parent qlock.  Assumes child is a child of parent.
 * Once you disconnect, you can't touch the child object.
 *
 * Racing with concurrent lookups, who might grab a ref if they get in before
 * DISCONNECTED, and racing with release (after ref = 0), who might free, if it
 * was already unlinked. */
static void __disconnect_child(struct tree_file *parent,
                               struct tree_file *child)
{
	bool need_to_free;

	need_to_free = __mark_disconnected(child);
	/* Note child->parent is still set.  We clear that in __tf_free. */
	__remove_from_parent_list(parent, child);
	wc_remove_child(parent, child);
	if (need_to_free)
		call_rcu(&child->rcu, __tf_free_rcu);
}

/* Backend will need to fill in dir, except for name.  Note this has a kref ==
 * 0, but is not on the LRU yet. */
struct tree_file *tree_file_alloc(struct tree_filesystem *tfs,
                                  struct tree_file *parent, const char *name)
{
	struct tree_file *tf;

	tf = kzmalloc(sizeof(struct tree_file), MEM_WAIT);
	fs_file_init((struct fs_file*)tf, name, &tfs->fs_ops);
	kref_init(&tf->kref, tf_release, 0);
	spinlock_init(&tf->lifetime);
	/* Need to set the parent early on, even if the child isn't linked yet, so
	 * that the TFS ops know who the parent is. */
	tf->parent = parent;
	if (parent)
		kref_get(&parent->kref, 1);
	INIT_LIST_HEAD(&tf->children);
	tf->can_have_children = true;
	tf->tfs = tfs;
	return tf;
}

/* Callers must hold the parent's qlock. */
static void __link_child(struct tree_file *parent, struct tree_file *child)
{
	/* Devices may have already increffed ("+1 for existing").  Those that don't
	 * need to be on the LRU.  We haven't linked to the parent yet, so we hold
	 * the only ref.  Once we unlock in __add_to_lru, we're discoverable via
	 * that list, even though we're not linked.  The lru pruner is careful to
	 * not muck with the parent's or wc linkage without qlocking the parent,
	 * which we currently hold. */
	if (kref_refcnt(&child->kref) == 0)
		__add_to_lru(child);
	/* This was set in tree_file_alloc */
	assert(child->parent == parent);
	__add_to_parent_list(parent, child);
	wc_insert_child(parent, child);
}

static void neuter_directory(struct tree_file *dir)
{
	bool throw = false;

	qlock(&dir->file.qlock);
	if (dir->tfs->tf_ops.has_children(dir))
		throw = true;
	dir->can_have_children = false;
	qunlock(&dir->file.qlock);
	if (throw)
		error(ENOTEMPTY, "can't remove dir with children");
}

/* Unlink a child from the tree.  Last ref will clean it up, which will not be
 * us.  Caller should hold krefs on the child and parent.  The child's kref will
 * actually keep the parent's alive, but all practical callers will have the
 * parent kreff'ed and qlocked - which is required to ensure the child is still
 * a child of parent. */
static void __unlink_child(struct tree_file *parent, struct tree_file *child)
{
	/* Need to make sure concurrent creates/renames do not add children to
	 * directories that are unlinked.  Note we don't undo the neutering if the
	 * backend fails. */
	if (tree_file_is_dir(child))
		neuter_directory(child);
	/* The ramfs backend will probably decref the "+1 for existing" ref.
	 * This is OK.  If that was the last ref, the child will briefly be on
	 * the LRU list (which ramfs ignores).  When we disconnect, we'll yank
	 * the child back off the list and then free it (after rcu). */
	parent->tfs->tf_ops.unlink(parent, child);
	__disconnect_child(parent, child);
}

/* Talks to the backend and ensures a tree_file for the child exists, either
 * positive or negative.  Throws an error; doesn't return NULL.
 *
 * This returns with an rcu read lock sufficient to protect the returned TF, but
 * it is *not* kreffed.  It could be a negative entry, which is not kreffed.
 *
 * It is possible that at the moment we qunlock, someone comes along and removes
 * the entry (LRU prune or file removal (for positive entries)).  That's fine -
 * we have an rcu read lock, just like during a regular walk, when the removal
 * could happen anyways. */
static struct tree_file *lookup_child_entry(struct tree_file *parent,
                                            const char *name)
{
	ERRSTACK(1);
	struct tree_file *child;

	qlock(&parent->file.qlock);
	child = wc_lookup_child(parent, name);
	if (child) {
		/* Since we last looked, but before we qlocked, someone else added our
		 * entry. */
		rcu_read_lock();
		qunlock(&parent->file.qlock);
		return child;
	}
	child = tree_file_alloc(parent->tfs, parent, name);
	if (waserror()) {
		/* child wasn't fully created, so freeing it may be tricky, esp on the
		 * device ops side (might see something they never created). */
		__tf_free(child);
		qunlock(&parent->file.qlock);
		nexterror();
	}
	parent->tfs->tf_ops.lookup(parent, child);
	poperror();
	__link_child(parent, child);
	rcu_read_lock();
	qunlock(&parent->file.qlock);
	return child;
}

/* Walks a tree filesystem from 'from' for array of null-terminated names.
 * Devices will often use tree_chan_walk(), but can use this directly if they
 * want more control.
 *
 * Returns the WQ of qids.  On complete/successful walks, we hang a refcnted TF
 * on wq->clone.
 *
 * Walks can return intermediate results, which is when there is an error but we
 * have walked at least once.  The partial return is useful for namec(), which
 * can succeed if something was mounted on an intermediate QID.  Walks that have
 * no results set error and return NULL, which is what namec() expects. */
struct walkqid *tree_file_walk(struct tree_file *from, char **name,
                               unsigned int nname)
{
	ERRSTACK(2);
	struct tree_file *at, *next;
	struct tree_filesystem *tfs = from->tfs;
	struct walkqid *wq;

	wq = kzmalloc(sizeof(struct walkqid) + nname * sizeof(struct qid),
				  MEM_WAIT);
	/* A walk with zero names means "make me a copy."  If we go through the
	 * regular walker, our usual tf_kref_get will fail - similar to failing if
	 * we got a walk for "foo/../" during a concurrent removal of ourselves.
	 * We'll let a walk of zero names work, but if you provide any names, the
	 * actual walk must happen.
	 *
	 * This is tricky, and confused me a little.  We're returning a *TF* through
	 * wq->clone, not a chan, and that is refcounted.  Normally for chans that
	 * end up with wq->clone == c, we do not incref the object hanging off the
	 * chan (see k/d/d/eventfd.c), since there is just one chan with a kreffed
	 * object hanging off e.g. c->aux.  But here, wq->clone is considered a
	 * distinct refcnt to some TF, and it might be 'from.'  Our *caller* needs
	 * to deal with the "wq->clone == from_chan", since they deal with chans.
	 * We deal with tree files. */
	if (!nname) {
		kref_get(&from->kref, 1);
		wq->clone = (struct chan*)from;
		return wq;
	}
	if (waserror()) {
		kfree(wq);
		poperror();
		return NULL;
	}
	rcu_read_lock();
	at = from;
	for (int i = 0; i < nname; i++) {
		/* Walks end if we reach a regular file, i.e. you can't walk through a
		 * file, only a dir.  But even if there are more names, the overall walk
		 * might succeed.  E.g. a directory could be mounted on top of the
		 * current file we're at.  That's just not our job. */
		if (tree_file_is_file(at)) {
			if (i == 0)
				error(ENOTDIR, "initial walk from a file");
			break;
		}
		/* Normally, symlinks stop walks, and namec's walk() will deal with it.
		 * We allow walks 'through' symlinks, but only for .. and only for the
		 * first name.  This is for relative lookups so we can find the parent
		 * of a symlink. */
		if (tree_file_is_symlink(at)) {
			if (i != 0)
				break;
			if (strcmp(name[i], ".."))
				error(ELOOP, "walk from a symlink that wasn't ..");
		}
		if (!caller_has_tf_perms(at, O_READ)) {
			if (i == 0)
				error(EACCES, "missing perm for lookup");
			break;
		}
		if (!strcmp(name[i], ".")) {
			wq->qid[wq->nqid++] = tree_file_to_qid(at);
			continue;
		}
		if (!strcmp(name[i], "..")) {
			next = rcu_dereference(at->parent);
			if (!next) {
				if (tree_file_is_root(at)) {
					wq->qid[wq->nqid++] = tree_file_to_qid(at);
					/* I think namec should never give us DOTDOT that isn't at
					 * the end of the names array.  Though devwalk() seems to
					 * expect it. */
					if (i != nname - 1)
						warn("Possible namec DOTDOT bug, call for help!");
					continue;
				}
				/* We lost our parent due to a removal/rename.  We might have
				 * walked enough for our walk to succeed (e.g.  there's a mount
				 * point in the WQ), so we can return what we have.  Though if
				 * we've done nothing, it's a failure.
				 *
				 * Note the removal could have happened a long time ago:
				 * consider an O_PATH open, then namec_from().
				 *
				 * We also could walk up and see the *new* parent during
				 * rename().  For instance, /src/x/../y could get the old /src/y
				 * or the new /dst/y.  If we want to avoid that, then we'll need
				 * some sort of sync with rename to make sure we don't get the
				 * new one.  Though this can happen with namec_from(), so I'm
				 * not sure I care. */
				if (i == 0)
					error(ENOENT, "file lost its parent during lookup");
				break;
			}
			at = next;
			wq->qid[wq->nqid++] = tree_file_to_qid(at);
			continue;
		}
		next = wc_lookup_child(at, name[i]);
		if (!next) {
			/* TFSs with no backend have the entire tree in the WC HT. */
			if (!tfs->tf_ops.lookup) {
				if (i == 0)
					error(ENOENT, "file does not exist");
				break;
			}
			/* Need to hold a kref on 'at' before we rcu_read_unlock().  Our
			 * TFS op might block. */
			if (!tf_kref_get(at)) {
				if (i == 0)
					error(ENOENT, "file was removed during lookup");
				/* WQ has a qid for 'at' from a previous loop, but since we
				 * can't walk to it, we should unwind it. */
				wq->nqid--;
				break;
			}
			rcu_read_unlock();
			/* propagate the error only on the first name.  Note we run the
			 * 'else' case, and run the poperror case for non-errors and
			 * non-name=0-errors. */
			if (waserror()) {
				if (i == 0) {
					tf_kref_put(at);
					nexterror();
				}
			} else {
				/* This returns with an rcu_read_lock protecting 'next' */
				next = lookup_child_entry(at, name[i]);
			}
			tf_kref_put(at);
			poperror();
			assert(next);
		}
		if (tree_file_is_negative(next)) {
			/* lockless peek.  other flag users aren't atomic, etc. */
			if (!(next->flags & TF_F_HAS_BEEN_USED)) {
				spin_lock(&next->lifetime);
				next->flags |= TF_F_HAS_BEEN_USED;
				spin_unlock(&next->lifetime);
			}
			if (i == 0)
				error(ENOENT, "file does not exist");
			break;
		}
		at = next;
		wq->qid[wq->nqid++] = tree_file_to_qid(at);
	}
	if (wq->nqid == nname || tree_file_is_symlink(at)) {
		if (!tf_kref_get(at)) {
			/* We need to undo our last result as if we never saw it. */
			wq->nqid--;
			if (wq->nqid == 0)
				error(ENOENT, "file was removed during lookup");
		} else {
			/* Hanging the refcounted TF off the wq->clone, which is cheating.
			 * Our walker shim knows to expect this. */
			wq->clone = (struct chan*)at;
		}
	}
	rcu_read_unlock();
	poperror();
	return wq;
}

/* Most tree devices will use this for their walk op, similar to devwalk. */
struct walkqid *tree_chan_walk(struct chan *c, struct chan *nc, char **name,
                               unsigned int nname)
{
	struct tree_file *from, *to;
	struct walkqid *wq;

	from = chan_to_tree_file(c);
	wq = tree_file_walk(from, name, nname);
	if (!wq)
		return NULL;
	if (!wq->clone)
		return wq;
	if (!nc)
		nc = devclone(c);
	/* Not sure if callers that specify nc must have a chan from our device */
	assert(nc->type == c->type);
	to = (struct tree_file*)wq->clone;
	nc->qid = tree_file_to_qid(to);
	chan_set_tree_file(nc, to);
	wq->clone = nc;
	/* We might be returning the same chan, so there's actually just one ref */
	if (wq->clone == c)
		tf_kref_put(chan_to_tree_file(c));
	return wq;
}

/* Creates a tree file under parent with name, omode, and perm.  Returns a
 * kreffed tree_file for the new child.  Throws on error. */
struct tree_file *tree_file_create(struct tree_file *parent, const char *name,
                                   uint32_t perm, char *ext)
{
	ERRSTACK(2);
	struct tree_file *child;
	bool got_ref;
	struct timespec now;

	qlock(&parent->file.qlock);
	if (waserror()) {
		qunlock(&parent->file.qlock);
		nexterror();
	}
	if (!caller_has_tf_perms(parent, O_WRITE))
		error(EACCES, "missing create permission on dir");
	child = wc_lookup_child(parent, name);
	if (child) {
		/* The create(5) message fails if the file exists, which differs from
		 * the syscall.  namec() handles this. */
		if (!tree_file_is_negative(child))
			error(EEXIST, "file exists");
		/* future lookups that find no entry will qlock.  concurrent ones that
		 * see the child, even if disconnected, will see it was negative and
		 * fail. */
		__disconnect_child(parent, child);
	}
	child = tree_file_alloc(parent->tfs, parent, name);
	if (waserror()) {
		__tf_free(child);
		nexterror();
	}
	/* Backend will need to know the ext for its create.  This gets cleaned up
	 * on error. */
	if (perm & DMSYMLINK)
		kstrdup(&child->file.dir.ext, ext);
	/* Backend will need to fill in dir, except for name. */
	parent->tfs->tf_ops.create(parent, child, perm);
	now = nsec2timespec(epoch_nsec());
	__set_acmtime_to(&child->file,
	                 FSF_ATIME | FSF_BTIME | FSF_CTIME | FSF_MTIME, &now);
	poperror();
	/* At this point, the child is visible, so it must be ready to go */
	__link_child(parent, child);
	got_ref = tf_kref_get(child);
	assert(got_ref);	/* we hold the qlock, no one should have removed */
	__set_acmtime_to(&parent->file, FSF_CTIME | FSF_MTIME, &now);
	qunlock(&parent->file.qlock);
	poperror();
	return child;
}

/* Most tree devices will use this for their create op. */
void tree_chan_create(struct chan *c, char *name, int omode, uint32_t perm,
                      char *ext)
{
	struct tree_file *parent, *child;

	parent = chan_to_tree_file(c);
	child = tree_file_create(parent, name, perm, ext);
	c->qid = tree_file_to_qid(child);
	c->mode = openmode(omode);
	chan_set_tree_file(c, child);
	tf_kref_put(parent);
}

struct chan *tree_chan_open(struct chan *c, int omode)
{
	struct tree_file *tf = chan_to_tree_file(c);

	if ((c->qid.type & QTDIR) && (omode & O_WRITE))
		error(EISDIR, "can't open a dir for writing");
	if (c->qid.type & QTSYMLINK)
		error(ELOOP, "can't open a symlink");
	tree_file_perm_check(tf, omode);
	/* TODO: if we want to support DMEXCL on dir.mode, we'll need to lock/sync
	 * on the fs_file (have a flag for FSF_IS_OPEN, handle in close).  We'll
	 * also need a way to pass it in to the dir.mode during create/wstat/etc. */
	if (omode & O_TRUNC)
		fs_file_truncate(&tf->file, 0);
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

void tree_chan_close(struct chan *c)
{
	struct tree_file *tf = chan_to_tree_file(c);

	tf_kref_put(tf);
}

void tree_file_remove(struct tree_file *child)
{
	ERRSTACK(1);
	struct tree_file *parent;

	parent = get_locked_and_kreffed_parent(child);
	if (!parent)
		error(ENOENT, "%s had no parent", tree_file_to_name(child));
	if (waserror()) {
		qunlock(&parent->file.qlock);
		tf_kref_put(parent);
		nexterror();
	}
	if (!caller_has_tf_perms(parent, O_WRITE))
		error(EACCES, "missing remove perm for dir");
	__unlink_child(parent, child);
	__set_acmtime(&parent->file, FSF_CTIME | FSF_MTIME);
	poperror();
	qunlock(&parent->file.qlock);
	tf_kref_put(parent);
}

void tree_chan_remove(struct chan *c)
{
	ERRSTACK(1);
	struct tree_file *tf = chan_to_tree_file(c);

	/* sysremove expects a chan that is disconnected from the device, regardless
	 * of whether or not we fail.  See sysremove(); it will clear type, ensuring
	 * our close is never called. */
	if (waserror()) {
		chan_set_tree_file(c, NULL);
		tf_kref_put(tf);	/* The ref from the original walk */
		nexterror();
	}
	tree_file_remove(tf);
	chan_set_tree_file(c, NULL);
	tf_kref_put(tf);	/* The ref from the original walk */
	poperror();
}

static bool is_descendant_of(struct tree_file *descendant,
                             struct tree_file *ancestor)
{
	if (!tree_file_is_dir(ancestor))
		return false;
	rcu_read_lock();
	for (struct tree_file *i = rcu_dereference(descendant->parent);
	     i;
	     i = rcu_dereference(i->parent)) {
		if (i == ancestor) {
			rcu_read_unlock();
			return true;
		}
	}
	rcu_read_unlock();
	return false;
}

/* Caller should hold the rename mutex.  This qlocks a and b, which can be the
 * same file, and this handles lock ordering.  Recall the rule: parents before
 * children, and otherwise only the renamer can lock. */
static void qlock_tree_files(struct tree_file *a, struct tree_file *b)
{
	if (a == b) {
		qlock(&a->file.qlock);
		return;
	}
	if (is_descendant_of(a, b)) {
		qlock(&b->file.qlock);
		qlock(&a->file.qlock);
	} else {
		qlock(&a->file.qlock);
		qlock(&b->file.qlock);
	}
}

static void qunlock_tree_files(struct tree_file *a, struct tree_file *b)
{
	if (a != b)
		qunlock(&a->file.qlock);
	qunlock(&b->file.qlock);
}

/* Higher layers (namec) ensure that tf and new_parent are in the same device.
 * The device (e.g. #mnt) ensures that they are in the same instance.
 * new_parent could be the parent of tf; everything should still work if the
 * move is within the same directory. */
void tree_file_rename(struct tree_file *tf, struct tree_file *new_parent,
                      const char *name, int flags)
{
	ERRSTACK(1);
	struct tree_file *old_parent;
	struct tree_file *prev_dst;
	struct timespec now;

	old_parent = __tf_get_potential_parent(tf);
	if (!old_parent)
		error(ENOENT, "renamed file had no parent");
	/* global mtx helps with a variety of weird races, including the "can't move
	 * to a subdirectory of yourself" case and the lock ordering of parents
	 * (locks flow from parent->child). */
	qlock(&tf->tfs->rename_mtx);
	qlock_tree_files(old_parent, new_parent);
	if (waserror()) {
		qunlock_tree_files(old_parent, new_parent);
		qunlock(&tf->tfs->rename_mtx);
		tf_kref_put(old_parent);
		nexterror();
	};
	if (old_parent != tf->parent)
		error(ENOENT, "renamed file lost its parent");
	/* Probably a namec bug (that code isn't written yet). */
	assert(tree_file_is_dir(new_parent));
	if (!new_parent->can_have_children)
		error(ENOENT, "target dir being removed");
	if (!caller_has_tf_perms(old_parent, O_WRITE))
		error(EACCES, "missing remove perm for src dir");
	if (!caller_has_tf_perms(new_parent, O_WRITE))
		error(EACCES, "missing create perm for dst dir");
	/* can't move tf to one of its subdirs */
	if (is_descendant_of(new_parent, tf))
		error(EINVAL, "can't rename to a child directory");
	/* We hold new_parent's qlock, so there's no worry about prev_dst
	 * disappearing, so no need for an rcu read lock. */
	prev_dst = wc_lookup_child(new_parent, name);
	if (prev_dst) {
		if (tree_file_is_dir(prev_dst)) {
			if (!tree_file_is_dir(tf))
				error(EISDIR, "can't rename a file onto a dir");
			/* We need to ensure prev_dst is childless and remains so.  That
			 * requires grabbing its qlock, but there's a potential lock
			 * ordering issue with old_parent.  We could have this:
			 * new_parent/dst/x/y/z/old_parent/src.  That will fail, but we need
			 * to check for that case instead of grabbing prev_dst's qlock. */
			if (is_descendant_of(prev_dst, old_parent))
				error(ENOTEMPTY, "old_parent descends from dst");
			neuter_directory(prev_dst);
		} else {
			if (tree_file_is_dir(tf))
				error(ENOTDIR, "can't rename a dir onto a file");
		}
	}
	/* We check with the backend first, so that it has a chance to fail early.
	 * Once we make the changes to the front end, lookups can see the effects of
	 * the change, which we can't roll back.  Since we hold the parents' qlocks,
	 * no one should be able to get the info from the backend either (lookups
	 * that require the backend, readdir, etc). */
	tf->tfs->tf_ops.rename(tf, old_parent, new_parent, name, flags);
	/* Similar to __disconnect_child, we don't clear tf->parent.  rcu readers at
	 * TF will be able to walk up (with ..).  Same with namec_from an FD.  If we
	 * atomically replace tf->parent, we should be good.  See tree_file_walk().
	 *
	 * Further, we don't mark the tf disconnected.  Someone might lookup from
	 * the old location, and that's fine.  We just don't want issues with
	 * decrefs. */
	__remove_from_parent_list(old_parent, tf);
	wc_remove_child(old_parent, tf);
	synchronize_rcu();
	/* Now, no new lookups will find it at the old location.  That change is not
	 * atomic wrt src, but it will be wrt dst.  Importantly, no one will see
	 * /path/to/old_parent/new_basename */
	fs_file_change_basename((struct fs_file*)tf, name);
	/* We're clobbering the old_parent ref, which we'll drop later */
	rcu_assign_pointer(tf->parent, new_parent);
	kref_get(&new_parent->kref, 1);
	__add_to_parent_list(new_parent, tf);
	wc_insert_child(new_parent, tf);
	/* Now both the prev_dst (if it existed) or the tf file are in the walk
	 * cache / HT and either could have been looked up by a concurrent reader.
	 * Readers will always get one or the other, but never see nothing.  This is
	 * the atomic guarantee of rename. */
	if (prev_dst) {
		__remove_from_parent_list(new_parent, prev_dst);
		wc_remove_child(new_parent, prev_dst);
		synchronize_rcu();
		/* Now no one can find prev_dst.  Someone might still have a ref, or it
		 * might be on the LRU list (if kref == 0).  Now we can mark
		 * disconnected.  Had we disconnected earlier, then lookup code would
		 * see that and treat it as a failure.  Using rcu and putting the
		 * complexity in rename was easier and simpler than changing lookup.
		 *
		 * We still need RCU here for freeing the prev_dst.  We could have had
		 * an LRU pruner, etc, looking.  The synchronize_rcu above only dealt
		 * with lookups via parent in this function. */
		if (__mark_disconnected(prev_dst))
			call_rcu(&prev_dst->rcu, __tf_free_rcu);
	}
	now = nsec2timespec(epoch_nsec());
	__set_acmtime_to(&old_parent->file, FSF_CTIME | FSF_MTIME, &now);
	__set_acmtime_to(&new_parent->file, FSF_CTIME | FSF_MTIME, &now);
	/* Can we unlock earlier?  No.  We need to at least hold new_parent's qlock,
	 * which was the parent of old_dst, until old_dst is marked disconnected.
	 * Even though old_dst is removed from new_parent's HT, it is still in the
	 * LRU list. */
	qunlock_tree_files(old_parent, new_parent);
	qunlock(&tf->tfs->rename_mtx);
	poperror();
	tf_kref_put(old_parent);	/* the original tf->parent ref we clobbered */
	tf_kref_put(old_parent);	/* the one we grabbed when we started */
}

void tree_chan_rename(struct chan *c, struct chan *new_p_c, const char *name,
                      int flags)
{
	struct tree_file *tf = chan_to_tree_file(c);
	struct tree_file *new_parent = chan_to_tree_file(new_p_c);

	tree_file_rename(tf, new_parent, name, flags);
}

/* dri is a pointer to the chan->dri, which is a count of how many directory
 * entries that have been read from this chan so far.  9ns handles it; we just
 * need to increment it for every successful entry.  Note we ignore offset. */
ssize_t tree_file_readdir(struct tree_file *parent, void *ubuf, size_t n,
                          off64_t offset, int *dri)
{
	ERRSTACK(1);
	struct tree_file *i;
	size_t dir_amt, so_far = 0;
	uint8_t *write_pos = ubuf;
	int child_nr = 0;

	qlock(&parent->file.qlock);
	if (waserror()) {
		qunlock(&parent->file.qlock);
		nexterror();
	}
	list_for_each_entry(i, &parent->children, siblings) {
		if (child_nr++ < *dri)
			continue;
		qlock(&i->file.qlock);
		dir_amt = convD2M(&i->file.dir, write_pos, n - so_far);
		qunlock(&i->file.qlock);
		if (dir_amt <= BIT16SZ) {
			if (!so_far)
				error(EINVAL, "buffer to small for readdir");
			break;
		}
		write_pos += dir_amt;
		so_far += dir_amt;
		assert(n - so_far >= 0);
		(*dri)++;
	}
	/* If we care about directory atime, we can do that here. (if so_far) */
	qunlock(&parent->file.qlock);
	poperror();
	return so_far;
}

/* Note this only works for backend-less TFSs.  It calls tree_file_readdir,
 * which only looks at the frontend's tree. */
size_t tree_chan_read(struct chan *c, void *ubuf, size_t n, off64_t offset)
{
	struct tree_file *tf = chan_to_tree_file(c);

	if (tree_file_is_dir(tf))
		return tree_file_readdir(tf, ubuf, n, offset, &c->dri);
	return fs_file_read(&tf->file, ubuf, n, offset);
}

size_t tree_chan_write(struct chan *c, void *ubuf, size_t n, off64_t offset)
{
	struct tree_file *tf = chan_to_tree_file(c);

	/* sysfile.c:rwrite checked the chan's type. */
	assert(!tree_file_is_dir(tf));
	return fs_file_write(&tf->file, ubuf, n, offset);
}

size_t tree_chan_stat(struct chan *c, uint8_t *m_buf, size_t m_buf_sz)
{
	struct tree_file *tf = chan_to_tree_file(c);

	return fs_file_stat(&tf->file, m_buf, m_buf_sz);
}

size_t tree_chan_wstat(struct chan *c, uint8_t *m_buf, size_t m_buf_sz)
{
	struct tree_file *tf = chan_to_tree_file(c);

	return fs_file_wstat(&tf->file, m_buf, m_buf_sz);
}

struct fs_file *tree_chan_mmap(struct chan *c, struct vm_region *vmr, int prot,
                               int flags)
{
	struct fs_file *f = &chan_to_tree_file(c)->file;

	/* TODO: In the future, we'll check the prot, establish hooks with the VMR,
	 * and other things, mostly in something like fs_file_mmap, which will be
	 * able to handle mmaping something that doesn't use the page cache.  For
	 * now, I'm aggressively qlocking to catch bugs. */
	qlock(&f->qlock);
	if ((prot & PROT_WRITE) && (flags & MAP_SHARED))
		f->flags |= FSF_DIRTY;
	qunlock(&f->qlock);
	return f;
}

/* Given a tree file, construct a chan that points to the TF for the given
 * device.  Careful with this - it's for bootstrapping. */
struct chan *tree_file_alloc_chan(struct tree_file *tf, struct dev *dev,
                                  char *name)
{
	struct chan *c;

	c = newchan();
	c->type = dev - devtab;
	c->name = newcname(name);
	kref_get(&tf->kref, 1);
	chan_set_tree_file(c, tf);
	c->qid = tree_file_to_qid(tf);
	return c;
}

/* Caller needs to set its customizable fields: tf_ops, pm_ops, etc.  root is
 * created with a ref of 1, but needs filled in by the particular TFS. */
void tfs_init(struct tree_filesystem *tfs)
{
	wc_init(&tfs->wc);
	qlock_init(&tfs->rename_mtx);
	tfs->root = tree_file_alloc(tfs, NULL, ".");
	tfs->root->flags |= TF_F_IS_ROOT;
	assert(!(tfs->root->flags & TF_F_ON_LRU));
	__kref_get(&tfs->root->kref, 1);
}

void tfs_destroy(struct tree_filesystem *tfs)
{
	tfs->root = NULL;	/* was just freed in __tf_free() */
	wc_destroy(&tfs->wc);
}

/* For every file except root, we hold our parent's qlock (root has no parent).
 * This prevents TF's removal/rename and any changes to tf->parent. */
static void tf_dfs_cb(struct tree_file *tf, void (*cb)(struct tree_file *tf))
{
	struct tree_file *child;

	if (tree_file_is_dir(tf)) {
		qlock(&tf->file.qlock);
		/* Note we don't have a kref on our child's TF - we have a weak
		 * reference (the list membership).  We hold the parent's qlock, which
		 * prevents removal/unlinking/disconnecting/etc.  The child's membership
		 * on the LRU list can change repeatedly.
		 *
		 * If we want to avoid holding the parent's qlock, we could grab a kref
		 * on the child.  However, our list walk would be in jeopardy - both
		 * child and temp could be removed from the list.  So we'd need to qlock
		 * the parent, grab krefs on all children, and put them on a local list.
		 * Also, grabbing krefs on our children will muck with the LRU list;
		 * when we're done, it would be like we sorted the LRU list in the DFS
		 * order. */
		list_for_each_entry(child, &tf->children, siblings)
			tf_dfs_cb(child, cb);
		qunlock(&tf->file.qlock);
	}
	if (!tree_file_is_negative(tf))
		cb(tf);
}

/* Runs CB on all in-memory, non-negative TFs from the TFS in a depth-first
 * search.  Compared to the other CB walkers (purge, LRU, etc), this never
 * removes/prunes/disconnects a TF from the tree.  You can use it for syncing FS
 * trees or pruning page maps (i.e. discarding non-dirty pages).
 *
 * One thing to note is that it qlocks the tree as part of its DFS.  We can
 * change that, but at a slight cost in complexity and tampering with the LRU
 * list.  Translation: we can do it if there's a performance problem.
 *
 * The tfs->root reference is also weak.  It's up to the user to make sure
 * there is no concurrent tfs_destroy.  Typically, if we're called on any
 * mounted device, we're fine (e.g. #tmpfs) or a device that is never destroyed
 * (e.g. #kfs). */
void tfs_frontend_for_each(struct tree_filesystem *tfs,
                           void (*cb)(struct tree_file *tf))
{
	tf_dfs_cb(tfs->root, cb);
}

/* We should be single-user, so no need for concurrency protections.  I keep
 * them around for paranoia/future use/documentation. */
static void tf_dfs_purge(struct tree_file *tf, void (*cb)(struct tree_file *tf))
{
	struct tree_file *child, *temp;

	if (tree_file_is_dir(tf)) {
		qlock(&tf->file.qlock);
		/* Note we don't have a kref on TF, and one of our children should
		 * decref *us* to 0.  We aren't disconnected yet, and we can't be
		 * removed (parent's qlock is held), so we'll just end up on the LRU
		 * list, which is OK.
		 *
		 * Our child should remove itself from our list, so we need the _safe.
		 *
		 * Also note that the child decrefs us in a call_rcu.  CB can block, and
		 * technically so can qlock, so we might run RCU callbacks while
		 * qlocked.  We'll need to rcu_barrier so that our children's decrefs
		 * occur before we remove ourselves from our parent. */
		list_for_each_entry_safe(child, temp, &tf->children, siblings)
			tf_dfs_purge(child, cb);
		qunlock(&tf->file.qlock);
	}
	rcu_barrier();
	/* ramfs will drop the "+1 for existing" ref here */
	if (!tree_file_is_negative(tf))
		cb(tf);
	spin_lock(&tf->lifetime);
	/* should be unused, with no children.  we have a ref on root, to keep the
	 * TFS around while we destroy the tree. */
	assert(kref_refcnt(&tf->kref) == 0 || tree_file_is_root(tf));
	/* This mark prevents new lookups.  We'll disconnect it shortly. */
	tf->flags |= TF_F_DISCONNECTED;
	spin_unlock(&tf->lifetime);
	if (tf->parent)
		__disconnect_child(tf->parent, tf);
}

/* Purges all in-memory TFs from the TFS in a depth-first search, both positive
 * and negative.  We run CB on all non-negative TFs.  It's up to the caller to
 * ensure there is no concurrency.
 *
 * The caller must make sure they have an extra ref on tfs->root to keep the
 * TFS around while it gets destroyed.  The root TF will get freed when it is
 * released, unlike other TFs that are still connected.
 *
 * This is for devices that want to destroy themselves, such as an unmounted
 * #tmpfs or #gtfs/#mnt, that want to do some extra work (e.g. sync).
 * Typically, those devices will call this after they have no users (e.g. mounts
 * or open chans). */
void tfs_frontend_purge(struct tree_filesystem *tfs,
                        void (*cb)(struct tree_file *tf))
{
	assert(kref_refcnt(&tfs->root->kref) > 0);
	tf_dfs_purge(tfs->root, cb);
}

static void print_tf(struct tree_file *tf)
{
	if (tree_file_is_negative(tf)) {
		printk("%-10s: Negative\n", tree_file_to_name(tf));
		return;
	}
	printk("%-10s: Q: %5d, R: %2d, U %s, %c%o %s\n",
		   tree_file_to_name(tf),
		   tf->file.dir.qid.path,
		   kref_refcnt(&tf->kref),
		   tf->file.dir.uid,
		   tree_file_is_dir(tf) ? 'd' :
								tf->file.dir.mode & DMSYMLINK ? 'l' : '-',
		   tf->file.dir.mode & S_PMASK,
		   tf->file.dir.mode & DMSYMLINK ? tf->file.dir.ext : ""
		   );
}

static void dump_tf(struct tree_file *tf, int tabs)
{
	struct tree_file *child;

	if (!!(tf->file.dir.mode & DMSYMLINK) !=
	    !!(tf->file.dir.qid.type & QTSYMLINK))
		warn("%s has differing symlink bits", tree_file_to_name(tf));

	for (int i = 0; i < tabs; i++)
		printk("    ");
	print_tf(tf);
	if (tree_file_is_dir(tf)) {
		for (int i = 0; i < tabs; i++)
			printk("    ");
		printk("---------------------\n");
		list_for_each_entry(child, &tf->children, siblings)
			dump_tf(child, tabs + 1);
	}
}

void __tfs_dump(struct tree_filesystem *tfs)
{
	dump_tf(tfs->root, 0);
}

/* Runs a callback on every non-negative TF on the LRU list, for a given
 * snapshot of the LRU list.  The CB returns true if it wants us to attempt to
 * free the TF.  One invariant is that we can never remove a TF from the tree
 * while it is dirty; it is the job of the CB to maintain that.  Note the CB can
 * run on a TF as soon as that TF was linked to the parent (see lookup).
 *
 * The work list is a list of strong refs.  We need to keep one in case the file
 * is disconnected while we're running our CBs.  Since we incref, we yank from
 * the LRU list.  We could design the rest of the TF code so that we stay on the
 * LRU list throughout, but I like the invariant of "kref == 0 IFF on LRU".
 *
 * Since we're only on one list at a time ('wc->lru' or 'work'), we can use the
 * lru list_head in the TF.  We know that so long as we hold our kref on a TF,
 * no one will attempt to put it back on the LRU list. */
void tfs_lru_for_each(struct tree_filesystem *tfs, bool cb(struct tree_file *),
                      size_t max_tfs)
{
	struct list_head work = LIST_HEAD_INIT(work);
	struct walk_cache *wc = &tfs->wc;
	struct tree_file *tf, *temp, *parent;
	size_t nr_tfs = 0;

	/* We can have multiple LRU workers in flight, though a given TF will be on
	 * only one CB list at a time. */
	spin_lock(&wc->lru_lock);
	list_for_each_entry_safe(tf, temp, &wc->lru, lru) {
		/* lockless peak at the flag.  once it's NEGATIVE, it never goes back */
		if (tree_file_is_negative(tf))
			continue;
		/* Normal lock order is TF -> LRU.  Best effort is fine for LRU. */
		if (!spin_trylock(&tf->lifetime))
			continue;
		/* Can't be disconnected and on LRU */
		assert(!(tf->flags & TF_F_DISCONNECTED));
		assert((tf->flags & TF_F_ON_LRU));
		tf->flags &= ~TF_F_ON_LRU;
		list_del(&tf->lru);
		__kref_get(&tf->kref, 1);
		/* The 'used' bit is the what allows us to detect a user in between our
		 * callback and the disconnection/freeing.  It's a moot point if the CB
		 * returns false. */
		tf->flags &= ~TF_F_HAS_BEEN_USED;
		spin_unlock(&tf->lifetime);
		list_add_tail(&tf->lru, &work);
		if (++nr_tfs >= max_tfs)
			break;
	}
	spin_unlock(&wc->lru_lock);

	/* We have a snapshot of the LRU list.  As soon as we unlocked a file,
	 * someone could incref it (e.g. to something > 1), and they'll set the used
	 * bit.  That won't abort the CB.  New TFs could be added to the LRU list.
	 * Those are ignored for this pass. */
	list_for_each_entry_safe(tf, temp, &work, lru) {
		if (!cb(tf)) {
			list_del(&tf->lru);
			tf_kref_put(tf);
			continue;
		}
	}

	/* Now we have a list of victims to be removed, so long as they haven't been
	 * used since. */
	list_for_each_entry_safe(tf, temp, &work, lru) {
		parent = get_locked_and_kreffed_parent(tf);
		if (!parent) {
			list_del(&tf->lru);
			tf_kref_put(tf);
			continue;
		}
		spin_lock(&tf->lifetime);
		if (tf->flags & TF_F_HAS_BEEN_USED) {
			spin_unlock(&tf->lifetime);
			qunlock(&parent->file.qlock);
			tf_kref_put(parent);
			list_del(&tf->lru);
			tf_kref_put(tf);
			continue;
		}
		tf->flags |= TF_F_DISCONNECTED;
		/* We hold a ref, so it shouldn't have found its way back on LRU */
		assert(!(tf->flags & TF_F_ON_LRU));
		spin_unlock(&tf->lifetime);
		__remove_from_parent_list(parent, tf);
		wc_remove_child(parent, tf);
		/* If we get tired of unlocking and relocking, we could see if the next
		 * parent is the current parent before unlocking. */
		qunlock(&parent->file.qlock);
		tf_kref_put(parent);
	}
	/* Now we have a list of refs that are all disconnected, kref == 1 (because
	 * no one used them since we increffed them when they were LRU, which was
	 * when the refcnt was 0).  Each TF has a ref on its parent btw, so parents
	 * will never be on the LRU list.  (leaves only).
	 *
	 * We need to synchronize_rcu() too, since we could have had lockless
	 * lookups that have pointers to TF and are waiting to notice that it is
	 * disconnected. */
	synchronize_rcu();
	list_for_each_entry_safe(tf, temp, &work, lru) {
		assert(kref_refcnt(&tf->kref) == 1);
		list_del(&tf->lru);
		/* We could decref, but instead we can directly free.  We know the ref
		 * == 1 and it is disconnected.  Directly freeing bypasses call_rcu. */
		__tf_free(tf);
	}
}

/* Does a one-cycle 'clock' algorithm to detect use.  On a given pass, we either
 * clear HAS_BEEN_USED xor we remove it.  For negative entries, that bit is used
 * when we look at an entry (use it), compared to positive entries, which is
 * used when we get a reference.  (we never get refs on negatives). */
void tfs_lru_prune_neg(struct tree_filesystem *tfs)
{
	struct list_head work = LIST_HEAD_INIT(work);
	struct walk_cache *wc = &tfs->wc;
	struct tree_file *tf, *temp, *parent;

	spin_lock(&wc->lru_lock);
	list_for_each_entry_safe(tf, temp, &wc->lru, lru) {
		if (!tree_file_is_negative(tf))
			continue;
		if (!spin_trylock(&tf->lifetime))
			continue;
		if (tf->flags & TF_F_HAS_BEEN_USED) {
			tf->flags &= ~TF_F_HAS_BEEN_USED;
			spin_unlock(&tf->lifetime);
			continue;
		}
		rcu_read_lock();	/* holding a spinlock, but just to be clear. */
		parent = rcu_dereference(tf->parent);
		/* Again, inverting the lock order, so best effort trylock */
		if (!canqlock(&parent->file.qlock)) {
			rcu_read_unlock();
			spin_unlock(&tf->lifetime);
			continue;
		}
		__remove_from_parent_list(parent, tf);
		wc_remove_child(parent, tf);
		qunlock(&parent->file.qlock);
		/* We're off the list, but our kref == 0 still.  We can break that
		 * invariant since we have the only ref and are about to free the TF. */
		tf->flags &= ~TF_F_ON_LRU;
		list_del(&tf->lru);
		spin_unlock(&tf->lifetime);
		list_add_tail(&tf->lru, &work);
	}
	spin_unlock(&wc->lru_lock);
	/* Now we have a list of refs that are all unlinked (but actually not
	 * flagged DISCONNECTED; that's only necessary for positives), kref == 0
	 * (because they are negatives).
	 *
	 * We need to synchronize_rcu() too, since we could have had lockless
	 * lookups that have pointers to TF, and they may even mark HAS_BEEN_USED.
	 * Too late. */
	synchronize_rcu();
	list_for_each_entry_safe(tf, temp, &work, lru) {
		assert(kref_refcnt(&tf->kref) == 0);
		list_del(&tf->lru);
		__tf_free(tf);
	}
}
