/* Copyright (c) 2018 Google Inc
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * #gtfs, generic tree file system frontend that hooks to a backend 9p device
 */

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <pmap.h>
#include <smp.h>
#include <tree_file.h>

struct dev gtfs_devtab;

static char *devname(void)
{
	return gtfs_devtab.name;
}

struct gtfs {
	struct tree_filesystem		tfs;
	struct kref					users;
};

// XXX
static struct gtfs *recent;

/* Blob hanging off the fs_file->priv.  The backend chans are only accessed,
 * (changed or used) with the corresponding fs_file qlock held.  That's the
 * primary use of the qlock - we might be able to avoid qlocking with increfs
 * and atomics or spinlocks, but be careful of be_length.  Qlocking doesn't
 * matter much yet since #mnt serializes.
 *
 * The walk chan is never opened - it's basically just the walked fid, from
 * which we can do other walks or get the I/O chans.  The read and write chans
 * are opened on demand and closed periodically.  We open them initially on
 * open/create in case we are unable to open them (e.g. unwritable).  Better to
 * find out early than during a long writeback.
 *
 * The mnt server might complain about having too many open fids.  We can run a
 * ktask that periodically closes the be_chans on any LRU'd files.
 *
 * be_{length,mode,mtime} should be what the remote server thinks they are -
 * especially for length and mode.  The invariant is that e.g. the file's length
 * == be_length, and the qlock protects that invariant.  We don't care as much
 * about mtime, since some 9p servers just change that on their own.
 *
 * Also note that you can't trust be_length for directories.  You'll often get
 * 4096 or 0, depending on the 9p server you're talking to. */
struct gtfs_priv {
	struct chan					*be_walk;	/* never opened */
	struct chan					*be_read;
	struct chan					*be_write;
	uint64_t					be_length;
	uint32_t					be_mode;
	struct timespec				be_mtime;
	bool						was_removed;
};

static inline struct gtfs_priv *fsf_to_gtfs_priv(struct fs_file *f)
{
	return f->priv;
}

static inline struct gtfs_priv *tf_to_gtfs_priv(struct tree_file *tf)
{
	return fsf_to_gtfs_priv(&tf->file);
}

/* Helper.  Clones the chan (walks to itself) and then opens with omode. */
static struct chan *cclone_and_open(struct chan *c, int omode)
{
	ERRSTACK(1);
	struct chan *new;

	new = cclone(c);
	if (waserror()) {
		cclose(new);
		nexterror();
	}
	new = devtab[new->type].open(new, omode);
	poperror();
	return new;
}

/* Send a wstat with the contents of dir for the file. */
static void wstat_dir(struct fs_file *f, struct dir *dir)
{
	ERRSTACK(1);
	struct gtfs_priv *gp = fsf_to_gtfs_priv(f);
	size_t sz;
	uint8_t *buf;

	sz = sizeD2M(dir);
	buf = kzmalloc(sz, MEM_WAIT);
	convD2M(dir, buf, sz);
	if (waserror()) {
		kfree(buf);
		nexterror();
	}
	devtab[gp->be_walk->type].wstat(gp->be_walk, buf, sz);
	kfree(buf);
	poperror();
}

/* Note we only track and thus change the following:
 * - length
 * - mode
 * - mtime (second granularity)
 * If we support chown, we'll have to do something else there.  See
 * fs_file_copy_from_dir(). */
