/*
 * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details
 */

#include <linux/config.h>
#include <linux/time.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/reiserfs_fs.h>

/* access to tail : when one is going to read tail it must make sure, that is not running.
 direct2indirect and indirect2direct can not run concurrently */

/* Converts direct items to an unformatted node. Panics if file has no
   tail. -ENOSPC if no disk space for conversion */
/* path points to first direct item of the file regarless of how many of
   them are there */
int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
		    struct path *path, struct buffer_head *unbh,
		    loff_t tail_offset)
{
	struct super_block *sb = inode->i_sb;
	struct buffer_head *up_to_date_bh;
	struct item_head *p_le_ih = PATH_PITEM_HEAD(path);
	unsigned long total_tail = 0;
	struct cpu_key end_key;	/* Key to search for the last byte of the
				   converted item. */
	struct item_head ind_ih;	/* new indirect item to be inserted or
					   key of unfm pointer to be pasted */
	int n_blk_size, n_retval;	/* returned value for reiserfs_insert_item and clones */
	unp_t unfm_ptr;		/* Handle on an unformatted node
				   that will be inserted in the
				   tree. */

	BUG_ON(!th->t_trans_id);

	REISERFS_SB(sb)->s_direct2indirect++;

	n_blk_size = sb->s_blocksize;

	/* and key to search for append or insert pointer to the new
	   unformatted node. */
	copy_item_head(&ind_ih, p_le_ih);
	set_le_ih_k_offset(&ind_ih, tail_offset);
	set_le_ih_k_type(&ind_ih, TYPE_INDIRECT);

	/* Set the key to search for the place for new unfm pointer */
	make_cpu_key(&end_key, inode, tail_offset, TYPE_INDIRECT, 4);

	// FIXME: we could avoid this 
	if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) {
		reiserfs_warning(sb, "PAP-14030: direct2indirect: "
				 "pasted or inserted byte exists in the tree %K. "
				 "Use fsck to repair.", &end_key);
		pathrelse(path);
		return -EIO;
	}

	p_le_ih = PATH_PITEM_HEAD(path);

	unfm_ptr = cpu_to_le32(unbh->b_blocknr);

	if (is_statdata_le_ih(p_le_ih)) {
		/* Insert new indirect item. */
		set_ih_free_space(&ind_ih, 0);	/* delete at nearest future */
		put_ih_item_len(&ind_ih, UNFM_P_SIZE);
		PATH_LAST_POSITION(path)++;
		n_retval =
		    reiserfs_insert_item(th, path, &end_key, &ind_ih, inode,
					 (char *)&unfm_ptr);
	} else {
		/* Paste into last indirect item of an object. */
		n_retval = reiserfs_paste_into_item(th, path, &end_key, inode,
						    (char *)&unfm_ptr,
						    UNFM_P_SIZE);
	}
	if (n_retval) {
		return n_retval;
	}
	// note: from here there are two keys which have matching first
	// three key components. They only differ by the fourth one.

	/* Set the key to search for the direct items of the file */
	make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT,
		     4);

	/* Move bytes from the direct items to the new unformatted node
	   and delete them. */
	while (1) {
		int tail_size;

		/* end_key.k_offset is set so, that we will always have found
		   last item of the file */
		if (search_for_position_by_key(sb, &end_key, path) ==
		    POSITION_FOUND)
			reiserfs_panic(sb,
				       "PAP-14050: direct2indirect: "
				       "direct item (%K) not found", &end_key);
		p_le_ih = PATH_PITEM_HEAD(path);
		RFALSE(!is_direct_le_ih(p_le_ih),
		       "vs-14055: direct item expected(%K), found %h",
		       &end_key, p_le_ih);
		tail_size = (le_ih_k_offset(p_le_ih) & (n_blk_size - 1))
		    + ih_item_len(p_le_ih) - 1;

		/* we only send the unbh pointer if the buffer is not up to date.
		 ** this avoids overwriting good data from writepage() with old data
		 ** from the disk or buffer cache
		 ** Special case: unbh->b_page will be NULL if we are coming through
		 ** DIRECT_IO handler here.
		 */
		if (!unbh->b_page || buffer_uptodate(unbh)
		    || PageUptodate(unbh->b_page)) {
			up_to_date_bh = NULL;
		} else {
			up_to_date_bh = unbh;
		}
		n_retval = reiserfs_delete_item(th, path, &end_key, inode,
						up_to_date_bh);

		total_tail += n_retval;
		if (tail_size == n_retval)
			// done: file does not have direct items anymore
			break;

	}
	/* if we've copied bytes from disk into the page, we need to zero
	 ** out the unused part of the block (it was not up to date before)
	 */
	if (up_to_date_bh) {
		unsigned pgoff =
		    (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
		char *kaddr = kmap_atomic(up_to_date_bh->b_page, KM_USER0);
		memset(kaddr + pgoff, 0, n_blk_size - total_tail);
		kunmap_atomic(kaddr, KM_USER0);
	}

	REISERFS_I(inode)->i_first_direct_byte = U32_MAX;

	return 0;
}

