/*
 * Cleancache frontend
 *
 * This code provides the generic "frontend" layer to call a matching
 * "backend" driver implementation of cleancache.  See
 * Documentation/vm/cleancache.txt for more information.
 *
 * Copyright (C) 2009-2010 Oracle Corp. All rights reserved.
 * Author: Dan Magenheimer
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 */

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/exportfs.h>
#include <linux/mm.h>
#include <linux/debugfs.h>
#include <linux/cleancache.h>

/*
 * cleancache_ops is set by cleancache_ops_register to contain the pointers
 * to the cleancache "backend" implementation functions.
 */
static struct cleancache_ops *cleancache_ops __read_mostly;

/*
 * Counters available via /sys/kernel/debug/cleancache (if debugfs is
 * properly configured.  These are for information only so are not protected
 * against increment races.
 */
static u64 cleancache_succ_gets;
static u64 cleancache_failed_gets;
static u64 cleancache_puts;
static u64 cleancache_invalidates;

/*
 * When no backend is registered all calls to init_fs and init_shared_fs
 * are registered and fake poolids (FAKE_FS_POOLID_OFFSET or
 * FAKE_SHARED_FS_POOLID_OFFSET, plus offset in the respective array
 * [shared_|]fs_poolid_map) are given to the respective super block
 * (sb->cleancache_poolid) and no tmem_pools are created. When a backend
 * registers with cleancache the previous calls to init_fs and init_shared_fs
 * are executed to create tmem_pools and set the respective poolids. While no
 * backend is registered all "puts", "gets" and "flushes" are ignored or failed.
 */
#define MAX_INITIALIZABLE_FS 32
#define FAKE_FS_POOLID_OFFSET 1000
#define FAKE_SHARED_FS_POOLID_OFFSET 2000

#define FS_NO_BACKEND (-1)
#define FS_UNKNOWN (-2)
static int fs_poolid_map[MAX_INITIALIZABLE_FS];
static int shared_fs_poolid_map[MAX_INITIALIZABLE_FS];
static char *uuids[MAX_INITIALIZABLE_FS];
/*
 * Mutex for the [shared_|]fs_poolid_map to guard against multiple threads
 * invoking umount (and ending in __cleancache_invalidate_fs) and also multiple
 * threads calling mount (and ending up in __cleancache_init_[shared|]fs).
 */
static DEFINE_MUTEX(poolid_mutex);
/*
 * When set to false (default) all calls to the cleancache functions, except
 * the __cleancache_invalidate_fs and __cleancache_init_[shared|]fs are guarded
 * by the if (!cleancache_ops) return. This means multiple threads (from
 * different filesystems) will be checking cleancache_ops. The usage of a
 * bool instead of a atomic_t or a bool guarded by a spinlock is OK - we are
 * OK if the time between the backend's have been initialized (and
 * cleancache_ops has been set to not NULL) and when the filesystems start
 * actually calling the backends. The inverse (when unloading) is obviously
 * not good - but this shim does not do that (yet).
 */

/*
 * The backends and filesystems work all asynchronously. This is b/c the
 * backends can be built as modules.
 * The usual sequence of events is:
 *	a) mount /	-> __cleancache_init_fs is called. We set the
 *		[shared_|]fs_poolid_map and uuids for.
 *
 *	b). user does I/Os -> we call the rest of __cleancache_* functions
 *		which return immediately as cleancache_ops is false.
 *
 *	c). modprobe zcache -> cleancache_register_ops. We init the backend
 *		and set cleancache_ops to true, and for any fs_poolid_map
 *		(which is set by __cleancache_init_fs) we initialize the poolid.
 *
 *	d). user does I/Os -> now that cleancache_ops is true all the
 *		__cleancache_* functions can call the backend. They all check
 *		that fs_poolid_map is valid and if so invoke the backend.
 *
 *	e). umount /	-> __cleancache_invalidate_fs, the fs_poolid_map is
 *		reset (which is the second check in the __cleancache_* ops
 *		to call the backend).
 *
 * The sequence of event could also be c), followed by a), and d). and e). The
 * c) would not happen anymore. There is also the chance of c), and one thread
 * doing a) + d), and another doing e). For that case we depend on the
 * filesystem calling __cleancache_invalidate_fs in the proper sequence (so
 * that it handles all I/Os before it invalidates the fs (which is last part
 * of unmounting process).
 *
 * Note: The acute reader will notice that there is no "rmmod zcache" case.
 * This is b/c the functionality for that is not yet implemented and when
 * done, will require some extra locking not yet devised.
 */

