/*
 * linux/mm/zcache.c
 *
 * A cleancache backend for file pages compression.
 * Concepts based on original zcache by Dan Magenheimer.
 * Copyright (C) 2013  Bob Liu <bob.liu@xxxxxxxxxx>
 *
 * With zcache, active file pages can be compressed in memory during page
 * reclaiming. When their data is needed again the I/O reading operation is
 * avoided. This results in a significant performance gain under memory pressure
 * for systems with many file pages.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/atomic.h>
#include <linux/cleancache.h>
#include <linux/cpu.h>
#include <linux/crypto.h>
#include <linux/page-flags.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/mm_types.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/radix-tree.h>
#include <linux/rbtree.h>
#include <linux/types.h>
#include <linux/zbud.h>

/*
 * Enable/disable zcache (disabled by default)
 */
static bool zcache_enabled __read_mostly;
module_param_named(enabled, zcache_enabled, bool, 0);

/*
 * Compressor to be used by zcache
 */
#define ZCACHE_COMPRESSOR_DEFAULT "lzo"
static char *zcache_compressor = ZCACHE_COMPRESSOR_DEFAULT;
module_param_named(compressor, zcache_compressor, charp, 0);

/*
 * The maximum percentage of memory that the compressed pool can occupy.
 */
static unsigned int zcache_max_pool_percent = 10;
module_param_named(max_pool_percent, zcache_max_pool_percent, uint, 0644);

static unsigned int zcache_clear_percent = 4;
module_param_named(clear_percent, zcache_clear_percent, uint, 0644);
/*
 * zcache statistics
 */
static u64 zcache_pool_limit_hit;
static u64 zcache_dup_entry;
static u64 zcache_zbud_alloc_fail;
static u64 zcache_evict_zpages;
static u64 zcache_evict_filepages;
static u64 zcache_inactive_pages_refused;
static u64 zcache_reclaim_fail;
static u64 zcache_pool_shrink;
static u64 zcache_pool_shrink_fail;
static u64 zcache_pool_shrink_pages;
static u64 zcache_store_failed;
static atomic_t zcache_stored_pages = ATOMIC_INIT(0);
static atomic_t zcache_stored_zero_pages = ATOMIC_INIT(0);

#define GFP_ZCACHE \
	(__GFP_FS | __GFP_NORETRY | __GFP_NOWARN | \
		__GFP_NOMEMALLOC | __GFP_ZERO)

/*
 * Make sure this is different from radix tree
 * indirect ptr or exceptional entry.
 */
#define ZERO_HANDLE	((void *)~(~0UL >> 1))

/*
 * Zcache receives pages for compression through the Cleancache API and is able
 * to evict pages from its own compressed pool on an LRU basis in the case that
 * the compressed pool is full.
 *
 * Zcache makes use of zbud for the managing the compressed memory pool. Each
 * allocation in zbud is not directly accessible by address.  Rather, a handle
 * (zaddr) is return by the allocation routine and that handle(zaddr must be
 * mapped before being accessed. The compressed memory pool grows on demand and
 * shrinks as compressed pages are freed.
 *
 * When a file page is passed from cleancache to zcache, zcache maintains a
 * mapping of the <filesystem_type, inode_number, page_index> to the zbud
 * address that references that compressed file page. This mapping is achieved
 * with a red-black tree per filesystem type, plus a radix tree per red-black
 * node.
 *
 * A zcache pool with pool_id as the index is created when a filesystem mounted
 * Each zcache pool has a red-black tree, the inode number(rb_index) is the
 * search key. Each red-black tree node has a radix tree which use
 * page->index(ra_index) as the index. Each radix tree slot points to the zbud
 * address combining with some extra information(zcache_ra_handle).
 */
#define MAX_ZCACHE_POOLS 32
/*
 * One zcache_pool per (cleancache aware) filesystem mount instance
 */
struct zcache_pool {
	struct rb_root rbtree;
	rwlock_t rb_lock;		/* Protects rbtree */
	u64 size;
	struct zbud_pool *pool;         /* Zbud pool used */
};

/*
 * Manage all zcache pools
 */
struct _zcache {
	struct zcache_pool *pools[MAX_ZCACHE_POOLS];
	u32 num_pools;			/* Current no. of zcache pools */
	spinlock_t pool_lock;		/* Protects pools[] and num_pools */
};
struct _zcache zcache;

/*
 * Redblack tree node, each node has a page index radix-tree.
 * Indexed by inode nubmer.
 */
struct zcache_rbnode {
	struct rb_node rb_node;
	int rb_index;
	struct radix_tree_root ratree; /* Page radix tree per inode rbtree */
	spinlock_t ra_lock;		/* Protects radix tree */
	struct kref refcount;
};

/*
 * Radix-tree leaf, indexed by page->index
 */