static void sync_metadata(struct fs_file *f)
{
	ERRSTACK(1);
	struct gtfs_priv *gp = fsf_to_gtfs_priv(f);
	struct dir dir;
	bool send_it = false;

	qlock(&f->qlock);
	init_empty_dir(&dir);
	if (f->dir.length != gp->be_length) {
		dir.length = f->dir.length;
		send_it = true;
	}
	if (f->dir.mode != gp->be_mode) {
		dir.mode = f->dir.mode;
		send_it = true;
	}
	if (f->dir.mtime.tv_sec != gp->be_mtime.tv_sec) {
		/* ninep's UFS server assumes you set both atime and mtime */
		dir.atime.tv_sec = f->dir.atime.tv_sec;
		dir.atime.tv_nsec = f->dir.atime.tv_nsec;
		dir.mtime.tv_sec = f->dir.mtime.tv_sec;
		dir.mtime.tv_nsec = f->dir.mtime.tv_nsec;
		send_it = true;
	}
	if (!send_it) {
		qunlock(&f->qlock);
		return;
	}
	if (waserror()) {
		qunlock(&f->qlock);
		nexterror();
	}
	wstat_dir(f, &dir);
	/* We set these after the wstat succeeds.  If we set them earlier, we'd have
	 * to roll back.  Remember the invariant: the be_values match the backend's
	 * file's values.  We should be able to stat be_walk and check these (though
	 * the 9p server might muck with atime/mtime). */
	if (f->dir.length != gp->be_length)
		gp->be_length = f->dir.length;
	if (f->dir.mode != gp->be_mode)
		gp->be_mode = f->dir.mode;
	if (f->dir.mtime.tv_sec != gp->be_mtime.tv_sec)
		gp->be_mtime = f->dir.mtime;
	qunlock(&f->qlock);
	poperror();
}

/* Can throw on error, currently from sync_metadata. */
static void writeback_file(struct fs_file *f)
{
	sync_metadata(f);
	/* This is a lockless peak.  Once a file is dirtied, we never undirty it.
	 * To do so, we need the file qlock (not a big deal, though that may replace
	 * the PM qlock), and we still need to handle/scan mmaps.  Specifically, we
	 * only dirty when an mmap attaches (PROT_WRITE and MAP_SHARED), but we
	 * don't know if an existing mapping has caused more dirtying (an mmap can
	 * re-dirty then detach before our next writeback).  That usually requires a
	 * scan.  This is all an optimization to avoid scanning the entire PM's
	 * pages for whether or not they are dirty.
	 *
	 * Also, our writeback pm op grabs the file's qlock.  So be careful; though
	 * we could use another qlock, since we're mostly protecting backend state.
	 */
	if (qid_is_file(f->dir.qid) && (f->flags & FSF_DIRTY))
		pm_writeback_pages(f->pm);
}

static void purge_cb(struct tree_file *tf)
{
	ERRSTACK(1)

	/* discard error, and keep on going if we can. */
	if (!waserror())
		writeback_file(&tf->file);
	poperror();
}

static void __gtfs_destroy(uint32_t srcid, long a0, long a1, long a2)
{
	struct gtfs *gtfs = (struct gtfs*)a0;

	tfs_frontend_purge(&gtfs->tfs, purge_cb);
	/* this is the ref from attach */
	assert(kref_refcnt(&gtfs->tfs.root->kref) == 1);
	tf_kref_put(gtfs->tfs.root);
	/* ensures __tf_free() happens before tfs_destroy */
	rcu_barrier();
	tfs_destroy(&gtfs->tfs);
	kfree(gtfs);
}

static void gtfs_release(struct kref *kref)
{
	struct gtfs *gtfs = container_of(kref, struct gtfs, users);

	/* We can't use RCU within an RCU callback, and release methods are often
	 * called from within callbacks.  We can use a kernel message, which can
	 * block and do whatever else it wants.  In essence, we break the connection
	 * to our current context (the rcu_mgmt_ktask) by using a kmsg. */
	send_kernel_message(core_id(), __gtfs_destroy, (long)gtfs, 0, 0,
	                    KMSG_ROUTINE);
}

static struct gtfs *chan_to_gtfs(struct chan *c)
{
	struct tree_file *tf = chan_to_tree_file(c);

	return (struct gtfs*)(tf->tfs);
}

static void incref_gtfs_chan(struct chan *c)
{
	kref_get(&chan_to_gtfs(c)->users, 1);
}

static void decref_gtfs_chan(struct chan *c)
{
	kref_put(&chan_to_gtfs(c)->users);
}

static struct walkqid *gtfs_walk(struct chan *c, struct chan *nc, char **name,
                                 unsigned int nname)
{
	struct walkqid *wq;

	wq = tree_chan_walk(c, nc, name, nname);
	if (wq && wq->clone && (wq->clone != c))
		incref_gtfs_chan(wq->clone);
	return wq;
}