/*
 * Register operations for cleancache, returning previous thus allowing
 * detection of multiple backends and possible nesting.
 */
struct cleancache_ops *cleancache_register_ops(struct cleancache_ops *ops)
{
	struct cleancache_ops *old = cleancache_ops;
	int i;

	mutex_lock(&poolid_mutex);
	for (i = 0; i < MAX_INITIALIZABLE_FS; i++) {
		if (fs_poolid_map[i] == FS_NO_BACKEND)
			fs_poolid_map[i] = ops->init_fs(PAGE_SIZE);
		if (shared_fs_poolid_map[i] == FS_NO_BACKEND)
			shared_fs_poolid_map[i] = ops->init_shared_fs
					(uuids[i], PAGE_SIZE);
	}
	/*
	 * We MUST set cleancache_ops _after_ we have called the backends
	 * init_fs or init_shared_fs functions. Otherwise the compiler might
	 * re-order where cleancache_ops is set in this function.
	 */
	barrier();
	cleancache_ops = ops;
	mutex_unlock(&poolid_mutex);
	return old;
}
EXPORT_SYMBOL(cleancache_register_ops);

/* Called by a cleancache-enabled filesystem at time of mount */
void __cleancache_init_fs(struct super_block *sb)
{
	int i;

	mutex_lock(&poolid_mutex);
	for (i = 0; i < MAX_INITIALIZABLE_FS; i++) {
		if (fs_poolid_map[i] == FS_UNKNOWN) {
			sb->cleancache_poolid = i + FAKE_FS_POOLID_OFFSET;
			if (cleancache_ops)
				fs_poolid_map[i] = cleancache_ops->init_fs(PAGE_SIZE);
			else
				fs_poolid_map[i] = FS_NO_BACKEND;
			break;
		}
	}
	mutex_unlock(&poolid_mutex);
}
EXPORT_SYMBOL(__cleancache_init_fs);

/* Called by a cleancache-enabled clustered filesystem at time of mount */
void __cleancache_init_shared_fs(char *uuid, struct super_block *sb)
{
	int i;

	mutex_lock(&poolid_mutex);
	for (i = 0; i < MAX_INITIALIZABLE_FS; i++) {
		if (shared_fs_poolid_map[i] == FS_UNKNOWN) {
			sb->cleancache_poolid = i + FAKE_SHARED_FS_POOLID_OFFSET;
			uuids[i] = uuid;
			if (cleancache_ops)
				shared_fs_poolid_map[i] = cleancache_ops->init_shared_fs
						(uuid, PAGE_SIZE);
			else
				shared_fs_poolid_map[i] = FS_NO_BACKEND;
			break;
		}
	}
	mutex_unlock(&poolid_mutex);
}
EXPORT_SYMBOL(__cleancache_init_shared_fs);

/*
 * If the filesystem uses exportable filehandles, use the filehandle as
 * the key, else use the inode number.
 */
static int cleancache_get_key(struct inode *inode,
			      struct cleancache_filekey *key)
{
	int (*fhfn)(struct inode *, __u32 *fh, int *, struct inode *);
	int len = 0, maxlen = CLEANCACHE_KEY_MAX;
	struct super_block *sb = inode->i_sb;