struct zcache_ra_handle {
	int rb_index;			/* Redblack tree index */
	int ra_index;			/* Radix tree index */
	int zlen;			/* Compressed page size */
	struct zcache_pool *zpool;	/* Finding zcache_pool during evict */
};

u64 zcache_pages(void)
{
	int i;
	u64 count = 0;

	for (i = 0; (i < MAX_ZCACHE_POOLS) && zcache.pools[i]; i++)
		count += zcache.pools[i]->size;

	return count;
}

static struct kmem_cache *zcache_rbnode_cache;
static int zcache_rbnode_cache_create(void)
{
	zcache_rbnode_cache = KMEM_CACHE(zcache_rbnode, 0);
	return zcache_rbnode_cache == NULL;
}
static void zcache_rbnode_cache_destroy(void)
{
	kmem_cache_destroy(zcache_rbnode_cache);
}

static unsigned long zcache_count(struct shrinker *s,
				  struct shrink_control *sc)
{
	unsigned long active_file;
	long file_gap;

	active_file = global_page_state(NR_ACTIVE_FILE);
	file_gap = zcache_pages() - active_file;
	if (file_gap < 0)
		file_gap = 0;
	return file_gap;
}

static unsigned long zcache_scan(struct shrinker *s, struct shrink_control *sc)
{
	unsigned long active_file;
	unsigned long file;
	long file_gap;
	unsigned long freed = 0;
	unsigned long pool;
	static bool running;
	int i = 0;
	int retries;

	if (running)
		goto end;

	running = true;
	active_file = global_page_state(NR_ACTIVE_FILE);
	file = global_page_state(NR_FILE_PAGES);
	pool = zcache_pages();

	file_gap = pool - file;

	if ((file_gap >= 0) &&
		(totalram_pages * zcache_clear_percent / 100 > file)) {
		file_gap = pool;
		zcache_pool_shrink++;
		goto reclaim;
	}

	/*
	 * file_gap == 0 means that the number of pages
	 * stored by zcache is around twice as many as the
	 * number of active file pages.
	 */
	file_gap = pool - active_file;
	if (file_gap < 0)
		file_gap = 0;
	else
		zcache_pool_shrink++;

reclaim:
	retries = file_gap;
	while ((file_gap > 0) && retries) {
		struct zcache_pool *zpool =
			zcache.pools[i++ % MAX_ZCACHE_POOLS];
		if (!zpool || !zpool->size)
			continue;
		if (zbud_reclaim_page(zpool->pool, 8)) {
			zcache_pool_shrink_fail++;
			retries--;
			continue;
		}
		freed++;
		file_gap--;
	}

	zcache_pool_shrink_pages += freed;
	for (i = 0; (i < MAX_ZCACHE_POOLS) && zcache.pools[i]; i++)
		zcache.pools[i]->size =
			zbud_get_pool_size(zcache.pools[i]->pool);

	running = false;
end:
	return freed;
}

static struct shrinker zcache_shrinker = {
	.scan_objects = zcache_scan,
	.count_objects = zcache_count,
	.seeks = DEFAULT_SEEKS * 16
};

/*
 * Compression functions
 * (Below functions are copyed from zswap!)
 */
static struct crypto_comp * __percpu *zcache_comp_pcpu_tfms;

enum comp_op {
	ZCACHE_COMPOP_COMPRESS,
	ZCACHE_COMPOP_DECOMPRESS
};

static int zcache_comp_op(enum comp_op op, const u8 *src, unsigned int slen,
				u8 *dst, unsigned int *dlen)
{
	struct crypto_comp *tfm;
	int ret;

	tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, get_cpu());
	switch (op) {
	case ZCACHE_COMPOP_COMPRESS:
		ret = crypto_comp_compress(tfm, src, slen, dst, dlen);
		break;
	case ZCACHE_COMPOP_DECOMPRESS:
		ret = crypto_comp_decompress(tfm, src, slen, dst, dlen);
		break;
	default:
		ret = -EINVAL;
	}

	put_cpu();
	return ret;
}

static int __init zcache_comp_init(void)
{
	if (!crypto_has_comp(zcache_compressor, 0, 0)) {
		pr_info("%s compressor not available\n", zcache_compressor);
		/* fall back to default compressor */
		zcache_compressor = ZCACHE_COMPRESSOR_DEFAULT;
		if (!crypto_has_comp(zcache_compressor, 0, 0))
			/* can't even load the default compressor */
			return -ENODEV;
	}
	pr_info("using %s compressor\n", zcache_compressor);

	/* alloc percpu transforms */
	zcache_comp_pcpu_tfms = alloc_percpu(struct crypto_comp *);
	if (!zcache_comp_pcpu_tfms)
		return -ENOMEM;
	return 0;
}