/* Given an omode, make sure the be chans are set up */
static void setup_be_chans(struct chan *c, int omode)
{
	ERRSTACK(1);
	struct tree_file *tf = chan_to_tree_file(c);
	struct fs_file *f = &tf->file;
	struct gtfs_priv *gp = fsf_to_gtfs_priv(f);

	qlock(&f->qlock);
	if (waserror()) {
		qunlock(&f->qlock);
		nexterror();
	}
	/* Readers and writers both need be_read.  With fs files you can't have a
	 * writable-only file, since we need to load the page into the page cache,
	 * which is a readpage. */
	if (!gp->be_read)
		gp->be_read = cclone_and_open(gp->be_walk, O_READ);
	if (!gp->be_write && (omode & O_WRITE))
		gp->be_write = cclone_and_open(gp->be_walk, O_WRITE);
	qunlock(&f->qlock);
	poperror();
}

static struct chan *gtfs_open(struct chan *c, int omode)
{
	/* truncate can happen before we setup the be_chans.  if we need those, we
	 * can swap the order */
	c = tree_chan_open(c, omode);
	setup_be_chans(c, omode);
	return c;
}


static void gtfs_create(struct chan *c, char *name, int omode, uint32_t perm,
                        char *ext)
{
	tree_chan_create(c, name, omode, perm, ext);
	/* We have to setup *after* create, since it moves the chan from the parent
	 * to the new file. */
	setup_be_chans(c, omode);
}

static void gtfs_close(struct chan *c)
{
	tree_chan_close(c);
	decref_gtfs_chan(c);
}

static void gtfs_remove(struct chan *c)
{
	ERRSTACK(1);
	struct gtfs *gtfs = chan_to_gtfs(c);

	if (waserror()) {
		/* Same old pain-in-the-ass for remove */
		kref_put(&gtfs->users);
		nexterror();
	}
	tree_chan_remove(c);
	kref_put(&gtfs->users);
	poperror();
}

static size_t gtfs_wstat(struct chan *c, uint8_t *m_buf, size_t m_buf_sz)
{
	size_t ret;

	ret = tree_chan_wstat(c, m_buf, m_buf_sz);
	/* Tell the backend so that any metadata changes take effect immediately.
	 * Consider chmod +w.  We need to tell the 9p server so that it will allow
	 * future accesses. */
	sync_metadata(&chan_to_tree_file(c)->file);
	return ret;
}

/* Caller holds the file's qlock. */
static size_t __gtfs_fsf_read(struct fs_file *f, void *ubuf, size_t n,
                              off64_t off)
{
	struct gtfs_priv *gp = fsf_to_gtfs_priv(f);

	if (!gp->be_read)
		gp->be_read = cclone_and_open(gp->be_walk, O_READ);
	return devtab[gp->be_read->type].read(gp->be_read, ubuf, n, off);
}

/* Reads a file from its backend chan */
static size_t gtfs_fsf_read(struct fs_file *f, void *ubuf, size_t n,
                            off64_t off)
{
	ERRSTACK(1);
	size_t ret;

	qlock(&f->qlock);
	if (waserror()) {
		qunlock(&f->qlock);
		nexterror();
	}
	ret = __gtfs_fsf_read(f, ubuf, n, off);
	qunlock(&f->qlock);
	poperror();
	return ret;
}

/* Caller holds the file's qlock. */
static size_t __gtfs_fsf_write(struct fs_file *f, void *ubuf, size_t n,
                               off64_t off)
{
	struct gtfs_priv *gp = fsf_to_gtfs_priv(f);
	size_t ret;

	if (!gp->be_write)
		gp->be_write = cclone_and_open(gp->be_walk, O_WRITE);
	ret = devtab[gp->be_write->type].write(gp->be_write, ubuf, n, off);
	gp->be_length = MAX(gp->be_length, n + ret);
	return ret;
}

/* Writes a file to its backend chan */
static size_t gtfs_fsf_write(struct fs_file *f, void *ubuf, size_t n,
                             off64_t off)
{
	ERRSTACK(1);
	size_t ret;

	qlock(&f->qlock);
	if (waserror()) {
		qunlock(&f->qlock);
		nexterror();
	}
	ret = __gtfs_fsf_write(f, ubuf, n, off);
	qunlock(&f->qlock);
	poperror();
	return ret;
}