	key->u.ino = inode->i_ino;
	if (sb->s_export_op != NULL) {
		fhfn = sb->s_export_op->encode_fh;
		if  (fhfn) {
			len = (*fhfn)(inode, &key->u.fh[0], &maxlen, NULL);
			if (len <= FILEID_ROOT || len == FILEID_INVALID)
				return -1;
			if (maxlen > CLEANCACHE_KEY_MAX)
				return -1;
		}
	}
	return 0;
}

/*
 * Returns a pool_id that is associated with a given fake poolid.
 */
static int get_poolid_from_fake(int fake_pool_id)
{
	if (fake_pool_id >= FAKE_SHARED_FS_POOLID_OFFSET)
		return shared_fs_poolid_map[fake_pool_id -
			FAKE_SHARED_FS_POOLID_OFFSET];
	else if (fake_pool_id >= FAKE_FS_POOLID_OFFSET)
		return fs_poolid_map[fake_pool_id - FAKE_FS_POOLID_OFFSET];
	return FS_NO_BACKEND;
}

/*
 * "Get" data from cleancache associated with the poolid/inode/index
 * that were specified when the data was put to cleanache and, if
 * successful, use it to fill the specified page with data and return 0.
 * The pageframe is unchanged and returns -1 if the get fails.
 * Page must be locked by caller.
 *
 * The function has two checks before any action is taken - whether
 * a backend is registered and whether the sb->cleancache_poolid
 * is correct.
 */
int __cleancache_get_page(struct page *page)
{
	int ret = -1;
	int pool_id;
	int fake_pool_id;
	struct cleancache_filekey key = { .u.key = { 0 } };

	if (!cleancache_ops) {
		cleancache_failed_gets++;
		goto out;
	}

	VM_BUG_ON_PAGE(!PageLocked(page), page);
	fake_pool_id = page->mapping->host->i_sb->cleancache_poolid;
	if (fake_pool_id < 0)
		goto out;
	pool_id = get_poolid_from_fake(fake_pool_id);

	if (cleancache_get_key(page->mapping->host, &key) < 0)
		goto out;

	if (pool_id >= 0)
		ret = cleancache_ops->get_page(pool_id,
				key, page->index, page);
	if (ret == 0)
		cleancache_succ_gets++;
	else
		cleancache_failed_gets++;
out:
	return ret;
}
EXPORT_SYMBOL(__cleancache_get_page);

/*
 * "Put" data from a page to cleancache and associate it with the
 * (previously-obtained per-filesystem) poolid and the page's,
 * inode and page index.  Page must be locked.  Note that a put_page
 * always "succeeds", though a subsequent get_page may succeed or fail.
 *
 * The function has two checks before any action is taken - whether
 * a backend is registered and whether the sb->cleancache_poolid
 * is correct.
 */
void __cleancache_put_page(struct page *page)
{
	int pool_id;
	int fake_pool_id;
	struct cleancache_filekey key = { .u.key = { 0 } };

	if (!cleancache_ops) {
		cleancache_puts++;
		return;
	}

	VM_BUG_ON_PAGE(!PageLocked(page), page);
	fake_pool_id = page->mapping->host->i_sb->cleancache_poolid;
	if (fake_pool_id < 0)
		return;

	pool_id = get_poolid_from_fake(fake_pool_id);

	if (pool_id >= 0 &&
		cleancache_get_key(page->mapping->host, &key) >= 0) {
		cleancache_ops->put_page(pool_id, key, page->index, page);
		cleancache_puts++;
	}
}
EXPORT_SYMBOL(__cleancache_put_page);

/*
 * Invalidate any data from cleancache associated with the poolid and the
 * page's inode and page index so that a subsequent "get" will fail.
 *
 * The function has two checks before any action is taken - whether
 * a backend is registered and whether the sb->cleancache_poolid
 * is correct.
 */
