/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v.2.
 */

#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/kthread.h>
#include <linux/gfs2_ondisk.h>

#include "gfs2.h"
#include "lm_interface.h"
#include "incore.h"
#include "bmap.h"
#include "inode.h"
#include "meta_io.h"
#include "trans.h"
#include "unlinked.h"
#include "util.h"

static int munge_ondisk(struct gfs2_sbd *sdp, unsigned int slot,
			struct gfs2_unlinked_tag *ut)
{
	struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
	unsigned int block, offset;
	uint64_t dblock;
	int new = 0;
	struct buffer_head *bh;
	int error;
	int boundary;

	block = slot / sdp->sd_ut_per_block;
	offset = slot % sdp->sd_ut_per_block;

	error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary);
	if (error)
		return error;
	error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh);
	if (error)
		return error;
	if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
		error = -EIO;
		goto out;
	}

	mutex_lock(&sdp->sd_unlinked_mutex);
	gfs2_trans_add_bh(ip->i_gl, bh, 1);
	gfs2_unlinked_tag_out(ut, bh->b_data +
				  sizeof(struct gfs2_meta_header) +
				  offset * sizeof(struct gfs2_unlinked_tag));
	mutex_unlock(&sdp->sd_unlinked_mutex);

 out:
	brelse(bh);

	return error;
}

static void ul_hash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	spin_lock(&sdp->sd_unlinked_spin);
	list_add(&ul->ul_list, &sdp->sd_unlinked_list);
	gfs2_assert(sdp, ul->ul_count);
	ul->ul_count++;
	atomic_inc(&sdp->sd_unlinked_count);
	spin_unlock(&sdp->sd_unlinked_spin);
}

static void ul_unhash(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	spin_lock(&sdp->sd_unlinked_spin);
	list_del_init(&ul->ul_list);
	gfs2_assert(sdp, ul->ul_count > 1);
	ul->ul_count--;
	gfs2_assert_warn(sdp, atomic_read(&sdp->sd_unlinked_count) > 0);
	atomic_dec(&sdp->sd_unlinked_count);
	spin_unlock(&sdp->sd_unlinked_spin);
}

static struct gfs2_unlinked *ul_fish(struct gfs2_sbd *sdp)
{
	struct list_head *head;
	struct gfs2_unlinked *ul;
	int found = 0;

	if (sdp->sd_vfs->s_flags & MS_RDONLY)
		return NULL;

	spin_lock(&sdp->sd_unlinked_spin);

	head = &sdp->sd_unlinked_list;

	list_for_each_entry(ul, head, ul_list) {
		if (test_bit(ULF_LOCKED, &ul->ul_flags))
			continue;

		list_move_tail(&ul->ul_list, head);
		ul->ul_count++;
		set_bit(ULF_LOCKED, &ul->ul_flags);
		found = 1;

		break;
	}

	if (!found)
		ul = NULL;

	spin_unlock(&sdp->sd_unlinked_spin);

	return ul;
}

/**
 * enforce_limit - limit the number of inodes waiting to be deallocated
 * @sdp: the filesystem
 *
 * Returns: errno
 */

static void enforce_limit(struct gfs2_sbd *sdp)
{
	unsigned int tries = 0, min = 0;
	int error;

	if (atomic_read(&sdp->sd_unlinked_count) <
	    gfs2_tune_get(sdp, gt_ilimit))
		return;

	tries = gfs2_tune_get(sdp, gt_ilimit_tries);
	min = gfs2_tune_get(sdp, gt_ilimit_min);

	while (tries--) {
		struct gfs2_unlinked *ul = ul_fish(sdp);
		if (!ul)
			break;
		error = gfs2_inode_dealloc(sdp, ul);
		gfs2_unlinked_put(sdp, ul);

		if (!error) {
			if (!--min)
				break;
		} else if (error != 1)
			break;
	}
}

static struct gfs2_unlinked *ul_alloc(struct gfs2_sbd *sdp)
{
	struct gfs2_unlinked *ul;

	ul = kzalloc(sizeof(struct gfs2_unlinked), GFP_KERNEL);
	if (ul) {
		INIT_LIST_HEAD(&ul->ul_list);
		ul->ul_count = 1;
		set_bit(ULF_LOCKED, &ul->ul_flags);
	}