static size_t gtfs_read(struct chan *c, void *ubuf, size_t n, off64_t off)
{
	struct tree_file *tf = chan_to_tree_file(c);

	if (tree_file_is_dir(tf))
		return gtfs_fsf_read(&tf->file, ubuf, n, off);
	return fs_file_read(&tf->file, ubuf, n, off);
}

/* Given a file (with dir->name set), couple it and sync to the backend chan.
 * This will store/consume the ref for backend, in the TF (freed with
 * gtfs_tf_free), even on error, unless you zero out the be_walk field. */
static void gtfs_tf_couple_backend(struct tree_file *tf, struct chan *backend)
{
	struct dir *dir;
	struct gtfs_priv *gp = kzmalloc(sizeof(struct gtfs_priv), MEM_WAIT);

	tf->file.priv = gp;
	tf->file.dir.qid = backend->qid;
	gp->be_walk = backend;
	dir = chandirstat(backend);
	if (!dir)
		error(ENOMEM, "chandirstat failed");
	fs_file_copy_from_dir(&tf->file, dir);
	kfree(dir);
	/* For sync_metadata */
	gp->be_length = tf->file.dir.length;
	gp->be_mode = tf->file.dir.mode;
	gp->be_mtime = tf->file.dir.mtime;
}

static void gtfs_tf_free(struct tree_file *tf)
{
	struct gtfs_priv *gp = tf_to_gtfs_priv(tf);

	/* Might have some partially / never constructed tree files */
	if (!gp)
		return;
	if (gp->was_removed) {
		gp->be_walk->type = -1;
		/* sanity */
		assert(kref_refcnt(&gp->be_walk->ref) == 1);
	}
	cclose(gp->be_walk);
	/* I/O chans can be NULL */
	cclose(gp->be_read);
	cclose(gp->be_write);
	kfree(gp);
}

static void gtfs_tf_unlink(struct tree_file *parent, struct tree_file *child)
{
	struct gtfs_priv *gp = tf_to_gtfs_priv(child);
	struct chan *be_walk = gp->be_walk;

	/* Remove clunks the be_walk chan/fid.  if it succeeded (and I think even if
	 * it didn't), we shouldn't close that fid again, which is what will happen
	 * soon after this function.  The TF code calls unlink, then when the last
	 * ref closes the TF, it'll get freed and we'll call back to gtfs_tf_free().
	 *
	 * This is the same issue we run into with all of the device remove ops
	 * where we want to refcnt something hanging off e.g. c->aux.  In 9p, you're
	 * not supposed to close a chan/fid that was already removed.
	 *
	 * Now here's the weird thing.  We can close the be_walk chan after remove,
	 * but it's possible that someone has walked and perhaps opened a frontend
	 * chan + TF, but hasn't done a read yet.  So someone might want to set up
	 * be_read, but they can't due to be_walk being closed.  We could give them
	 * a 'phase error' (one of 9p's errors for I/O on a removed file).
	 *
	 * Alternatively, we can mark the gtfs_priv so that when we do free it, we
	 * skip the dev.remove, similar to what sysremove() does.  That's probably
	 * easier.  This is technically racy, but we know that the release/free
	 * method won't be called until we return. */
	gp->was_removed = true;
	devtab[be_walk->type].remove(be_walk);
}

/* Caller sets the name, but doesn't know if it exists or not.  It's our job to
 * find out if it exists and fill in the child structure appropriately.  For
 * negative entries, just flagging it is fine.  Otherwise, we fill in the dir.
 * We should throw on error. */