void __cleancache_invalidate_page(struct address_space *mapping,
					struct page *page)
{
	/* careful... page->mapping is NULL sometimes when this is called */
	int pool_id;
	int fake_pool_id = mapping->host->i_sb->cleancache_poolid;
	struct cleancache_filekey key = { .u.key = { 0 } };

	if (!cleancache_ops)
		return;

	if (fake_pool_id >= 0) {
		pool_id = get_poolid_from_fake(fake_pool_id);
		if (pool_id < 0)
			return;

		VM_BUG_ON_PAGE(!PageLocked(page), page);
		if (cleancache_get_key(mapping->host, &key) >= 0) {
			cleancache_ops->invalidate_page(pool_id,
					key, page->index);
			cleancache_invalidates++;
		}
	}
}
EXPORT_SYMBOL(__cleancache_invalidate_page);

/*
 * Invalidate all data from cleancache associated with the poolid and the
 * mappings's inode so that all subsequent gets to this poolid/inode
 * will fail.
 *
 * The function has two checks before any action is taken - whether
 * a backend is registered and whether the sb->cleancache_poolid
 * is correct.
 */
void __cleancache_invalidate_inode(struct address_space *mapping)
{
	int pool_id;
	int fake_pool_id = mapping->host->i_sb->cleancache_poolid;
	struct cleancache_filekey key = { .u.key = { 0 } };

	if (!cleancache_ops)
		return;

	if (fake_pool_id < 0)
		return;

	pool_id = get_poolid_from_fake(fake_pool_id);

	if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0)
		cleancache_ops->invalidate_inode(pool_id, key);
}
EXPORT_SYMBOL(__cleancache_invalidate_inode);

/*
 * Called by any cleancache-enabled filesystem at time of unmount;
 * note that pool_id is surrendered and may be returned by a subsequent
 * cleancache_init_fs or cleancache_init_shared_fs.
 */
void __cleancache_invalidate_fs(struct super_block *sb)
{
	int index;
	int fake_pool_id = sb->cleancache_poolid;
	int old_poolid = fake_pool_id;

	mutex_lock(&poolid_mutex);
	if (fake_pool_id >= FAKE_SHARED_FS_POOLID_OFFSET) {
		index = fake_pool_id - FAKE_SHARED_FS_POOLID_OFFSET;
		old_poolid = shared_fs_poolid_map[index];
		shared_fs_poolid_map[index] = FS_UNKNOWN;
		uuids[index] = NULL;
	} else if (fake_pool_id >= FAKE_FS_POOLID_OFFSET) {
		index = fake_pool_id - FAKE_FS_POOLID_OFFSET;
		old_poolid = fs_poolid_map[index];
		fs_poolid_map[index] = FS_UNKNOWN;
	}
	sb->cleancache_poolid = -1;
	if (cleancache_ops)
		cleancache_ops->invalidate_fs(old_poolid);
	mutex_unlock(&poolid_mutex);
}
EXPORT_SYMBOL(__cleancache_invalidate_fs);

static int __init init_cleancache(void)
{
	int i;

#ifdef CONFIG_DEBUG_FS
	struct dentry *root = debugfs_create_dir("cleancache", NULL);
	if (root == NULL)
		return -ENXIO;
	debugfs_create_u64("succ_gets", S_IRUGO, root, &cleancache_succ_gets);
	debugfs_create_u64("failed_gets", S_IRUGO,
				root, &cleancache_failed_gets);
	debugfs_create_u64("puts", S_IRUGO, root, &cleancache_puts);
	debugfs_create_u64("invalidates", S_IRUGO,
				root, &cleancache_invalidates);
#endif
	for (i = 0; i < MAX_INITIALIZABLE_FS; i++) {
		fs_poolid_map[i] = FS_UNKNOWN;
		shared_fs_poolid_map[i] = FS_UNKNOWN;
	}
	return 0;
}
module_init(init_cleancache)