	return ul;
}

int gfs2_unlinked_get(struct gfs2_sbd *sdp, struct gfs2_unlinked **ul)
{
	unsigned int c, o = 0, b;
	unsigned char byte = 0;

	enforce_limit(sdp);

	*ul = ul_alloc(sdp);
	if (!*ul)
		return -ENOMEM;

	spin_lock(&sdp->sd_unlinked_spin);

	for (c = 0; c < sdp->sd_unlinked_chunks; c++)
		for (o = 0; o < PAGE_SIZE; o++) {
			byte = sdp->sd_unlinked_bitmap[c][o];
			if (byte != 0xFF)
				goto found;
		}

	goto fail;

found:
	for (b = 0; b < 8; b++)
		if (!(byte & (1 << b)))
			break;
	(*ul)->ul_slot = c * (8 * PAGE_SIZE) + o * 8 + b;

	if ((*ul)->ul_slot >= sdp->sd_unlinked_slots)
		goto fail;

	sdp->sd_unlinked_bitmap[c][o] |= 1 << b;

	spin_unlock(&sdp->sd_unlinked_spin);

	return 0;

fail:
	spin_unlock(&sdp->sd_unlinked_spin);
	kfree(*ul);
	return -ENOSPC;
}

void gfs2_unlinked_put(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	gfs2_assert_warn(sdp, test_and_clear_bit(ULF_LOCKED, &ul->ul_flags));

	spin_lock(&sdp->sd_unlinked_spin);
	gfs2_assert(sdp, ul->ul_count);
	ul->ul_count--;
	if (!ul->ul_count) {
		gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, ul->ul_slot, 0);
		spin_unlock(&sdp->sd_unlinked_spin);
		kfree(ul);
	} else
		spin_unlock(&sdp->sd_unlinked_spin);
}

int gfs2_unlinked_ondisk_add(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	int error;

	gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
	gfs2_assert_warn(sdp, list_empty(&ul->ul_list));

	error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);
	if (!error)
		ul_hash(sdp, ul);

	return error;
}

int gfs2_unlinked_ondisk_munge(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	int error;

	gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
	gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));

	error = munge_ondisk(sdp, ul->ul_slot, &ul->ul_ut);

	return error;
}

int gfs2_unlinked_ondisk_rm(struct gfs2_sbd *sdp, struct gfs2_unlinked *ul)
{
	struct gfs2_unlinked_tag ut;
	int error;

	gfs2_assert_warn(sdp, test_bit(ULF_LOCKED, &ul->ul_flags));
	gfs2_assert_warn(sdp, !list_empty(&ul->ul_list));

	memset(&ut, 0, sizeof(struct gfs2_unlinked_tag));

	error = munge_ondisk(sdp, ul->ul_slot, &ut);
	if (error)
		return error;

	ul_unhash(sdp, ul);

	return 0;
}

/**
 * gfs2_unlinked_dealloc - Go through the list of inodes to be deallocated
 * @sdp: the filesystem
 *
 * Returns: errno
 */

int gfs2_unlinked_dealloc(struct gfs2_sbd *sdp)
{
	unsigned int hits, strikes;
	int error;

	for (;;) {
		hits = 0;
		strikes = 0;

		for (;;) {
			struct gfs2_unlinked *ul = ul_fish(sdp);
			if (!ul)
				return 0;
			error = gfs2_inode_dealloc(sdp, ul);
			gfs2_unlinked_put(sdp, ul);

			if (!error) {
				hits++;
				if (strikes)
					strikes--;
			} else if (error == 1) {
				strikes++;
				if (strikes >=
				    atomic_read(&sdp->sd_unlinked_count)) {
					error = 0;
					break;
				}
			} else
				return error;
		}

		if (!hits || kthread_should_stop())
			break;

		cond_resched();
	}

	return 0;
}