static void zcache_comp_exit(void)
{
	/* free percpu transforms */
	if (zcache_comp_pcpu_tfms)
		free_percpu(zcache_comp_pcpu_tfms);
}

/*
 * Per-cpu code
 * (Below functions are also copyed from zswap!)
 */
static DEFINE_PER_CPU(u8 *, zcache_dstmem);

static int __zcache_cpu_notifier(unsigned long action, unsigned long cpu)
{
	struct crypto_comp *tfm;
	u8 *dst;

	switch (action) {
	case CPU_UP_PREPARE:
		tfm = crypto_alloc_comp(zcache_compressor, 0, 0);
		if (IS_ERR(tfm)) {
			pr_err("can't allocate compressor transform\n");
			return NOTIFY_BAD;
		}
		*per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = tfm;
		dst = kmalloc(PAGE_SIZE * 2, GFP_KERNEL);
		if (!dst) {
			pr_err("can't allocate compressor buffer\n");
			crypto_free_comp(tfm);
			*per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = NULL;
			return NOTIFY_BAD;
		}
		per_cpu(zcache_dstmem, cpu) = dst;
		break;
	case CPU_DEAD:
	case CPU_UP_CANCELED:
		tfm = *per_cpu_ptr(zcache_comp_pcpu_tfms, cpu);
		if (tfm) {
			crypto_free_comp(tfm);
			*per_cpu_ptr(zcache_comp_pcpu_tfms, cpu) = NULL;
		}
		dst = per_cpu(zcache_dstmem, cpu);
		kfree(dst);
		per_cpu(zcache_dstmem, cpu) = NULL;
		break;
	default:
		break;
	}
	return NOTIFY_OK;
}

static int zcache_cpu_notifier(struct notifier_block *nb,
				unsigned long action, void *pcpu)
{
	unsigned long cpu = (unsigned long)pcpu;

	return __zcache_cpu_notifier(action, cpu);
}

static struct notifier_block zcache_cpu_notifier_block = {
	.notifier_call = zcache_cpu_notifier
};

static int zcache_cpu_init(void)
{
	unsigned long cpu;

	get_online_cpus();
	for_each_online_cpu(cpu)
		if (__zcache_cpu_notifier(CPU_UP_PREPARE, cpu) != NOTIFY_OK)
			goto cleanup;
	register_cpu_notifier(&zcache_cpu_notifier_block);
	put_online_cpus();
	return 0;

cleanup:
	for_each_online_cpu(cpu)
		__zcache_cpu_notifier(CPU_UP_CANCELED, cpu);
	put_online_cpus();
	return -ENOMEM;
}

/*
 * Zcache helpers
 */
static bool zcache_is_full(void)
{
	long file = global_page_state(NR_FILE_PAGES);

	return ((totalram_pages * zcache_max_pool_percent / 100 <
			zcache_pages()) ||
			(totalram_pages * zcache_clear_percent / 100 >
			file));
}

/*
 * The caller must hold zpool->rb_lock at least
 */
static struct zcache_rbnode *zcache_find_rbnode(struct rb_root *rbtree,
	int index, struct rb_node **rb_parent, struct rb_node ***rb_link)
{
	struct zcache_rbnode *entry;
	struct rb_node **__rb_link, *__rb_parent, *rb_prev;

	__rb_link = &rbtree->rb_node;
	rb_prev = __rb_parent = NULL;

	while (*__rb_link) {
		__rb_parent = *__rb_link;
		entry = rb_entry(__rb_parent, struct zcache_rbnode, rb_node);
		if (entry->rb_index > index)
			__rb_link = &__rb_parent->rb_left;
		else if (entry->rb_index < index) {
			rb_prev = __rb_parent;
			__rb_link = &__rb_parent->rb_right;
		} else
			return entry;
	}

	if (rb_parent)
		*rb_parent = __rb_parent;
	if (rb_link)
		*rb_link = __rb_link;
	return NULL;
}

static struct zcache_rbnode *zcache_find_get_rbnode(struct zcache_pool *zpool,
					int rb_index)
{
	unsigned long flags;
	struct zcache_rbnode *rbnode;

	read_lock_irqsave(&zpool->rb_lock, flags);
	rbnode = zcache_find_rbnode(&zpool->rbtree, rb_index, 0, 0);
	if (rbnode)
		kref_get(&rbnode->refcount);
	read_unlock_irqrestore(&zpool->rb_lock, flags);
	return rbnode;
}

/*
 * kref_put callback for zcache_rbnode.
 *
 * The rbnode must have been isolated from rbtree already.
 */
static void zcache_rbnode_release(struct kref *kref)
{
	struct zcache_rbnode *rbnode;

	rbnode = container_of(kref, struct zcache_rbnode, refcount);
	BUG_ON(rbnode->ratree.rnode);
	kmem_cache_free(zcache_rbnode_cache, rbnode);
}

