/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 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 <asm/semaphore.h>

#include "gfs2.h"
#include "bmap.h"
#include "inode.h"
#include "meta_io.h"
#include "trans.h"
#include "unlinked.h"

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

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

	error = gfs2_block_map(ip, block, &new, &dblock, NULL);
	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)) {
		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 = get_v2ip(sdp->sd_ut_inode);
	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_RU(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_block_map(ip, 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);
	}
}

