/*
 * Copyright (c) 2008, Daniel Phillips
 * Copyright (c) 2008, OGAWA Hirofumi
 * Licensed under the GPL version 2
 */

#include "tux3.h"
#include "filemap_hole.h"
#ifdef __KERNEL__
#include <linux/module.h>
#include <linux/statfs.h>
#include "kcompat.h"

/* This will go to include/linux/magic.h */
#ifndef TUX3_SUPER_MAGIC
#define TUX3_SUPER_MAGIC	0x74757833
#endif

#define trace trace_on

/* FIXME: this should be mount option? */
int tux3_trace;
module_param(tux3_trace, int, 0644);
#endif

#ifdef __KERNEL__
#define BUFFER_LINK	b_assoc_buffers
#else
#define BUFFER_LINK	link
#endif

static void cleanup_dirty_buffers(struct inode *inode, struct list_head *head,
				  unsigned delta)
{
	struct buffer_head *buffer, *n;

	list_for_each_entry_safe(buffer, n, head, BUFFER_LINK) {
		trace(">>> clean inum %Lx, buffer %Lx, count %d",
		      tux_inode(inode)->inum, bufindex(buffer),
		      bufcount(buffer));
		assert(buffer_dirty(buffer));
		tux3_clear_buffer_dirty(buffer, delta);
	}
}

static void cleanup_dirty_inode(struct inode *inode)
{
	if (inode->i_state & I_DIRTY) {
		trace(">>> clean inum %Lx, i_count %d, i_state %lx",
		      tux_inode(inode)->inum, atomic_read(&inode->i_count),
		      inode->i_state);
		cancel_defer_alloc_inum(inode);
		tux3_clear_dirty_inode(inode);
	}
}

/*
 * Some inode/buffers are always (re-)dirtied, so we have to cleanup
 * those for umount.
 */
static void cleanup_dirty_for_umount(struct sb *sb)
{
	unsigned unify = sb->unify;
	struct list_head *head;

	/*
	 * Pinned buffer and bitmap are not flushing always, it is
	 * normal. So, this clean those for unmount.
	 */
	if (sb->bitmap) {
		head = tux3_dirty_buffers(sb->bitmap, unify);
		cleanup_dirty_buffers(sb->bitmap, head, unify);
		cleanup_dirty_inode(sb->bitmap);
	}
	if (sb->countmap) {
		head = tux3_dirty_buffers(sb->countmap, unify);
		cleanup_dirty_buffers(sb->countmap, head, unify);
		cleanup_dirty_inode(sb->countmap);
	}
	if (sb->volmap) {
		cleanup_dirty_buffers(sb->volmap, &sb->unify_buffers, unify);
		/*
		 * FIXME: mark_buffer_dirty() for unify buffers marks
		 * volmap as I_DIRTY_PAGES (we don't need I_DIRTY_PAGES
		 * actually) without changing tuxnode->flags.
		 *
		 * So this is called to clear I_DIRTY_PAGES.
		 */
		cleanup_dirty_inode(sb->volmap);
	}

	/* orphan_add should be empty */
	assert(list_empty(&sb->orphan_add));
	/* Deferred orphan deletion request is not flushed for each delta  */
	clean_orphan_list(&sb->orphan_del);

	/* defree must be flushed for each delta */
	assert(flink_empty(&sb->defree.head)||flink_is_last(&sb->defree.head));
}

static void __tux3_put_super(struct sb *sbi)
{
	cleanup_dirty_for_umount(sbi);

	/* All forked buffers should be freed here */
	free_forked_buffers(sbi, NULL, 1);

	destroy_defer_bfree(&sbi->deunify);
	destroy_defer_bfree(&sbi->defree);

	countmap_put(&sbi->countmap_pin);

	iput(sbi->rootdir);
	sbi->rootdir = NULL;
	iput(sbi->atable);
	sbi->atable = NULL;
	iput(sbi->vtable);
	sbi->vtable = NULL;
	iput(sbi->bitmap);
	sbi->bitmap = NULL;
	iput(sbi->countmap);
	sbi->countmap = NULL;
	iput(sbi->logmap);
	sbi->logmap = NULL;
	iput(sbi->volmap);
	sbi->volmap = NULL;

	/* Cleanup flusher after inode was evicted */
	tux3_exit_flusher(sbi);

	tux3_free_idefer_map(sbi->idefer_map);
	sbi->idefer_map = NULL;
	/* FIXME: add more sanity check */
	assert(list_empty(&sbi->alloc_inodes));
	assert(link_empty(&sbi->forked_buffers));
}