/*
 * Check whether the radix-tree of this rbnode is empty.
 * If that's true, then we can delete this zcache_rbnode from
 * zcache_pool->rbtree
 *
 * Caller must hold zcache_rbnode->ra_lock
 */
static int zcache_rbnode_empty(struct zcache_rbnode *rbnode)
{
	return rbnode->ratree.rnode == NULL;
}

/*
 * Remove zcache_rbnode from zpool->rbtree
 *
 * holded_rblock - whether the caller has holded zpool->rb_lock
 */
static void zcache_rbnode_isolate(struct zcache_pool *zpool,
		struct zcache_rbnode *rbnode, bool holded_rblock)
{
	unsigned long flags;

	if (!holded_rblock)
		write_lock_irqsave(&zpool->rb_lock, flags);
	/*
	 * Someone can get reference on this rbnode before we could
	 * acquire write lock above.
	 * We want to remove it from zpool->rbtree when only the caller and
	 * corresponding ratree holds a reference to this rbnode.
	 * Below check ensures that a racing zcache put will not end up adding
	 * a page to an isolated node and thereby losing that memory.
	 */
	if (atomic_read(&rbnode->refcount.refcount) == 2) {
		rb_erase(&rbnode->rb_node, &zpool->rbtree);
		RB_CLEAR_NODE(&rbnode->rb_node);
		kref_put(&rbnode->refcount, zcache_rbnode_release);
	}
	if (!holded_rblock)
		write_unlock_irqrestore(&zpool->rb_lock, flags);
}

/*
 * Store zaddr which allocated by zbud_alloc() to the hierarchy rbtree-ratree.
 */
static int zcache_store_zaddr(struct zcache_pool *zpool,
		int ra_index, int rb_index, unsigned long zaddr)
{
	unsigned long flags;
	struct zcache_rbnode *rbnode, *tmp;
	struct rb_node **link = NULL, *parent = NULL;
	int ret;
	void *dup_zaddr;

	rbnode = zcache_find_get_rbnode(zpool, rb_index);
	if (!rbnode) {
		/* alloc and init a new rbnode */
		rbnode = kmem_cache_alloc(zcache_rbnode_cache,
			GFP_ZCACHE);
		if (!rbnode)
			return -ENOMEM;

		INIT_RADIX_TREE(&rbnode->ratree, GFP_ATOMIC|__GFP_NOWARN);
		spin_lock_init(&rbnode->ra_lock);
		rbnode->rb_index = rb_index;
		kref_init(&rbnode->refcount);
		RB_CLEAR_NODE(&rbnode->rb_node);

		/* add that rbnode to rbtree */
		write_lock_irqsave(&zpool->rb_lock, flags);
		tmp = zcache_find_rbnode(&zpool->rbtree, rb_index,
				&parent, &link);
		if (tmp) {
			/* somebody else allocated new rbnode */
			kmem_cache_free(zcache_rbnode_cache, rbnode);
			rbnode = tmp;
		} else {
			rb_link_node(&rbnode->rb_node, parent, link);
			rb_insert_color(&rbnode->rb_node, &zpool->rbtree);
		}

		/* Inc the reference of this zcache_rbnode */
		kref_get(&rbnode->refcount);
		write_unlock_irqrestore(&zpool->rb_lock, flags);
	}

	/* Succfully got a zcache_rbnode when arriving here */
	spin_lock_irqsave(&rbnode->ra_lock, flags);
	dup_zaddr = radix_tree_delete(&rbnode->ratree, ra_index);
	if (unlikely(dup_zaddr)) {
		WARN_ON("duplicated, will be replaced!\n");
		if (dup_zaddr == ZERO_HANDLE) {
			atomic_dec(&zcache_stored_zero_pages);
		} else {
			zbud_free(zpool->pool, (unsigned long)dup_zaddr);
			atomic_dec(&zcache_stored_pages);
			zpool->size = zbud_get_pool_size(zpool->pool);
		}
		zcache_dup_entry++;
	}

	/* Insert zcache_ra_handle to ratree */
	ret = radix_tree_insert(&rbnode->ratree, ra_index,
				(void *)zaddr);
	spin_unlock_irqrestore(&rbnode->ra_lock, flags);
	if (unlikely(ret)) {
		write_lock_irqsave(&zpool->rb_lock, flags);
		spin_lock(&rbnode->ra_lock);

		if (zcache_rbnode_empty(rbnode))
			zcache_rbnode_isolate(zpool, rbnode, 1);

		spin_unlock(&rbnode->ra_lock);
		write_unlock_irqrestore(&zpool->rb_lock, flags);
	}

	kref_put(&rbnode->refcount, zcache_rbnode_release);
	return ret;
}

/*
 * Load zaddr and delete it from radix tree.
 * If the radix tree of the corresponding rbnode is empty, delete the rbnode
 * from zpool->rbtree also.
 */