static void gtfs_tf_lookup(struct tree_file *parent, struct tree_file *child)
{
	struct walkqid *wq;
	struct chan *be_walk = tf_to_gtfs_priv(parent)->be_walk;
	struct chan *child_be_walk;

	wq = devtab[be_walk->type].walk(be_walk, NULL, &child->file.dir.name, 1);
	if (!wq || !wq->clone) {
		kfree(wq);
		/* This isn't racy, since the child isn't linked to the tree yet */
		child->flags |= TF_F_NEGATIVE | TF_F_HAS_BEEN_USED;
		return;
	}
	/* walk shouldn't give us the same chan struct since we gave it a name and a
	 * NULL nc. */
	assert(wq->clone != be_walk);
	/* only gave it one name, and it didn't fail. */
	assert(wq->nqid == 1);
	/* sanity */
	assert(wq->clone->qid.path == wq->qid[wq->nqid - 1].path);
	child_be_walk = wq->clone;
	kfree(wq);
	gtfs_tf_couple_backend(child, child_be_walk);
}

static void gtfs_tf_create(struct tree_file *parent, struct tree_file *child,
                           int perm)
{
	ERRSTACK(1);
	struct chan *c = cclone(tf_to_gtfs_priv(parent)->be_walk);

	if (waserror()) {
		cclose(c);
		nexterror();
	}
	devtab[c->type].create(c, tree_file_to_name(child), 0, perm,
	                       child->file.dir.ext);
	/* The chan c is opened, which we don't want.  We can't cclone it either
	 * (since it is opened).  All we can do is have the parent walk again so we
	 * can get the child's unopened be_walk chan.  Conveniently, that's
	 * basically a lookup, so create is really two things: make it, then look it
	 * up from the backend. */
	cclose(c);
	poperror();
	if (waserror()) {
		warn("File %s was created in the backend, but unable to look it up!",
		     tree_file_to_name(child));
		nexterror();
	}
	gtfs_tf_lookup(parent, child);
	poperror();
}

static void gtfs_wstat_rename(struct fs_file *f, const char *name)
{
	struct dir dir;

	init_empty_dir(&dir);
	dir.name = (char*)name;
	wstat_dir(f, &dir);
}

static void gtfs_tf_rename(struct tree_file *tf, struct tree_file *old_parent,
                           struct tree_file *new_parent, const char *name,
                           int flags)
{
	struct chan *tf_c = tf_to_gtfs_priv(tf)->be_walk;
	struct chan *np_c = tf_to_gtfs_priv(new_parent)->be_walk;

	if (!devtab[tf_c->type].rename) {
		/* 9p can handle intra-directory renames, though some Akaros #devices
		 * might throw. */
		if (old_parent == new_parent) {
			gtfs_wstat_rename(&tf->file, name);
			return;
		}
		error(EXDEV, "%s: %s doesn't support rename", devname(),
		      devtab[tf_c->type].name);
	}
	devtab[tf_c->type].rename(tf_c, np_c, name, flags);
}

static bool gtfs_tf_has_children(struct tree_file *parent)
{
	struct dir dir[1];

	assert(tree_file_is_dir(parent));	/* TF bug */
	/* Any read should work, but there might be issues asking for something
	 * smaller than a dir.
	 *
	 * Note we use the unlocked read here.  The fs_file's qlock is held by our
	 * caller, and we reuse that qlock for the sync for reading/writing. */
	return __gtfs_fsf_read(&parent->file, dir, sizeof(struct dir), 0) > 0;
}

struct tree_file_ops gtfs_tf_ops = {
	.free = gtfs_tf_free,
	.unlink = gtfs_tf_unlink,
	.lookup = gtfs_tf_lookup,
	.create = gtfs_tf_create,
	.rename = gtfs_tf_rename,
	.has_children = gtfs_tf_has_children,
};

/* Fills page with its contents from its backing store file.
 *
 * Note the page/offset might be beyond the current file length, based on the
 * current pagemap code. */
static int gtfs_pm_readpage(struct page_map *pm, struct page *pg)
{
	ERRSTACK(1);
	void *kva = page2kva(pg);
	off64_t offset = pg->pg_index << PGSHIFT;
	size_t ret;

	if (waserror()) {
		poperror();
		return -get_errno();
	}
	/* If offset is beyond the length of the file, the 9p device/server should
	 * return 0.  We'll just init an empty page.  The length on the frontend (in
	 * the fsf->dir.length) will be adjusted.  The backend will hear about it on
	 * the next sync. */
	ret = gtfs_fsf_read(pm->pm_file, kva, PGSIZE, offset);
	poperror();
	if (ret < PGSIZE)
		memset(kva + ret, 0, PGSIZE - ret);
	atomic_or(&pg->pg_flags, PG_UPTODATE);
	return 0;
}

