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

#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;
}