static void *zcache_load_delete_zaddr(struct zcache_pool *zpool,
				int rb_index, int ra_index)
{
	struct zcache_rbnode *rbnode;
	void *zaddr = NULL;
	unsigned long flags;

	rbnode = zcache_find_get_rbnode(zpool, rb_index);
	if (!rbnode)
		goto out;

	BUG_ON(rbnode->rb_index != rb_index);

	spin_lock_irqsave(&rbnode->ra_lock, flags);
	zaddr = radix_tree_delete(&rbnode->ratree, ra_index);
	spin_unlock_irqrestore(&rbnode->ra_lock, flags);

	/* rb_lock and ra_lock must be taken again in the given sequence */
	write_lock_irqsave(&zpool->rb_lock, flags);
	spin_lock(&rbnode->ra_lock);
	if (zcache_rbnode_empty(rbnode))
		zcache_rbnode_isolate(zpool, rbnode, 1);
	spin_unlock(&rbnode->ra_lock);
	write_unlock_irqrestore(&zpool->rb_lock, flags);

	kref_put(&rbnode->refcount, zcache_rbnode_release);
out:
	return zaddr;
}

static bool zero_page(struct page *page)
{
	unsigned long *ptr = kmap_atomic(page);
	int i;
	bool ret = false;

	for (i = 0; i < PAGE_SIZE / sizeof(*ptr); i++) {
		if (ptr[i])
			goto out;
	}
	ret = true;
out:
	kunmap_atomic(ptr);
	return ret;
}

static void zcache_store_page(int pool_id, struct cleancache_filekey key,
		pgoff_t index, struct page *page)
{
	struct zcache_ra_handle *zhandle;
	u8 *zpage, *src, *dst;
	/* Address of zhandle + compressed data(zpage) */
	unsigned long zaddr = 0;
	unsigned int zlen = PAGE_SIZE;
	bool zero = 0;
	int ret;

	struct zcache_pool *zpool = zcache.pools[pool_id];

	/*
	 * Zcache will be ineffective if the compressed memory pool is full with
	 * compressed inactive file pages and most of them will never be used
	 * again.
	 * So we refuse to compress pages that are not from active file list.
	 */
	if (!PageWasActive(page)) {
		zcache_inactive_pages_refused++;
		return;
	}

	zero = zero_page(page);
	if (zero)
		goto zero;

	if (zcache_is_full()) {
		zcache_pool_limit_hit++;
		if (zbud_reclaim_page(zpool->pool, 8)) {
			zcache_reclaim_fail++;
			return;
		}
		/*
		 * Continue if reclaimed a page frame succ.
		 */
		zcache_evict_filepages++;
		zpool->size = zbud_get_pool_size(zpool->pool);
	}

	/* compress */
	dst = get_cpu_var(zcache_dstmem);
	src = kmap_atomic(page);
	ret = zcache_comp_op(ZCACHE_COMPOP_COMPRESS, src, PAGE_SIZE, dst,
			&zlen);
	kunmap_atomic(src);
	if (ret) {
		pr_err("zcache compress error ret %d\n", ret);
		put_cpu_var(zcache_dstmem);
		return;
	}

	/* store zcache handle together with compressed page data */
	ret = zbud_alloc(zpool->pool, zlen + sizeof(struct zcache_ra_handle),
			GFP_ZCACHE, &zaddr);
	if (ret) {
		zcache_zbud_alloc_fail++;
		put_cpu_var(zcache_dstmem);
		return;
	}

	zhandle = (struct zcache_ra_handle *)zbud_map(zpool->pool, zaddr);

	/* Compressed page data stored at the end of zcache_ra_handle */
	zpage = (u8 *)(zhandle + 1);
	memcpy(zpage, dst, zlen);
	zbud_unmap(zpool->pool, zaddr);
	put_cpu_var(zcache_dstmem);

zero:
	if (zero)
		zaddr = (unsigned long)ZERO_HANDLE;

	/* store zcache handle */
	ret = zcache_store_zaddr(zpool, index, key.u.ino, zaddr);
	if (ret) {
		zcache_store_failed++;
		if (!zero)
			zbud_free(zpool->pool, zaddr);
		return;
	}

	/* update stats */
	if (zero) {
		atomic_inc(&zcache_stored_zero_pages);
	} else {
		zhandle->ra_index = index;
		zhandle->rb_index = key.u.ino;
		zhandle->zlen = zlen;
		zhandle->zpool = zpool;
		atomic_inc(&zcache_stored_pages);
		zpool->size = zbud_get_pool_size(zpool->pool);
	}

	return;
}