/* Meant to take the page from PM and flush to backing store. */
static int gtfs_pm_writepage(struct page_map *pm, struct page *pg)
{
	ERRSTACK(1);
	struct fs_file *f = pm->pm_file;
	void *kva = page2kva(pg);
	off64_t offset = pg->pg_index << PGSHIFT;
	size_t amt;

	qlock(&f->qlock);
	if (waserror()) {
		qunlock(&f->qlock);
		poperror();
		return -get_errno();
	}
	/* Don't writeback beyond the length of the file.  Most of the time this
	 * comes up is when the len is in the middle of the last page. */
	if (offset >= fs_file_get_length(f)) {
		qunlock(&f->qlock);
		return 0;
	}
	amt = MIN(PGSIZE, fs_file_get_length(f) - offset);
	__gtfs_fsf_write(f, kva, amt, offset);
	qunlock(&f->qlock);
	poperror();
	return 0;
}

/* Caller holds the file's qlock */
static void __trunc_to(struct fs_file *f, off64_t begin)
{
	struct gtfs_priv *gp = fsf_to_gtfs_priv(f);
	struct dir dir;

	init_empty_dir(&dir);
	dir.length = begin;
	wstat_dir(f, &dir);
	/* recall the invariant: be_length == the backend's length */
	gp->be_length = begin;
}

/* Caller holds the file's qlock */
static void __zero_fill(struct fs_file *f, off64_t begin, off64_t end)
{
	ERRSTACK(1);
	void *zeros;

	if (PGOFF(begin) || PGOFF(end))
		error(EINVAL, "zero_fill had unaligned begin (%p) or end (%p)\n",
		      begin, end);
	zeros = kpages_zalloc(PGSIZE, MEM_WAIT);
	if (waserror()) {
		kpages_free(zeros, PGSIZE);
		nexterror();
	}
	for (off64_t o = begin; o < end; o += PGSIZE)
		__gtfs_fsf_write(f, zeros, PGSIZE, o);
	poperror();
}

/* The intent here is for the backend to drop all data in the range.  Zeros are
 * OK - any future read should get a zero.
 *
 * These offsets are the beginning and end of the hole to punch.  The TF code
 * already dealt with edge cases, so these happen to be page aligned.  That
 * shouldn't matter for the backend device.
 *
 * Don't worry about a border page for end that is all zeros.
 * fs_file_truncate() rounded up to the nearest page to avoid issues.  The user
 * could manually punch a hole, and they could create a page of zeros at end.
 * We don't care.
 *
 * 9p doesn't have a hole-punch, so we'll truncate if we can and o/w fill with
 * zeros.
 *
 * Note that the frontend's file length often differs from the backend.  Under
 * normal operation, such as writing to a file, the frontend's len will be
 * greater than the backend's.  When we sync, the backend learns the real
 * length.  Similarly, when we shrink a gile, the backend's length may be
 * greater than the frontend.  Consider a truncate from 8192 to 4095: we punch
 * with begin = 4096, end = 8192.  In either case, the backend learns the real
 * length on a sync.  In punch_hole, we're just trying to discard old data. */
static void gtfs_fs_punch_hole(struct fs_file *f, off64_t begin, off64_t end)
{
	ERRSTACK(1);
	struct gtfs_priv *gp = fsf_to_gtfs_priv(f);

	qlock(&f->qlock);
	if (waserror()) {
		qunlock(&f->qlock);
		nexterror();
	}
	if (end >= gp->be_length) {
		if (begin < gp->be_length)
			__trunc_to(f, begin);
	} else {
		__zero_fill(f, begin, end);
	}
	qunlock(&f->qlock);
	poperror();
}

static bool gtfs_fs_can_grow_to(struct fs_file *f, size_t len)
{
	/* TODO: are there any limits in 9p? */
	return true;
}