static struct inode *create_internal_inode(struct sb *sbi, inum_t inum,
					   struct tux_iattr *iattr)
{
	static struct tux_iattr null_iattr;
	struct inode *dir = &(struct inode){
		.i_sb = vfs_sb(sbi),
		.i_mode = S_IFDIR | 0755,
	};
	struct inode *inode;

	if (iattr == NULL)
		iattr = &null_iattr;

	inode = tux_create_specific_inode(dir, inum, iattr, 0);
	if (!IS_ERR(inode)) {
		assert(tux_inode(inode)->inum == inum);
		unlock_new_inode(inode);
	}
	return inode;
}

/*
 * Internal inode (e.g. bitmap inode) yet may not be written. So, if
 * there is no inode, create inode instead.
 */
static struct inode *iget_or_create_inode(struct sb *sbi, inum_t inum)
{
	struct inode *inode;

	inode = tux3_iget(sbi, inum);
	if (IS_ERR(inode) && PTR_ERR(inode) == -ENOENT)
		inode = create_internal_inode(sbi, inum, NULL);
	return inode;
}

struct replay *tux3_init_fs(struct sb *sbi)
{
	struct replay *rp = NULL;
	struct inode *inode;
	char *name;
	int err;

	/* Initialize flusher before setup inode */
	err = tux3_init_flusher(sbi);
	if (err) {
		tux3_err(sbi, "failed to initialize flusher");
		goto error;
	}

	err = -ENOMEM;

	/* Prepare non on-disk inodes */
	sbi->volmap = tux_new_volmap(sbi);
	if (!sbi->volmap)
		goto error;

	sbi->logmap = tux_new_logmap(sbi);
	if (!sbi->logmap)
		goto error;

	/* Replay physical structures */
	rp = replay_stage1(sbi);
	if (IS_ERR(rp)) {
		err = PTR_ERR(rp);
		goto error;
	}

	/* Load internal inodes */
	inode = iget_or_create_inode(sbi, TUX_BITMAP_INO);
	if (IS_ERR(inode)) {
		name = "bitmap";
		goto error_inode;
	}
	sbi->bitmap = inode;

	inode = iget_or_create_inode(sbi, TUX_COUNTMAP_INO);
	if (IS_ERR(inode)) {
		name = "countmap";
		goto error_inode;
	}
	sbi->countmap = inode;
#if 0
	inode = tux3_iget(sbi, TUX_VTABLE_INO);
	if (IS_ERR(inode)) {
		name = "vtable";
		goto error_inode;
	}
	sbi->vtable = inode;
#endif
	inode = tux3_iget(sbi, TUX_ATABLE_INO);
	if (IS_ERR(inode)) {
		name = "atable";
		goto error_inode;
	}
	sbi->atable = inode;

	inode = tux3_iget(sbi, TUX_ROOTDIR_INO);
	if (IS_ERR(inode)) {
		name = "rootdir";
		goto error_inode;
	}
	sbi->rootdir = inode;

	err = replay_stage2(rp);
	if (err) {
		rp = NULL;
		goto error;
	}

	return rp;

error_inode:
	err = PTR_ERR(inode);
	tux3_err(sbi, "failed to load %s inode (err %d)", name, err);
error:
	if (!IS_ERR_OR_NULL(rp))
		replay_stage3(rp, 0);
	__tux3_put_super(sbi);

	return ERR_PTR(err);
}

static void tux3_inode_init_once(void *mem)
{
	struct tux3_inode *tuxnode = mem;
	struct inode *inode = &tuxnode->vfs_inode;
	int i;

	INIT_LIST_HEAD(&tuxnode->alloc_list);
	INIT_LIST_HEAD(&tuxnode->orphan_list);
	spin_lock_init(&tuxnode->hole_extents_lock);
	INIT_LIST_HEAD(&tuxnode->hole_extents);
	init_rwsem(&tuxnode->truncate_lock);
	spin_lock_init(&tuxnode->lock);
	/* Initialize inode_delta_dirty */
	for (i = 0; i < ARRAY_SIZE(tuxnode->i_ddc); i++) {
		INIT_LIST_HEAD(&tuxnode->i_ddc[i].dirty_buffers);
		INIT_LIST_HEAD(&tuxnode->i_ddc[i].dirty_holes);
		INIT_LIST_HEAD(&tuxnode->i_ddc[i].dirty_list);
		/* For debugging, set invalid value to ->present */
		tuxnode->i_ddc[i].idata.present = TUX3_INVALID_PRESENT;
	}

	/* Initialize generic part */
	inode_init_once(inode);
}