static int zcache_load_page(int pool_id, struct cleancache_filekey key,
			pgoff_t index, struct page *page)
{
	int ret = 0;
	u8 *src, *dst;
	void *zaddr;
	unsigned int dlen = PAGE_SIZE;
	struct zcache_ra_handle *zhandle;
	struct zcache_pool *zpool = zcache.pools[pool_id];

	zaddr = zcache_load_delete_zaddr(zpool, key.u.ino, index);
	if (!zaddr)
		return -ENOENT;
	else if (zaddr == ZERO_HANDLE)
		goto map;

	zhandle = (struct zcache_ra_handle *)zbud_map(zpool->pool,
			(unsigned long)zaddr);
	/* Compressed page data stored at the end of zcache_ra_handle */
	src = (u8 *)(zhandle + 1);

	/* decompress */
map:
	dst = kmap_atomic(page);
	if (zaddr != ZERO_HANDLE) {
		ret = zcache_comp_op(ZCACHE_COMPOP_DECOMPRESS, src,
				zhandle->zlen, dst, &dlen);
	} else {
		memset(dst, 0, PAGE_SIZE);
		kunmap_atomic(dst);
		flush_dcache_page(page);
		atomic_dec(&zcache_stored_zero_pages);
		goto out;
	}
	kunmap_atomic(dst);
	zbud_unmap(zpool->pool, (unsigned long)zaddr);
	zbud_free(zpool->pool, (unsigned long)zaddr);

	BUG_ON(ret);
	BUG_ON(dlen != PAGE_SIZE);

	/* update stats */
	atomic_dec(&zcache_stored_pages);
	zpool->size = zbud_get_pool_size(zpool->pool);
out:
	SetPageWasActive(page);
	return ret;
}

static void zcache_flush_page(int pool_id, struct cleancache_filekey key,
			pgoff_t index)
{
	struct zcache_pool *zpool = zcache.pools[pool_id];
	void *zaddr = NULL;

	zaddr = zcache_load_delete_zaddr(zpool, key.u.ino, index);
	if (zaddr && (zaddr != ZERO_HANDLE)) {
		zbud_free(zpool->pool, (unsigned long)zaddr);
		atomic_dec(&zcache_stored_pages);
		zpool->size = zbud_get_pool_size(zpool->pool);
	} else if (zaddr == ZERO_HANDLE) {
		atomic_dec(&zcache_stored_zero_pages);
	}
}

#define FREE_BATCH 16
/*
 * Callers must hold the lock
 */
static void zcache_flush_ratree(struct zcache_pool *zpool,
		struct zcache_rbnode *rbnode)
{
	unsigned long index = 0;
	int count, i;
	struct zcache_ra_handle *zhandle;
	void *zaddr = NULL;

	do {
		void *zaddrs[FREE_BATCH];
		unsigned long indices[FREE_BATCH];

		count = radix_tree_gang_lookup_index(&rbnode->ratree,
				(void **)zaddrs, indices,
				index, FREE_BATCH);

		for (i = 0; i < count; i++) {
			if (zaddrs[i] == ZERO_HANDLE) {
				zaddr = radix_tree_delete(&rbnode->ratree,
					indices[i]);
				if (zaddr)
					atomic_dec(&zcache_stored_zero_pages);
				continue;
			}
			zhandle = (struct zcache_ra_handle *)zbud_map(
					zpool->pool, (unsigned long)zaddrs[i]);
			index = zhandle->ra_index;
			zaddr = radix_tree_delete(&rbnode->ratree, index);
			if (!zaddr)
				continue;
			zbud_unmap(zpool->pool, (unsigned long)zaddrs[i]);
			zbud_free(zpool->pool, (unsigned long)zaddrs[i]);
			atomic_dec(&zcache_stored_pages);
			zpool->size = zbud_get_pool_size(zpool->pool);
		}

		index++;
	} while (count == FREE_BATCH);
}

static void zcache_flush_inode(int pool_id, struct cleancache_filekey key)
{
	struct zcache_rbnode *rbnode;
	unsigned long flags1, flags2;
	struct zcache_pool *zpool = zcache.pools[pool_id];

	/*
	 * Refuse new pages added in to the same rbinode, so get rb_lock at
	 * first.
	 */
	write_lock_irqsave(&zpool->rb_lock, flags1);
	rbnode = zcache_find_rbnode(&zpool->rbtree, key.u.ino, 0, 0);
	if (!rbnode) {
		write_unlock_irqrestore(&zpool->rb_lock, flags1);
		return;
	}

	kref_get(&rbnode->refcount);
	spin_lock_irqsave(&rbnode->ra_lock, flags2);

	zcache_flush_ratree(zpool, rbnode);
	if (zcache_rbnode_empty(rbnode))
		/* When arrvied here, we already hold rb_lock */
		zcache_rbnode_isolate(zpool, rbnode, 1);

	spin_unlock_irqrestore(&rbnode->ra_lock, flags2);
	write_unlock_irqrestore(&zpool->rb_lock, flags1);
	kref_put(&rbnode->refcount, zcache_rbnode_release);
}