struct fs_file_ops gtfs_fs_ops = {
	.readpage = gtfs_pm_readpage,
	.writepage = gtfs_pm_writepage,
	.punch_hole = gtfs_fs_punch_hole,
	.can_grow_to = gtfs_fs_can_grow_to,
};

/* We're passed a backend chan, usually of type #mnt, used for an uncached
 * mount.  We call it 'backend.'  It is the result of an attach, e.g. mntattach.
 * In the case of #mnt, this chan is different than the one that has the 9p
 * server on the other side, called 'mchan'.  That chan is at backend->mchan,
 * and also the struct mnt->c.  The struct mnt is shared by all mounts talking
 * to the 9p server over the mchan, and is stored at mchan->mux.  Backend chans
 * have a strong (counted) ref on the mchan.
 *
 * We create and return a chan of #gtfs, suitable for attaching to the
 * namespace.  This chan will have the root TF hanging off aux, just like how
 * any other attached TFS has a root TF.  #gtfs manages the linkage between a TF
 * and the backend, which is the purpose of gtfs_priv.
 *
 * A note on refcounts: in the normal, uncached operation, the 'backend' chan
 * has a ref (actually a chan kref, which you cclose) on the comms chan (mchan).
 * We get one ref at mntattach time, and every distinct mntwalk gets another
 * ref.  Those actually get closed in chanfree(), since they are stored at
 * mchan.
 *
 * All gtfs *tree_files* have at least one refcounted chan corresponding to the
 * file/FID on the backend server.  Think of it as a 1:1 connection, even though
 * there is more than one chan.  The gtfs device can have many chans pointing to
 * the same TF, which is kreffed.  That TF is 1:1 on a backend object.
 *
 * All walks from this attach point will get chans with TFs from this TFS and
 * will incref the struct gtfs.
 */
static struct chan *gtfs_attach(char *arg)
{
	ERRSTACK(2);
	struct chan *backend = (struct chan*)arg;
	struct chan *frontend;
	struct tree_filesystem *tfs;
	struct gtfs *gtfs;

	frontend = devattach(devname(), 0);
	if (waserror()) {
		/* same as #mnt - don't cclose, since we don't want to devtab close, and
		 * we know the ref == 1 here. */
		chanfree(frontend);
		nexterror();
	}
	gtfs = kzmalloc(sizeof(struct gtfs), MEM_WAIT);
// XXX
recent = gtfs;
	/* This 'users' kref is the one that every distinct frontend chan has.
	 * These come from attaches and successful, 'moving' walks. */
	kref_init(&gtfs->users, gtfs_release, 1);
	tfs = (struct tree_filesystem*)gtfs;
	/* This gives us one ref on root, released during gtfs_release().  name is
	 * set to ".", though that gets overwritten during coupling. */
	tfs_init(tfs);
	if (waserror()) {
		/* don't consume the backend ref on error, caller expects to have it */
		tf_to_gtfs_priv(tfs->root)->be_walk = NULL;
		/* ref from tfs_init.  this should free the TF. */
		tf_kref_put(tfs->root);
		tfs_destroy(tfs);
		kfree(gtfs);
		// XXX
		recent = NULL;
		nexterror();
	}
	/* stores the ref for 'backend' inside tfs->root */
	gtfs_tf_couple_backend(tfs->root, backend);
	poperror();
	tfs->tf_ops = gtfs_tf_ops;
	tfs->fs_ops = gtfs_fs_ops;
	/* need another ref on root for the frontend chan */
	tf_kref_get(tfs->root);
	chan_set_tree_file(frontend, tfs->root);
	poperror();
	return frontend;
}

static bool lru_prune_cb(struct tree_file *tf)
{
	ERRSTACK(1);

	if (waserror()) {
		/* not much to do - ssh the file out? */
		printk("Failed to sync file %s: %s\n", tree_file_to_name(tf),
		       current_errstr());
		poperror();
		return false;
	}
	writeback_file(&tf->file);
	poperror();
	return true;
}

static void pressure_dfs_cb(struct tree_file *tf)
{
	if (!tree_file_is_dir(tf))
		pm_free_unused_pages(tf->file.pm);
}