/* stolen from fs/buffer.c */
void reiserfs_unmap_buffer(struct buffer_head *bh)
{
	lock_buffer(bh);
	if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
		BUG();
	}
	clear_buffer_dirty(bh);
	/* Remove the buffer from whatever list it belongs to. We are mostly
	   interested in removing it from per-sb j_dirty_buffers list, to avoid
	   BUG() on attempt to write not mapped buffer */
	if ((!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) {
		struct inode *inode = bh->b_page->mapping->host;
		struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
		spin_lock(&j->j_dirty_buffers_lock);
		list_del_init(&bh->b_assoc_buffers);
		reiserfs_free_jh(bh);
		spin_unlock(&j->j_dirty_buffers_lock);
	}
	clear_buffer_mapped(bh);
	clear_buffer_req(bh);
	clear_buffer_new(bh);
	bh->b_bdev = NULL;
	unlock_buffer(bh);
}

/* this first locks inode (neither reads nor sync are permitted),
   reads tail through page cache, insert direct item. When direct item
   inserted successfully inode is left locked. Return value is always
   what we expect from it (number of cut bytes). But when tail remains
   in the unformatted node, we set mode to SKIP_BALANCING and unlock
   inode */
int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_inode, struct page *page, struct path *p_s_path,	/* path to the indirect item. */
		    const struct cpu_key *p_s_item_key,	/* Key to look for unformatted node pointer to be cut. */
		    loff_t n_new_file_size,	/* New file size. */
		    char *p_c_mode)
{
	struct super_block *p_s_sb = p_s_inode->i_sb;
	struct item_head s_ih;
	unsigned long n_block_size = p_s_sb->s_blocksize;
	char *tail;
	int tail_len, round_tail_len;
	loff_t pos, pos1;	/* position of first byte of the tail */
	struct cpu_key key;

	BUG_ON(!th->t_trans_id);

	REISERFS_SB(p_s_sb)->s_indirect2direct++;

	*p_c_mode = M_SKIP_BALANCING;

	/* store item head path points to. */
	copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));

	tail_len = (n_new_file_size & (n_block_size - 1));
	if (get_inode_sd_version(p_s_inode) == STAT_DATA_V2)
		round_tail_len = ROUND_UP(tail_len);
	else
		round_tail_len = tail_len;

	pos =
	    le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE -
					 1) * p_s_sb->s_blocksize;
	pos1 = pos;

	// we are protected by i_sem. The tail can not disapper, not
	// append can be done either
	// we are in truncate or packing tail in file_release

	tail = (char *)kmap(page);	/* this can schedule */

	if (path_changed(&s_ih, p_s_path)) {
		/* re-search indirect item */
		if (search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path)
		    == POSITION_NOT_FOUND)
			reiserfs_panic(p_s_sb,
				       "PAP-5520: indirect2direct: "
				       "item to be converted %K does not exist",
				       p_s_item_key);
		copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
#ifdef CONFIG_REISERFS_CHECK
		pos = le_ih_k_offset(&s_ih) - 1 +
		    (ih_item_len(&s_ih) / UNFM_P_SIZE -
		     1) * p_s_sb->s_blocksize;
		if (pos != pos1)
			reiserfs_panic(p_s_sb, "vs-5530: indirect2direct: "
				       "tail position changed while we were reading it");
#endif
	}

	/* Set direct item header to insert. */
	make_le_item_head(&s_ih, NULL, get_inode_item_key_version(p_s_inode),
			  pos1 + 1, TYPE_DIRECT, round_tail_len,
			  0xffff /*ih_free_space */ );

	/* we want a pointer to the first byte of the tail in the page.
	 ** the page was locked and this part of the page was up to date when
	 ** indirect2direct was called, so we know the bytes are still valid
	 */
	tail = tail + (pos & (PAGE_CACHE_SIZE - 1));

	PATH_LAST_POSITION(p_s_path)++;

	key = *p_s_item_key;
	set_cpu_key_k_type(&key, TYPE_DIRECT);
	key.key_length = 4;
	/* Insert tail as new direct item in the tree */
	if (reiserfs_insert_item(th, p_s_path, &key, &s_ih, p_s_inode,
				 tail ? tail : NULL) < 0) {
		/* No disk memory. So we can not convert last unformatted node
		   to the direct item.  In this case we used to adjust
		   indirect items's ih_free_space. Now ih_free_space is not
		   used, it would be ideal to write zeros to corresponding
		   unformatted node. For now i_size is considered as guard for
		   going out of file size */
		kunmap(page);
		return n_block_size - round_tail_len;
	}
	kunmap(page);

	/* make sure to get the i_blocks changes from reiserfs_insert_item */
	reiserfs_update_sd(th, p_s_inode);

	// note: we have now the same as in above direct2indirect
	// conversion: there are two keys which have matching first three
	// key components. They only differ by the fouhth one.

	/* We have inserted new direct item and must remove last
	   unformatted node. */
	*p_c_mode = M_CUT;

	/* we store position of first direct item in the in-core inode */
	//mark_file_with_tail (p_s_inode, pos1 + 1);
	REISERFS_I(p_s_inode)->i_first_direct_byte = pos1 + 1;

	return n_block_size - round_tail_len;
}