static void tux3_inode_init_always(struct tux3_inode *tuxnode)
{
	static struct timespec epoch;
	struct inode *inode = &tuxnode->vfs_inode;

	tuxnode->btree		= (struct btree){ };
	tuxnode->present	= 0;
	tuxnode->xcache		= NULL;
	tuxnode->flags		= 0;
#ifdef __KERNEL__
	tuxnode->io		= NULL;
#endif

	/* uninitialized stuff by alloc_inode() */
	inode->i_version	= 1;
	inode->i_atime		= epoch;
	inode->i_mtime		= epoch;
	inode->i_ctime		= epoch;
	inode->i_mode		= 0;
}

static int i_ddc_is_clean(struct inode *inode)
{
	struct tux3_inode *tuxnode = tux_inode(inode);
	int i;

	for (i = 0; i < ARRAY_SIZE(tuxnode->i_ddc); i++) {
		if (!list_empty(&tuxnode->i_ddc[i].dirty_buffers) ||
		    !list_empty(&tuxnode->i_ddc[i].dirty_list))
			return 0;
	}

	return 1;
}

static void tux3_check_destroy_inode(struct inode *inode)
{
	tux3_check_destroy_inode_flags(inode);
	assert(list_empty(&tux_inode(inode)->alloc_list));
	assert(list_empty(&tux_inode(inode)->orphan_list));
	assert(i_ddc_is_clean(inode));
}

#ifdef __KERNEL__
static struct kmem_cache *tux_inode_cachep;

static int __init tux3_init_inodecache(void)
{
	tux_inode_cachep = kmem_cache_create("tux3_inode_cache",
			sizeof(struct tux3_inode), 0,
			(SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
			tux3_inode_init_once);
	if (tux_inode_cachep == NULL)
		return -ENOMEM;
	return 0;
}

static void tux3_destroy_inodecache(void)
{
	/*
	 * Make sure all delayed rcu free inodes are flushed before we
	 * destroy cache.
	 */
	rcu_barrier();
	kmem_cache_destroy(tux_inode_cachep);
}

static struct inode *tux3_alloc_inode(struct super_block *sb)
{
	struct tux3_inode *tuxnode;

	tuxnode = kmem_cache_alloc(tux_inode_cachep, GFP_KERNEL);
	if (!tuxnode)
		return NULL;

	tux3_inode_init_always(tuxnode);

	return &tuxnode->vfs_inode;
}

static void tux3_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	kmem_cache_free(tux_inode_cachep, tux_inode(inode));
}

static void tux3_destroy_inode(struct inode *inode)
{
	tux3_check_destroy_inode(inode);
	call_rcu(&inode->i_rcu, tux3_i_callback);
}

#if TUX3_FLUSHER != TUX3_FLUSHER_ASYNC_HACK
static int tux3_sync_fs(struct super_block *sb, int wait)
{
	/* FIXME: We should support "wait" parameter. */
	trace_on("wait (%u) parameter is unsupported for now", wait);
	return force_delta(tux_sb(sb));
}
#endif

static void tux3_put_super(struct super_block *sb)
{
	struct sb *sbi = tux_sb(sb);

	__tux3_put_super(sbi);
	sb->s_fs_info = NULL;
	kfree(sbi);
}

static int tux3_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct super_block *sb = dentry->d_sb;
	struct sb *sbi = tux_sb(sb);

	buf->f_type = sb->s_magic;
	buf->f_bsize = sbi->blocksize;
	buf->f_blocks = sbi->volblocks;
	buf->f_bfree = sbi->freeblocks;
	buf->f_bavail = sbi->freeblocks;
	buf->f_files = MAX_INODES;
	buf->f_ffree = sbi->freeinodes;
#if 0
	buf->f_fsid.val[0] = sbi->serial_number;
	/*buf->f_fsid.val[1];*/
#endif
	buf->f_namelen = TUX_NAME_LEN;
//	buf->f_frsize = sbi->blocksize;

	return 0;
}