int gfs2_unlinked_init(struct gfs2_sbd *sdp)
{
	struct gfs2_inode *ip = sdp->sd_ut_inode->u.generic_ip;
	unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift;
	unsigned int x, slot = 0;
	unsigned int found = 0;
	uint64_t dblock;
	uint32_t extlen = 0;
	int error;

	if (!ip->i_di.di_size ||
	    ip->i_di.di_size > (64 << 20) ||
	    ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1)) {
		gfs2_consist_inode(ip);
		return -EIO;		
	}
	sdp->sd_unlinked_slots = blocks * sdp->sd_ut_per_block;
	sdp->sd_unlinked_chunks = DIV_ROUND_UP(sdp->sd_unlinked_slots,
					       8 * PAGE_SIZE);

	error = -ENOMEM;

	sdp->sd_unlinked_bitmap = kcalloc(sdp->sd_unlinked_chunks,
					  sizeof(unsigned char *),
					  GFP_KERNEL);
	if (!sdp->sd_unlinked_bitmap)
		return error;

	for (x = 0; x < sdp->sd_unlinked_chunks; x++) {
		sdp->sd_unlinked_bitmap[x] = kzalloc(PAGE_SIZE, GFP_KERNEL);
		if (!sdp->sd_unlinked_bitmap[x])
			goto fail;
	}

	for (x = 0; x < blocks; x++) {
		struct buffer_head *bh;
		unsigned int y;

		if (!extlen) {
			int new = 0;
			error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen);
			if (error)
				goto fail;
		}
		gfs2_meta_ra(ip->i_gl, dblock, extlen);
		error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT,
				       &bh);
		if (error)
			goto fail;
		error = -EIO;
		if (gfs2_metatype_check(sdp, bh, GFS2_METATYPE_UT)) {
			brelse(bh);
			goto fail;
		}

		for (y = 0;
		     y < sdp->sd_ut_per_block && slot < sdp->sd_unlinked_slots;
		     y++, slot++) {
			struct gfs2_unlinked_tag ut;
			struct gfs2_unlinked *ul;

			gfs2_unlinked_tag_in(&ut, bh->b_data +
					  sizeof(struct gfs2_meta_header) +
					  y * sizeof(struct gfs2_unlinked_tag));
			if (!ut.ut_inum.no_addr)
				continue;

			error = -ENOMEM;
			ul = ul_alloc(sdp);
			if (!ul) {
				brelse(bh);
				goto fail;
			}
			ul->ul_ut = ut;
			ul->ul_slot = slot;

			spin_lock(&sdp->sd_unlinked_spin);
			gfs2_icbit_munge(sdp, sdp->sd_unlinked_bitmap, slot, 1);
			spin_unlock(&sdp->sd_unlinked_spin);
			ul_hash(sdp, ul);

			gfs2_unlinked_put(sdp, ul);
			found++;
		}

		brelse(bh);
		dblock++;
		extlen--;
	}

	if (found)
		fs_info(sdp, "found %u unlinked inodes\n", found);

	return 0;

fail:
	gfs2_unlinked_cleanup(sdp);
	return error;
}

/**
 * gfs2_unlinked_cleanup - get rid of any extra struct gfs2_unlinked structures
 * @sdp: the filesystem
 *
 */

void gfs2_unlinked_cleanup(struct gfs2_sbd *sdp)
{
	struct list_head *head = &sdp->sd_unlinked_list;
	struct gfs2_unlinked *ul;
	unsigned int x;

	spin_lock(&sdp->sd_unlinked_spin);
	while (!list_empty(head)) {
		ul = list_entry(head->next, struct gfs2_unlinked, ul_list);

		if (ul->ul_count > 1) {
			list_move_tail(&ul->ul_list, head);
			spin_unlock(&sdp->sd_unlinked_spin);
			schedule();
			spin_lock(&sdp->sd_unlinked_spin);
			continue;
		}

		list_del_init(&ul->ul_list);
		atomic_dec(&sdp->sd_unlinked_count);

		gfs2_assert_warn(sdp, ul->ul_count == 1);
		gfs2_assert_warn(sdp, !test_bit(ULF_LOCKED, &ul->ul_flags));
		kfree(ul);
	}
	spin_unlock(&sdp->sd_unlinked_spin);

	gfs2_assert_warn(sdp, !atomic_read(&sdp->sd_unlinked_count));

	if (sdp->sd_unlinked_bitmap) {
		for (x = 0; x < sdp->sd_unlinked_chunks; x++)
			kfree(sdp->sd_unlinked_bitmap[x]);
		kfree(sdp->sd_unlinked_bitmap);
	}
}