static void zcache_destroy_pool(struct zcache_pool *zpool);
static void zcache_flush_fs(int pool_id)
{
	struct zcache_rbnode *z_rbnode = NULL;
	struct rb_node *rbnode;
	unsigned long flags1, flags2;
	struct zcache_pool *zpool;

	if (pool_id < 0)
		return;

	zpool = zcache.pools[pool_id];
	if (!zpool)
		return;

	/*
	 * Refuse new pages added in, so get rb_lock at first.
	 */
	write_lock_irqsave(&zpool->rb_lock, flags1);

	rbnode = rb_first(&zpool->rbtree);
	while (rbnode) {
		z_rbnode = rb_entry(rbnode, struct zcache_rbnode, rb_node);
		rbnode = rb_next(rbnode);
		if (z_rbnode) {
			kref_get(&z_rbnode->refcount);
			spin_lock_irqsave(&z_rbnode->ra_lock, flags2);
			zcache_flush_ratree(zpool, z_rbnode);
			if (zcache_rbnode_empty(z_rbnode))
				zcache_rbnode_isolate(zpool, z_rbnode, 1);
			spin_unlock_irqrestore(&z_rbnode->ra_lock, flags2);
			kref_put(&z_rbnode->refcount, zcache_rbnode_release);
		}
	}

	write_unlock_irqrestore(&zpool->rb_lock, flags1);
	zcache_destroy_pool(zpool);
}

/*
 * Evict compressed pages from zcache pool on an LRU basis after the compressed
 * pool is full.
 */
static int zcache_evict_zpage(struct zbud_pool *pool, unsigned long zaddr)
{
	struct zcache_pool *zpool;
	struct zcache_ra_handle *zhandle;
	void *zaddr_intree;

	BUG_ON(zaddr == (unsigned long)ZERO_HANDLE);

	zhandle = (struct zcache_ra_handle *)zbud_map(pool, zaddr);

	zpool = zhandle->zpool;
	/* There can be a race with zcache store */
	if (!zpool)
		return -EINVAL;

	BUG_ON(pool != zpool->pool);

	zaddr_intree = zcache_load_delete_zaddr(zpool, zhandle->rb_index,
			zhandle->ra_index);
	if (zaddr_intree) {
		BUG_ON((unsigned long)zaddr_intree != zaddr);
		zbud_unmap(pool, zaddr);
		zbud_free(pool, zaddr);
		atomic_dec(&zcache_stored_pages);
		zpool->size = zbud_get_pool_size(pool);
		zcache_evict_zpages++;
	}
	return 0;
}

static struct zbud_ops zcache_zbud_ops = {
	.evict = zcache_evict_zpage
};

/* Return pool id */
static int zcache_create_pool(void)
{
	int ret;
	struct zcache_pool *zpool;

	zpool = kzalloc(sizeof(*zpool), GFP_KERNEL);
	if (!zpool) {
		ret = -ENOMEM;
		goto out;
	}

	zpool->pool = zbud_create_pool(GFP_KERNEL, &zcache_zbud_ops);
	if (!zpool->pool) {
		kfree(zpool);
		ret = -ENOMEM;
		goto out;
	}

	spin_lock(&zcache.pool_lock);
	if (zcache.num_pools == MAX_ZCACHE_POOLS) {
		pr_err("Cannot create new pool (limit:%u)\n", MAX_ZCACHE_POOLS);
		zbud_destroy_pool(zpool->pool);
		kfree(zpool);
		ret = -EPERM;
		goto out_unlock;
	}

	rwlock_init(&zpool->rb_lock);
	zpool->rbtree = RB_ROOT;
	/* Add to pool list */
	for (ret = 0; ret < MAX_ZCACHE_POOLS; ret++)
		if (!zcache.pools[ret])
			break;
	zcache.pools[ret] = zpool;
	zcache.num_pools++;
	pr_info("New pool created id:%d\n", ret);

out_unlock:
	spin_unlock(&zcache.pool_lock);
out:
	return ret;
}

static void zcache_destroy_pool(struct zcache_pool *zpool)
{
	int i;

	if (!zpool)
		return;

	spin_lock(&zcache.pool_lock);
	zcache.num_pools--;
	for (i = 0; i < MAX_ZCACHE_POOLS; i++)
		if (zcache.pools[i] == zpool)
			break;
	zcache.pools[i] = NULL;
	spin_unlock(&zcache.pool_lock);

	if (!RB_EMPTY_ROOT(&zpool->rbtree))
		WARN_ON("Memory leak detected. Freeing non-empty pool!\n");

	zbud_destroy_pool(zpool->pool);
	kfree(zpool);
}