static const struct super_operations tux3_super_ops = {
	.alloc_inode	= tux3_alloc_inode,
	.destroy_inode	= tux3_destroy_inode,
	.dirty_inode	= tux3_dirty_inode,
	.drop_inode	= tux3_drop_inode,
	.evict_inode	= tux3_evict_inode,
	/* FIXME: we have to handle write_inode of sync (e.g. cache pressure) */
//	.write_inode	= tux3_write_inode,
#if TUX3_FLUSHER != TUX3_FLUSHER_ASYNC_HACK
	/* If TUX3_FLUSHER_ASYNC_HACK, normal kernel flush request does all */
	.sync_fs	= tux3_sync_fs,
#endif
	.put_super	= tux3_put_super,
	.statfs		= tux3_statfs,
};

static int tux3_fill_super(struct super_block *sb, void *data, int silent)
{
	struct sb *sbi;
	struct replay *rp = NULL;
	int err, blocksize;

	sbi = kzalloc(sizeof(struct sb), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;
	sbi->vfs_sb = sb;
	sb->s_fs_info = sbi;
	/*
	 * FIXME: atime can insert inode into dirty list unexpectedly.
	 * For now, doesn't support and disable atime.
	 */
	sb->s_flags |= MS_NOATIME;
	sb->s_magic = TUX3_SUPER_MAGIC;
	sb->s_op = &tux3_super_ops;
	sb->s_time_gran = 1;

	err = -EIO;
	blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
	if (!blocksize) {
		if (!silent)
			printk(KERN_ERR "TUX3: unable to set blocksize\n");
		goto error_free;
	}

	/* Initialize and load sbi */
	err = load_sb(sbi);
	if (err) {
		if (!silent) {
			if (err == -EINVAL)
				tux3_err(sbi, "invalid superblock [%Lx]",
				     be64_to_cpup((__be64 *)sbi->super.magic));
			else
				tux3_err(sbi, "unable to read superblock");
		}
		goto error;
	}

	if (sbi->blocksize != blocksize) {
		if (!sb_set_blocksize(sb, sbi->blocksize)) {
			tux3_err(sbi, "blocksize too small for device");
			goto error;
		}
	}
	tux3_dbg("s_blocksize %lu", sb->s_blocksize);

	rp = tux3_init_fs(sbi);
	if (IS_ERR(rp)) {
		err = PTR_ERR(rp);
		goto error;
	}

	err = replay_stage3(rp, 1);
	if (err) {
		rp = NULL;
		goto error;
	}

	sb->s_root = d_make_root(sbi->rootdir);
	sbi->rootdir = NULL;	/* vfs takes care rootdir inode */
	if (!sb->s_root) {
		err = -ENOMEM;
		goto error;
	}

	return 0;

error:
	if (!IS_ERR_OR_NULL(rp))
		replay_stage3(rp, 0);
	__tux3_put_super(sbi);
error_free:
	kfree(sbi);

	return err;
}

static struct dentry *tux3_mount(struct file_system_type *fs_type, int flags,
	const char *dev_name, void *data)
{
	return mount_bdev(fs_type, flags, dev_name, data, tux3_fill_super);
}

static struct file_system_type tux3_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "tux3",
	.fs_flags	= FS_REQUIRES_DEV,
	.mount		= tux3_mount,
	.kill_sb	= kill_block_super,
};

static int __init init_tux3(void)
{
	int err;

	err = tux3_init_inodecache();
	if (err)
		goto error;

	err = tux3_init_hole_cache();
	if (err)
		goto error_hole;

	err = tux3_init_idefer_cache();
	if (err)
		goto error_idefer;

	err = register_filesystem(&tux3_fs_type);
	if (err)
		goto error_fs;

	return 0;

error_fs:
	tux3_destroy_idefer_cache();
error_idefer:
	tux3_destroy_hole_cache();
error_hole:
	tux3_destroy_inodecache();
error:
	return err;
}

static void __exit exit_tux3(void)
{
	unregister_filesystem(&tux3_fs_type);
	tux3_destroy_idefer_cache();
	tux3_destroy_hole_cache();
	tux3_destroy_inodecache();
}

module_init(init_tux3);
module_exit(exit_tux3);
MODULE_LICENSE("GPL");
MODULE_ALIAS_FS("tux3");
#endif /* !__KERNEL__ */
