/*
 * 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_mutex. 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;
}