static int zcache_init_fs(size_t pagesize)
{
	int ret;

	if (pagesize != PAGE_SIZE) {
		pr_info("Unsupported page size: %zu", pagesize);
		ret = -EINVAL;
		goto out;
	}

	ret = zcache_create_pool();
	if (ret < 0) {
		pr_info("Failed to create new pool\n");
		ret = -ENOMEM;
		goto out;
	}
out:
	return ret;
}

static int zcache_init_shared_fs(char *uuid, size_t pagesize)
{
	/* shared pools are unsupported and map to private */
	return zcache_init_fs(pagesize);
}

static struct cleancache_ops zcache_ops = {
	.put_page = zcache_store_page,
	.get_page = zcache_load_page,
	.invalidate_page = zcache_flush_page,
	.invalidate_inode = zcache_flush_inode,
	.invalidate_fs = zcache_flush_fs,
	.init_shared_fs = zcache_init_shared_fs,
	.init_fs = zcache_init_fs
};

/*
 * Debugfs functions
 */
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>

static int pool_pages_get(void *_data, u64 *val)
{
	*val = zcache_pages();
	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(pool_page_fops, pool_pages_get, NULL, "%llu\n");

static struct dentry *zcache_debugfs_root;

static int __init zcache_debugfs_init(void)
{
	if (!debugfs_initialized())
		return -ENODEV;

	zcache_debugfs_root = debugfs_create_dir("zcache", NULL);
	if (!zcache_debugfs_root)
		return -ENOMEM;

	debugfs_create_u64("pool_limit_hit", S_IRUGO, zcache_debugfs_root,
			&zcache_pool_limit_hit);
	debugfs_create_u64("reject_alloc_fail", S_IRUGO, zcache_debugfs_root,
			&zcache_zbud_alloc_fail);
	debugfs_create_u64("duplicate_entry", S_IRUGO, zcache_debugfs_root,
			&zcache_dup_entry);
	debugfs_create_file("pool_pages", S_IRUGO, zcache_debugfs_root, NULL,
			&pool_page_fops);
	debugfs_create_atomic_t("stored_pages", S_IRUGO, zcache_debugfs_root,
			&zcache_stored_pages);
	debugfs_create_atomic_t("stored_zero_pages", S_IRUGO,
			zcache_debugfs_root, &zcache_stored_zero_pages);
	debugfs_create_u64("evicted_zpages", S_IRUGO, zcache_debugfs_root,
			&zcache_evict_zpages);
	debugfs_create_u64("evicted_filepages", S_IRUGO, zcache_debugfs_root,
			&zcache_evict_filepages);
	debugfs_create_u64("reclaim_fail", S_IRUGO, zcache_debugfs_root,
			&zcache_reclaim_fail);
	debugfs_create_u64("inactive_pages_refused", S_IRUGO,
			zcache_debugfs_root, &zcache_inactive_pages_refused);
	debugfs_create_u64("pool_shrink_count", S_IRUGO,
			zcache_debugfs_root, &zcache_pool_shrink);
	debugfs_create_u64("pool_shrink_fail", S_IRUGO,
			zcache_debugfs_root, &zcache_pool_shrink_fail);
	debugfs_create_u64("pool_shrink_pages", S_IRUGO,
			zcache_debugfs_root, &zcache_pool_shrink_pages);
	debugfs_create_u64("store_fail", S_IRUGO,
			zcache_debugfs_root, &zcache_store_failed);
	return 0;
}

static void __exit zcache_debugfs_exit(void)
{
	debugfs_remove_recursive(zcache_debugfs_root);
}
#else
static int __init zcache_debugfs_init(void)
{
	return 0;
}
static void __exit zcache_debugfs_exit(void)
{
}
#endif

/*
 * zcache init and exit
 */
static int __init init_zcache(void)
{
	if (!zcache_enabled)
		return 0;

	pr_info("loading zcache..\n");
	if (zcache_rbnode_cache_create()) {
		pr_err("entry cache creation failed\n");
		goto error;
	}

	if (zcache_comp_init()) {
		pr_err("compressor initialization failed\n");
		goto compfail;
	}
	if (zcache_cpu_init()) {
		pr_err("per-cpu initialization failed\n");
		goto pcpufail;
	}

	spin_lock_init(&zcache.pool_lock);
	cleancache_register_ops(&zcache_ops);

	if (zcache_debugfs_init())
		pr_warn("debugfs initialization failed\n");
	register_shrinker(&zcache_shrinker);
	return 0;
pcpufail:
	zcache_comp_exit();
compfail:
	zcache_rbnode_cache_destroy();
error:
	return -ENOMEM;
}

/* must be late so crypto has time to come up */
late_initcall(init_zcache);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Bob Liu <bob.liu@xxxxxxxxxx>");
MODULE_DESCRIPTION("Compressed cache for clean file pages");