/* Under memory pressure, there are a bunch of things we can do. */
static void gtfs_free_memory(struct gtfs *gtfs)
{
	/* This attempts to remove every file from the LRU.  It'll write back dirty
	 * files, then if they haven't been used since we started, it'll delete the
	 * frontend TF, which will delete the entire page cache entry.  The heavy
	 * lifting is done by TF code. */
	tfs_lru_for_each(&gtfs->tfs, lru_prune_cb, -1);
	/* This drops the negative TFs.  It's not a huge deal, since they are small,
	 * but perhaps it'll help. */
	tfs_lru_prune_neg(&gtfs->tfs);
	/* This will attempt to free memory from all files in the frontend,
	 * regardless of whether or not they are in use.  This might help if you
	 * have some large files that happened to be open. */
	tfs_frontend_for_each(&gtfs->tfs, pressure_dfs_cb);
}

static void gtfs_sync_tf(struct tree_file *tf)
{
	writeback_file(&tf->file);
}

static void gtfs_sync_gtfs(struct gtfs *gtfs)
{
	tfs_frontend_for_each(&gtfs->tfs, gtfs_sync_tf);
}

/* chan_ctl or something can hook into these functions */
static void gtfs_sync_chan(struct chan *c)
{
	gtfs_sync_tf(chan_to_tree_file(c));
}

static void gtfs_sync_chans_fs(struct chan *any_c)
{
	gtfs_sync_gtfs(chan_to_gtfs(any_c));
}

static unsigned long gtfs_chan_ctl(struct chan *c, int op, unsigned long a1,
                                   unsigned long a2, unsigned long a3,
                                   unsigned long a4)
{
	switch (op) {
	case CCTL_SYNC:
		if (tree_file_is_dir(chan_to_tree_file(c)))
			gtfs_sync_chans_fs(c);
		else
			gtfs_sync_chan(c);
		return 0;
	default:
		error(EINVAL, "%s does not support %d", __func__, op);
	}
}

struct dev gtfs_devtab __devtab = {
	.name = "gtfs",

	.reset = devreset,
	.init = devinit,
	.shutdown = devshutdown,
	.attach = gtfs_attach,
	.walk = gtfs_walk,
	.stat = tree_chan_stat,
	.open = gtfs_open,
	.create = gtfs_create,
	.close = gtfs_close,
	.read = gtfs_read,
	.bread = devbread,
	.write = tree_chan_write,
	.bwrite = devbwrite,
	.remove = gtfs_remove,
	.rename = tree_chan_rename,
	.wstat = gtfs_wstat,
	.power = devpower,
	.chaninfo = devchaninfo,
	.mmap = tree_chan_mmap,
	.chan_ctl = gtfs_chan_ctl,
};

// XXX
int xme(int op)
{
	if (!recent)
		return -1;
	switch (op) {
	case 1:
		printk("dumping GTFS (Qidpath, Ref)\n-----------------\n");
		__tfs_dump(&recent->tfs);
		break;
	case 3:
		gtfs_free_memory(recent);
		break;
	default:
		printk("give me an op\n");
		return -1;
	}
	return 0;
}

// XXX
//
//	would like some torture tests
//
//ktask changes:
//	maybe better framework for ktasks and rendez.
//			and ktask names
// 			also, would like a better kthread interface regarding the string.
// 				like an snprintf or something.
//
// 			either that, or just have the ktask code malloc and free its own
// 			copy of the name.  so we don't have different behavior for each.
// 				probably this
// 		also, this kth might be on another core.  same as the mgmt kth,
// 		since we don't have kthread affinity.
// 				right now, whoever does the wakeup hosts the core, right?
// 				maybe have ktasks head to core 0 or some affinity
//		enum / #define for the gp_ktask_ctl states
//		there's some element of post-and-poke to it, esp regarding rcu_barrier
//			also, we now care if a ktask is running or not, more like
//			schedulable entities.  no one ever had a pointer to a ktask before
// for_each_mgmt_core, is_mgmt_core()
// 		dynamically changing this is harder?
//
// cache-align fields in rcu_state
// 		actually, probably should have a ktask struct, and a pointer hangs off
// 		rcu_state
