/*
 *  Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
 */

/*
 *  Written by Anatoly P. Pinchuk pap@namesys.botik.ru
 *  Programm System Institute
 *  Pereslavl-Zalessky Russia
 */

/*
 *  This file contains functions dealing with S+tree
 *
 * B_IS_IN_TREE
 * copy_item_head
 * comp_short_keys
 * comp_keys
 * comp_short_le_keys
 * le_key2cpu_key
 * comp_le_keys
 * bin_search
 * get_lkey
 * get_rkey
 * key_in_buffer
 * decrement_bcount
 * decrement_counters_in_path
 * reiserfs_check_path
 * pathrelse_and_restore
 * pathrelse
 * search_by_key_reada
 * search_by_key
 * search_for_position_by_key
 * comp_items
 * prepare_for_direct_item
 * prepare_for_direntry_item
 * prepare_for_delete_or_cut
 * calc_deleted_bytes_number
 * init_tb_struct
 * padd_item
 * reiserfs_delete_item
 * reiserfs_delete_solid_item
 * reiserfs_delete_object
 * maybe_indirect_to_direct
 * indirect_to_direct_roll_back
 * reiserfs_cut_from_item
 * truncate_directory
 * reiserfs_do_truncate
 * reiserfs_paste_into_item
 * reiserfs_insert_item
 */

#include <linux/time.h>
#include <linux/string.h>
#include <linux/pagemap.h>
#include <linux/reiserfs_fs.h>
#include <linux/smp_lock.h>
#include <linux/buffer_head.h>
#include <linux/quotaops.h>

/* Does the buffer contain a disk block which is in the tree. */
inline int B_IS_IN_TREE(const struct buffer_head *p_s_bh)
{

	RFALSE(B_LEVEL(p_s_bh) > MAX_HEIGHT,
	       "PAP-1010: block (%b) has too big level (%z)", p_s_bh, p_s_bh);

	return (B_LEVEL(p_s_bh) != FREE_LEVEL);
}

//
// to gets item head in le form
//
inline void copy_item_head(struct item_head *p_v_to,
			   const struct item_head *p_v_from)
{
	memcpy(p_v_to, p_v_from, IH_SIZE);
}

/* k1 is pointer to on-disk structure which is stored in little-endian
   form. k2 is pointer to cpu variable. For key of items of the same
   object this returns 0.
   Returns: -1 if key1 < key2 
   0 if key1 == key2
   1 if key1 > key2 */
inline int comp_short_keys(const struct reiserfs_key *le_key,
			   const struct cpu_key *cpu_key)
{
	__u32 n;
	n = le32_to_cpu(le_key->k_dir_id);
	if (n < cpu_key->on_disk_key.k_dir_id)
		return -1;
	if (n > cpu_key->on_disk_key.k_dir_id)
		return 1;
	n = le32_to_cpu(le_key->k_objectid);
	if (n < cpu_key->on_disk_key.k_objectid)
		return -1;
	if (n > cpu_key->on_disk_key.k_objectid)
		return 1;
	return 0;
}

/* k1 is pointer to on-disk structure which is stored in little-endian
   form. k2 is pointer to cpu variable.
   Compare keys using all 4 key fields.
   Returns: -1 if key1 < key2 0
   if key1 = key2 1 if key1 > key2 */
static inline int comp_keys(const struct reiserfs_key *le_key,
			    const struct cpu_key *cpu_key)
{
	int retval;

	retval = comp_short_keys(le_key, cpu_key);
	if (retval)
		return retval;
	if (le_key_k_offset(le_key_version(le_key), le_key) <
	    cpu_key_k_offset(cpu_key))
		return -1;
	if (le_key_k_offset(le_key_version(le_key), le_key) >
	    cpu_key_k_offset(cpu_key))
		return 1;

	if (cpu_key->key_length == 3)
		return 0;

	/* this part is needed only when tail conversion is in progress */
	if (le_key_k_type(le_key_version(le_key), le_key) <
	    cpu_key_k_type(cpu_key))
		return -1;

	if (le_key_k_type(le_key_version(le_key), le_key) >
	    cpu_key_k_type(cpu_key))
		return 1;

	return 0;
}

inline int comp_short_le_keys(const struct reiserfs_key *key1,
			      const struct reiserfs_key *key2)
{
	__u32 *p_s_1_u32, *p_s_2_u32;
	int n_key_length = REISERFS_SHORT_KEY_LEN;

	p_s_1_u32 = (__u32 *) key1;
	p_s_2_u32 = (__u32 *) key2;
	for (; n_key_length--; ++p_s_1_u32, ++p_s_2_u32) {
		if (le32_to_cpu(*p_s_1_u32) < le32_to_cpu(*p_s_2_u32))
			return -1;
		if (le32_to_cpu(*p_s_1_u32) > le32_to_cpu(*p_s_2_u32))
			return 1;
	}
	return 0;
}

inline void le_key2cpu_key(struct cpu_key *to, const struct reiserfs_key *from)
{
	int version;
	to->on_disk_key.k_dir_id = le32_to_cpu(from->k_dir_id);
	to->on_disk_key.k_objectid = le32_to_cpu(from->k_objectid);

	// find out version of the key
	version = le_key_version(from);
	to->version = version;
	to->on_disk_key.k_offset = le_key_k_offset(version, from);
	to->on_disk_key.k_type = le_key_k_type(version, from);
}

// this does not say which one is bigger, it only returns 1 if keys
// are not equal, 0 otherwise
inline int comp_le_keys(const struct reiserfs_key *k1,
			const struct reiserfs_key *k2)
{
	return memcmp(k1, k2, sizeof(struct reiserfs_key));
}

/**************************************************************************
 *  Binary search toolkit function                                        *
 *  Search for an item in the array by the item key                       *
 *  Returns:    1 if found,  0 if not found;                              *
 *        *p_n_pos = number of the searched element if found, else the    *
 *        number of the first element that is larger than p_v_key.        *
 **************************************************************************/
/* For those not familiar with binary search: n_lbound is the leftmost item that it
 could be, n_rbound the rightmost item that it could be.  We examine the item
 halfway between n_lbound and n_rbound, and that tells us either that we can increase
 n_lbound, or decrease n_rbound, or that we have found it, or if n_lbound <= n_rbound that
 there are no possible items, and we have not found it. With each examination we
 cut the number of possible items it could be by one more than half rounded down,
 or we find it. */
static inline int bin_search(const void *p_v_key,	/* Key to search for.                   */
			     const void *p_v_base,	/* First item in the array.             */
			     int p_n_num,	/* Number of items in the array.        */
			     int p_n_width,	/* Item size in the array.
						   searched. Lest the reader be
						   confused, note that this is crafted
						   as a general function, and when it
						   is applied specifically to the array
						   of item headers in a node, p_n_width
						   is actually the item header size not
						   the item size.                      */
			     int *p_n_pos	/* Number of the searched for element. */
    )
{
	int n_rbound, n_lbound, n_j;

	for (n_j = ((n_rbound = p_n_num - 1) + (n_lbound = 0)) / 2;
	     n_lbound <= n_rbound; n_j = (n_rbound + n_lbound) / 2)
		switch (comp_keys
			((struct reiserfs_key *)((char *)p_v_base +
						 n_j * p_n_width),
			 (struct cpu_key *)p_v_key)) {
		case -1:
			n_lbound = n_j + 1;
			continue;
		case 1:
			n_rbound = n_j - 1;
			continue;
		case 0:
			*p_n_pos = n_j;
			return ITEM_FOUND;	/* Key found in the array.  */
		}

	/* bin_search did not find given key, it returns position of key,
	   that is minimal and greater than the given one. */
	*p_n_pos = n_lbound;
	return ITEM_NOT_FOUND;
}

#ifdef CONFIG_REISERFS_CHECK
extern struct tree_balance *cur_tb;
#endif

/* Minimal possible key. It is never in the tree. */
const struct reiserfs_key MIN_KEY = { 0, 0, {{0, 0},} };

/* Maximal possible key. It is never in the tree. */
static const struct reiserfs_key MAX_KEY = {
	__constant_cpu_to_le32(0xffffffff),
	__constant_cpu_to_le32(0xffffffff),
	{{__constant_cpu_to_le32(0xffffffff),
	  __constant_cpu_to_le32(0xffffffff)},}
};

/* Get delimiting key of the buffer by looking for it in the buffers in the path, starting from the bottom
   of the path, and going upwards.  We must check the path's validity at each step.  If the key is not in
   the path, there is no delimiting key in the tree (buffer is first or last buffer in tree), and in this
   case we return a special key, either MIN_KEY or MAX_KEY. */
static inline const struct reiserfs_key *get_lkey(const struct path
						  *p_s_chk_path,
						  const struct super_block
						  *p_s_sb)
{
	int n_position, n_path_offset = p_s_chk_path->path_length;
	struct buffer_head *p_s_parent;

	RFALSE(n_path_offset < FIRST_PATH_ELEMENT_OFFSET,
	       "PAP-5010: invalid offset in the path");

	/* While not higher in path than first element. */
	while (n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET) {

		RFALSE(!buffer_uptodate
		       (PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
		       "PAP-5020: parent is not uptodate");

		/* Parent at the path is not in the tree now. */
		if (!B_IS_IN_TREE
		    (p_s_parent =
		     PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)))
			return &MAX_KEY;
		/* Check whether position in the parent is correct. */
		if ((n_position =
		     PATH_OFFSET_POSITION(p_s_chk_path,
					  n_path_offset)) >
		    B_NR_ITEMS(p_s_parent))
			return &MAX_KEY;
		/* Check whether parent at the path really points to the child. */
		if (B_N_CHILD_NUM(p_s_parent, n_position) !=
		    PATH_OFFSET_PBUFFER(p_s_chk_path,
					n_path_offset + 1)->b_blocknr)
			return &MAX_KEY;
		/* Return delimiting key if position in the parent is not equal to zero. */
		if (n_position)
			return B_N_PDELIM_KEY(p_s_parent, n_position - 1);
	}
	/* Return MIN_KEY if we are in the root of the buffer tree. */
	if (PATH_OFFSET_PBUFFER(p_s_chk_path, FIRST_PATH_ELEMENT_OFFSET)->
	    b_blocknr == SB_ROOT_BLOCK(p_s_sb))
		return &MIN_KEY;
	return &MAX_KEY;
}

/* Get delimiting key of the buffer at the path and its right neighbor. */
inline const struct reiserfs_key *get_rkey(const struct path *p_s_chk_path,
					   const struct super_block *p_s_sb)
{
	int n_position, n_path_offset = p_s_chk_path->path_length;
	struct buffer_head *p_s_parent;

	RFALSE(n_path_offset < FIRST_PATH_ELEMENT_OFFSET,
	       "PAP-5030: invalid offset in the path");

	while (n_path_offset-- > FIRST_PATH_ELEMENT_OFFSET) {

		RFALSE(!buffer_uptodate
		       (PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)),
		       "PAP-5040: parent is not uptodate");

		/* Parent at the path is not in the tree now. */
		if (!B_IS_IN_TREE
		    (p_s_parent =
		     PATH_OFFSET_PBUFFER(p_s_chk_path, n_path_offset)))
			return &MIN_KEY;
		/* Check whether position in the parent is correct. */
		if ((n_position =
		     PATH_OFFSET_POSITION(p_s_chk_path,
					  n_path_offset)) >
		    B_NR_ITEMS(p_s_parent))
			return &MIN_KEY;
		/* Check whether parent at the path really points to the child. */
		if (B_N_CHILD_NUM(p_s_parent, n_position) !=
		    PATH_OFFSET_PBUFFER(p_s_chk_path,
					n_path_offset + 1)->b_blocknr)
			return &MIN_KEY;
		/* Return delimiting key if position in the parent is not the last one. */
		if (n_position != B_NR_ITEMS(p_s_parent))
			return B_N_PDELIM_KEY(p_s_parent, n_position);
	}
	/* Return MAX_KEY if we are in the root of the buffer tree. */
	if (PATH_OFFSET_PBUFFER(p_s_chk_path, FIRST_PATH_ELEMENT_OFFSET)->
	    b_blocknr == SB_ROOT_BLOCK(p_s_sb))
		return &MAX_KEY;
	return &MIN_KEY;
}

/* Check whether a key is contained in the tree rooted from a buffer at a path. */
/* This works by looking at the left and right delimiting keys for the buffer in the last path_element in
   the path.  These delimiting keys are stored at least one level above that buffer in the tree. If the
   buffer is the first or last node in the tree order then one of the delimiting keys may be absent, and in
   this case get_lkey and get_rkey return a special key which is MIN_KEY or MAX_KEY. */
static inline int key_in_buffer(struct path *p_s_chk_path,	/* Path which should be checked.  */
				const struct cpu_key *p_s_key,	/* Key which should be checked.   */
				struct super_block *p_s_sb	/* Super block pointer.           */
    )
{

	RFALSE(!p_s_key || p_s_chk_path->path_length < FIRST_PATH_ELEMENT_OFFSET
	       || p_s_chk_path->path_length > MAX_HEIGHT,
	       "PAP-5050: pointer to the key(%p) is NULL or invalid path length(%d)",
	       p_s_key, p_s_chk_path->path_length);
	RFALSE(!PATH_PLAST_BUFFER(p_s_chk_path)->b_bdev,
	       "PAP-5060: device must not be NODEV");

	if (comp_keys(get_lkey(p_s_chk_path, p_s_sb), p_s_key) == 1)
		/* left delimiting key is bigger, that the key we look for */
		return 0;
	//  if ( comp_keys(p_s_key, get_rkey(p_s_chk_path, p_s_sb)) != -1 )
	if (comp_keys(get_rkey(p_s_chk_path, p_s_sb), p_s_key) != 1)
		/* p_s_key must be less than right delimitiing key */
		return 0;
	return 1;
}

inline void decrement_bcount(struct buffer_head *p_s_bh)
{
	if (p_s_bh) {
		if (atomic_read(&(p_s_bh->b_count))) {
			put_bh(p_s_bh);
			return;
		}
		reiserfs_panic(NULL,
			       "PAP-5070: decrement_bcount: trying to free free buffer %b",
			       p_s_bh);
	}
}

/* Decrement b_count field of the all buffers in the path. */
void decrement_counters_in_path(struct path *p_s_search_path)
{
	int n_path_offset = p_s_search_path->path_length;

	RFALSE(n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET ||
	       n_path_offset > EXTENDED_MAX_HEIGHT - 1,
	       "PAP-5080: invalid path offset of %d", n_path_offset);

	while (n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET) {
		struct buffer_head *bh;

		bh = PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--);
		decrement_bcount(bh);
	}
	p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
}

int reiserfs_check_path(struct path *p)
{
	RFALSE(p->path_length != ILLEGAL_PATH_ELEMENT_OFFSET,
	       "path not properly relsed");
	return 0;
}

/* Release all buffers in the path. Restore dirty bits clean
** when preparing the buffer for the log
**
** only called from fix_nodes()
*/
void pathrelse_and_restore(struct super_block *s, struct path *p_s_search_path)
{
	int n_path_offset = p_s_search_path->path_length;

	RFALSE(n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET,
	       "clm-4000: invalid path offset");

	while (n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET) {
		reiserfs_restore_prepared_buffer(s,
						 PATH_OFFSET_PBUFFER
						 (p_s_search_path,
						  n_path_offset));
		brelse(PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--));
	}
	p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
}

/* Release all buffers in the path. */
void pathrelse(struct path *p_s_search_path)
{
	int n_path_offset = p_s_search_path->path_length;

	RFALSE(n_path_offset < ILLEGAL_PATH_ELEMENT_OFFSET,
	       "PAP-5090: invalid path offset");

	while (n_path_offset > ILLEGAL_PATH_ELEMENT_OFFSET)
		brelse(PATH_OFFSET_PBUFFER(p_s_search_path, n_path_offset--));

	p_s_search_path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;
}

static int is_leaf(char *buf, int blocksize, struct buffer_head *bh)
{
	struct block_head *blkh;
	struct item_head *ih;
	int used_space;
	int prev_location;
	int i;
	int nr;

	blkh = (struct block_head *)buf;
	if (blkh_level(blkh) != DISK_LEAF_NODE_LEVEL) {
		reiserfs_warning(NULL,
				 "is_leaf: this should be caught earlier");
		return 0;
	}

	nr = blkh_nr_item(blkh);
	if (nr < 1 || nr > ((blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN))) {
		/* item number is too big or too small */
		reiserfs_warning(NULL, "is_leaf: nr_item seems wrong: %z", bh);
		return 0;
	}
	ih = (struct item_head *)(buf + BLKH_SIZE) + nr - 1;
	used_space = BLKH_SIZE + IH_SIZE * nr + (blocksize - ih_location(ih));
	if (used_space != blocksize - blkh_free_space(blkh)) {
		/* free space does not match to calculated amount of use space */
		reiserfs_warning(NULL, "is_leaf: free space seems wrong: %z",
				 bh);
		return 0;
	}
	// FIXME: it is_leaf will hit performance too much - we may have
	// return 1 here

	/* check tables of item heads */
	ih = (struct item_head *)(buf + BLKH_SIZE);
	prev_location = blocksize;
	for (i = 0; i < nr; i++, ih++) {
		if (le_ih_k_type(ih) == TYPE_ANY) {
			reiserfs_warning(NULL,
					 "is_leaf: wrong item type for item %h",
					 ih);
			return 0;
		}
		if (ih_location(ih) >= blocksize
		    || ih_location(ih) < IH_SIZE * nr) {
			reiserfs_warning(NULL,
					 "is_leaf: item location seems wrong: %h",
					 ih);
			return 0;
		}
		if (ih_item_len(ih) < 1
		    || ih_item_len(ih) > MAX_ITEM_LEN(blocksize)) {
			reiserfs_warning(NULL,
					 "is_leaf: item length seems wrong: %h",
					 ih);
			return 0;
		}
		if (prev_location - ih_location(ih) != ih_item_len(ih)) {
			reiserfs_warning(NULL,
					 "is_leaf: item location seems wrong (second one): %h",
					 ih);
			return 0;
		}
		prev_location = ih_location(ih);
	}

	// one may imagine much more checks
	return 1;
}

/* returns 1 if buf looks like an internal node, 0 otherwise */
static int is_internal(char *buf, int blocksize, struct buffer_head *bh)
{
	struct block_head *blkh;
	int nr;
	int used_space;

	blkh = (struct block_head *)buf;
	nr = blkh_level(blkh);
	if (nr <= DISK_LEAF_NODE_LEVEL || nr > MAX_HEIGHT) {
		/* this level is not possible for internal nodes */
		reiserfs_warning(NULL,
				 "is_internal: this should be caught earlier");
		return 0;
	}

	nr = blkh_nr_item(blkh);
	if (nr > (blocksize - BLKH_SIZE - DC_SIZE) / (KEY_SIZE + DC_SIZE)) {
		/* for internal which is not root we might check min number of keys */
		reiserfs_warning(NULL,
				 "is_internal: number of key seems wrong: %z",
				 bh);
		return 0;
	}

	used_space = BLKH_SIZE + KEY_SIZE * nr + DC_SIZE * (nr + 1);
	if (used_space != blocksize - blkh_free_space(blkh)) {
		reiserfs_warning(NULL,
				 "is_internal: free space seems wrong: %z", bh);
		return 0;
	}
	// one may imagine much more checks
	return 1;
}

// make sure that bh contains formatted node of reiserfs tree of
// 'level'-th level
static int is_tree_node(struct buffer_head *bh, int level)
{
	if (B_LEVEL(bh) != level) {
		reiserfs_warning(NULL,
				 "is_tree_node: node level %d does not match to the expected one %d",
				 B_LEVEL(bh), level);
		return 0;
	}
	if (level == DISK_LEAF_NODE_LEVEL)
		return is_leaf(bh->b_data, bh->b_size, bh);

	return is_internal(bh->b_data, bh->b_size, bh);
}

#define SEARCH_BY_KEY_READA 16

/* The function is NOT SCHEDULE-SAFE! */
static void search_by_key_reada(struct super_block *s,
				struct buffer_head **bh,
				unsigned long *b, int num)
{
	int i, j;

	for (i = 0; i < num; i++) {
		bh[i] = sb_getblk(s, b[i]);
	}
	for (j = 0; j < i; j++) {
		/*
		 * note, this needs attention if we are getting rid of the BKL
		 * you have to make sure the prepared bit isn't set on this buffer
		 */
		if (!buffer_uptodate(bh[j]))
			ll_rw_block(READA, 1, bh + j);
		brelse(bh[j]);
	}
}

/**************************************************************************
 * Algorithm   SearchByKey                                                *
 *             look for item in the Disk S+Tree by its key                *
 * Input:  p_s_sb   -  super block                                        *
 *         p_s_key  - pointer to the key to search                        *
 * Output: ITEM_FOUND, ITEM_NOT_FOUND or IO_ERROR                         *
 *         p_s_search_path - path from the root to the needed leaf        *
 **************************************************************************/

/* This function fills up the path from the root to the leaf as it
   descends the tree looking for the key.  It uses reiserfs_bread to
   try to find buffers in the cache given their block number.  If it
   does not find them in the cache it reads them from disk.  For each
   node search_by_key finds using reiserfs_bread it then uses
   bin_search to look through that node.  bin_search will find the
   position of the block_number of the next node if it is looking
   through an internal node.  If it is looking through a leaf node
   bin_search will find the position of the item which has key either
   equal to given key, or which is the maximal key less than the given
   key.  search_by_key returns a path that must be checked for the
   correctness of the top of the path but need not be checked for the
   correctness of the bottom of the path */
/* The function is NOT SCHEDULE-SAFE! */
int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key,	/* Key to search. */
		  struct path *p_s_search_path,	/* This structure was
						   allocated and initialized
						   by the calling
						   function. It is filled up
						   by this function.  */
		  int n_stop_level	/* How far down the tree to search. To
					   stop at leaf level - set to
					   DISK_LEAF_NODE_LEVEL */
    )
{
	int n_block_number;
	int expected_level;
	struct buffer_head *p_s_bh;
	struct path_element *p_s_last_element;
	int n_node_level, n_retval;
	int right_neighbor_of_leaf_node;
	int fs_gen;
	struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
	unsigned long reada_blocks[SEARCH_BY_KEY_READA];
	int reada_count = 0;

#ifdef CONFIG_REISERFS_CHECK
	int n_repeat_counter = 0;
#endif

	PROC_INFO_INC(p_s_sb, search_by_key);

	/* As we add each node to a path we increase its count.  This means that
	   we must be careful to release all nodes in a path before we either
	   discard the path struct or re-use the path struct, as we do here. */

	decrement_counters_in_path(p_s_search_path);

	right_neighbor_of_leaf_node = 0;

	/* With each iteration of this loop we search through the items in the
	   current node, and calculate the next current node(next path element)
	   for the next iteration of this loop.. */
	n_block_number = SB_ROOT_BLOCK(p_s_sb);
	expected_level = -1;
	while (1) {

#ifdef CONFIG_REISERFS_CHECK
		if (!(++n_repeat_counter % 50000))
			reiserfs_warning(p_s_sb, "PAP-5100: search_by_key: %s:"
					 "there were %d iterations of while loop "
					 "looking for key %K",
					 current->comm, n_repeat_counter,
					 p_s_key);
#endif

		/* prep path to have another element added to it. */
		p_s_last_element =
		    PATH_OFFSET_PELEMENT(p_s_search_path,
					 ++p_s_search_path->path_length);
		fs_gen = get_generation(p_s_sb);

		/* Read the next tree node, and set the last element in the path to
		   have a pointer to it. */
		if ((p_s_bh = p_s_last_element->pe_buffer =
		     sb_getblk(p_s_sb, n_block_number))) {
			if (!buffer_uptodate(p_s_bh) && reada_count > 1) {
				search_by_key_reada(p_s_sb, reada_bh,
						    reada_blocks, reada_count);
			}
			ll_rw_block(READ, 1, &p_s_bh);
			wait_on_buffer(p_s_bh);
			if (!buffer_uptodate(p_s_bh))
				goto io_error;
		} else {
		      io_error:
			p_s_search_path->path_length--;
			pathrelse(p_s_search_path);
			return IO_ERROR;
		}
		reada_count = 0;
		if (expected_level == -1)
			expected_level = SB_TREE_HEIGHT(p_s_sb);
		expected_level--;

		/* It is possible that schedule occurred. We must check whether the key
		   to search is still in the tree rooted from the current buffer. If
		   not then repeat search from the root. */
		if (fs_changed(fs_gen, p_s_sb) &&
		    (!B_IS_IN_TREE(p_s_bh) ||
		     B_LEVEL(p_s_bh) != expected_level ||
		     !key_in_buffer(p_s_search_path, p_s_key, p_s_sb))) {
			PROC_INFO_INC(p_s_sb, search_by_key_fs_changed);
			PROC_INFO_INC(p_s_sb, search_by_key_restarted);
			PROC_INFO_INC(p_s_sb,
				      sbk_restarted[expected_level - 1]);
			decrement_counters_in_path(p_s_search_path);

			/* Get the root block number so that we can repeat the search
			   starting from the root. */
			n_block_number = SB_ROOT_BLOCK(p_s_sb);
			expected_level = -1;
			right_neighbor_of_leaf_node = 0;

			/* repeat search from the root */
			continue;
		}

		/* only check that the key is in the buffer if p_s_key is not
		   equal to the MAX_KEY. Latter case is only possible in
		   "finish_unfinished()" processing during mount. */
		RFALSE(comp_keys(&MAX_KEY, p_s_key) &&
		       !key_in_buffer(p_s_search_path, p_s_key, p_s_sb),
		       "PAP-5130: key is not in the buffer");
#ifdef CONFIG_REISERFS_CHECK
		if (cur_tb) {
			print_cur_tb("5140");
			reiserfs_panic(p_s_sb,
				       "PAP-5140: search_by_key: schedule occurred in do_balance!");
		}
#endif

		// make sure, that the node contents look like a node of
		// certain level
		if (!is_tree_node(p_s_bh, expected_level)) {
			reiserfs_warning(p_s_sb, "vs-5150: search_by_key: "
					 "invalid format found in block %ld. Fsck?",
					 p_s_bh->b_blocknr);
			pathrelse(p_s_search_path);
			return IO_ERROR;
		}

		/* ok, we have acquired next formatted node in the tree */
		n_node_level = B_LEVEL(p_s_bh);

		PROC_INFO_BH_STAT(p_s_sb, p_s_bh, n_node_level - 1);

		RFALSE(n_node_level < n_stop_level,
		       "vs-5152: tree level (%d) is less than stop level (%d)",
		       n_node_level, n_stop_level);

		n_retval = bin_search(p_s_key, B_N_PITEM_HEAD(p_s_bh, 0),
				      B_NR_ITEMS(p_s_bh),
				      (n_node_level ==
				       DISK_LEAF_NODE_LEVEL) ? IH_SIZE :
				      KEY_SIZE,
				      &(p_s_last_element->pe_position));
		if (n_node_level == n_stop_level) {
			return n_retval;
		}

		/* we are not in the stop level */
		if (n_retval == ITEM_FOUND)
			/* item has been found, so we choose the pointer which is to the right of the found one */
			p_s_last_element->pe_position++;

		/* if item was not found we choose the position which is to
		   the left of the found item. This requires no code,
		   bin_search did it already. */

		/* So we have chosen a position in the current node which is
		   an internal node.  Now we calculate child block number by
		   position in the node. */
		n_block_number =
		    B_N_CHILD_NUM(p_s_bh, p_s_last_element->pe_position);

		/* if we are going to read leaf nodes, try for read ahead as well */
		if ((p_s_search_path->reada & PATH_READA) &&
		    n_node_level == DISK_LEAF_NODE_LEVEL + 1) {
			int pos = p_s_last_element->pe_position;
			int limit = B_NR_ITEMS(p_s_bh);
			struct reiserfs_key *le_key;

			if (p_s_search_path->reada & PATH_READA_BACK)
				limit = 0;
			while (reada_count < SEARCH_BY_KEY_READA) {
				if (pos == limit)
					break;
				reada_blocks[reada_count++] =
				    B_N_CHILD_NUM(p_s_bh, pos);
				if (p_s_search_path->reada & PATH_READA_BACK)
					pos--;
				else
					pos++;

				/*
				 * check to make sure we're in the same object
				 */
				le_key = B_N_PDELIM_KEY(p_s_bh, pos);
				if (le32_to_cpu(le_key->k_objectid) !=
				    p_s_key->on_disk_key.k_objectid) {
					break;
				}
			}
		}
	}
}

/* Form the path to an item and position in this item which contains
   file byte defined by p_s_key. If there is no such item
   corresponding to the key, we point the path to the item with
   maximal key less than p_s_key, and *p_n_pos_in_item is set to one
   past the last entry/byte in the item.  If searching for entry in a
   directory item, and it is not found, *p_n_pos_in_item is set to one
   entry more than the entry with maximal key which is less than the
   sought key.

   Note that if there is no entry in this same node which is one more,
   then we point to an imaginary entry.  for direct items, the
   position is in units of bytes, for indirect items the position is
   in units of blocknr entries, for directory items the position is in
   units of directory entries.  */

/* The function is NOT SCHEDULE-SAFE! */
int search_for_position_by_key(struct super_block *p_s_sb,	/* Pointer to the super block.          */
			       const struct cpu_key *p_cpu_key,	/* Key to search (cpu variable)         */
			       struct path *p_s_search_path	/* Filled up by this function.          */
    )
{
	struct item_head *p_le_ih;	/* pointer to on-disk structure */
	int n_blk_size;
	loff_t item_offset, offset;
	struct reiserfs_dir_entry de;
	int retval;

	/* If searching for directory entry. */
	if (is_direntry_cpu_key(p_cpu_key))
		return search_by_entry_key(p_s_sb, p_cpu_key, p_s_search_path,
					   &de);

	/* If not searching for directory entry. */

	/* If item is found. */
	retval = search_item(p_s_sb, p_cpu_key, p_s_search_path);
	if (retval == IO_ERROR)
		return retval;
	if (retval == ITEM_FOUND) {

		RFALSE(!ih_item_len
		       (B_N_PITEM_HEAD
			(PATH_PLAST_BUFFER(p_s_search_path),
			 PATH_LAST_POSITION(p_s_search_path))),
		       "PAP-5165: item length equals zero");

		pos_in_item(p_s_search_path) = 0;
		return POSITION_FOUND;
	}

	RFALSE(!PATH_LAST_POSITION(p_s_search_path),
	       "PAP-5170: position equals zero");

	/* Item is not found. Set path to the previous item. */
	p_le_ih =
	    B_N_PITEM_HEAD(PATH_PLAST_BUFFER(p_s_search_path),
			   --PATH_LAST_POSITION(p_s_search_path));
	n_blk_size = p_s_sb->s_blocksize;

	if (comp_short_keys(&(p_le_ih->ih_key), p_cpu_key)) {
		return FILE_NOT_FOUND;
	}
	// FIXME: quite ugly this far

	item_offset = le_ih_k_offset(p_le_ih);
	offset = cpu_key_k_offset(p_cpu_key);

	/* Needed byte is contained in the item pointed to by the path. */
	if (item_offset <= offset &&
	    item_offset + op_bytes_number(p_le_ih, n_blk_size) > offset) {
		pos_in_item(p_s_search_path) = offset - item_offset;
		if (is_indirect_le_ih(p_le_ih)) {
			pos_in_item(p_s_search_path) /= n_blk_size;
		}
		return POSITION_FOUND;
	}

	/* Needed byte is not contained in the item pointed to by the
	   path. Set pos_in_item out of the item. */
	if (is_indirect_le_ih(p_le_ih))
		pos_in_item(p_s_search_path) =
		    ih_item_len(p_le_ih) / UNFM_P_SIZE;
	else
		pos_in_item(p_s_search_path) = ih_item_len(p_le_ih);

	return POSITION_NOT_FOUND;
}

/* Compare given item and item pointed to by the path. */
int comp_items(const struct item_head *stored_ih, const struct path *p_s_path)
{
	struct buffer_head *p_s_bh;
	struct item_head *ih;

	/* Last buffer at the path is not in the tree. */
	if (!B_IS_IN_TREE(p_s_bh = PATH_PLAST_BUFFER(p_s_path)))
		return 1;

	/* Last path position is invalid. */
	if (PATH_LAST_POSITION(p_s_path) >= B_NR_ITEMS(p_s_bh))
		return 1;

	/* we need only to know, whether it is the same item */
	ih = get_ih(p_s_path);
	return memcmp(stored_ih, ih, IH_SIZE);
}

/* unformatted nodes are not logged anymore, ever.  This is safe
** now
*/
#define held_by_others(bh) (atomic_read(&(bh)->b_count) > 1)

// block can not be forgotten as it is in I/O or held by someone
#define block_in_use(bh) (buffer_locked(bh) || (held_by_others(bh)))

// prepare for delete or cut of direct item
static inline int prepare_for_direct_item(struct path *path,
					  struct item_head *le_ih,
					  struct inode *inode,
					  loff_t new_file_length, int *cut_size)
{
	loff_t round_len;

	if (new_file_length == max_reiserfs_offset(inode)) {
		/* item has to be deleted */
		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
		return M_DELETE;
	}
	// new file gets truncated
	if (get_inode_item_key_version(inode) == KEY_FORMAT_3_6) {
		// 
		round_len = ROUND_UP(new_file_length);
		/* this was n_new_file_length < le_ih ... */
		if (round_len < le_ih_k_offset(le_ih)) {
			*cut_size = -(IH_SIZE + ih_item_len(le_ih));
			return M_DELETE;	/* Delete this item. */
		}
		/* Calculate first position and size for cutting from item. */
		pos_in_item(path) = round_len - (le_ih_k_offset(le_ih) - 1);
		*cut_size = -(ih_item_len(le_ih) - pos_in_item(path));

		return M_CUT;	/* Cut from this item. */
	}

	// old file: items may have any length

	if (new_file_length < le_ih_k_offset(le_ih)) {
		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
		return M_DELETE;	/* Delete this item. */
	}
	/* Calculate first position and size for cutting from item. */
	*cut_size = -(ih_item_len(le_ih) -
		      (pos_in_item(path) =
		       new_file_length + 1 - le_ih_k_offset(le_ih)));
	return M_CUT;		/* Cut from this item. */
}

static inline int prepare_for_direntry_item(struct path *path,
					    struct item_head *le_ih,
					    struct inode *inode,
					    loff_t new_file_length,
					    int *cut_size)
{
	if (le_ih_k_offset(le_ih) == DOT_OFFSET &&
	    new_file_length == max_reiserfs_offset(inode)) {
		RFALSE(ih_entry_count(le_ih) != 2,
		       "PAP-5220: incorrect empty directory item (%h)", le_ih);
		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
		return M_DELETE;	/* Delete the directory item containing "." and ".." entry. */
	}

	if (ih_entry_count(le_ih) == 1) {
		/* Delete the directory item such as there is one record only
		   in this item */
		*cut_size = -(IH_SIZE + ih_item_len(le_ih));
		return M_DELETE;
	}

	/* Cut one record from the directory item. */
	*cut_size =
	    -(DEH_SIZE +
	      entry_length(get_last_bh(path), le_ih, pos_in_item(path)));
	return M_CUT;
}

#define JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD (2 * JOURNAL_PER_BALANCE_CNT + 1)

/*  If the path points to a directory or direct item, calculate mode and the size cut, for balance.
    If the path points to an indirect item, remove some number of its unformatted nodes.
    In case of file truncate calculate whether this item must be deleted/truncated or last
    unformatted node of this item will be converted to a direct item.
    This function returns a determination of what balance mode the calling function should employ. */
static char prepare_for_delete_or_cut(struct reiserfs_transaction_handle *th, struct inode *inode, struct path *p_s_path, const struct cpu_key *p_s_item_key, int *p_n_removed,	/* Number of unformatted nodes which were removed
																						   from end of the file. */
				      int *p_n_cut_size, unsigned long long n_new_file_length	/* MAX_KEY_OFFSET in case of delete. */
    )
{
	struct super_block *p_s_sb = inode->i_sb;
	struct item_head *p_le_ih = PATH_PITEM_HEAD(p_s_path);
	struct buffer_head *p_s_bh = PATH_PLAST_BUFFER(p_s_path);

	BUG_ON(!th->t_trans_id);

	/* Stat_data item. */
	if (is_statdata_le_ih(p_le_ih)) {

		RFALSE(n_new_file_length != max_reiserfs_offset(inode),
		       "PAP-5210: mode must be M_DELETE");

		*p_n_cut_size = -(IH_SIZE + ih_item_len(p_le_ih));
		return M_DELETE;
	}

	/* Directory item. */
	if (is_direntry_le_ih(p_le_ih))
		return prepare_for_direntry_item(p_s_path, p_le_ih, inode,
						 n_new_file_length,
						 p_n_cut_size);

	/* Direct item. */
	if (is_direct_le_ih(p_le_ih))
		return prepare_for_direct_item(p_s_path, p_le_ih, inode,
					       n_new_file_length, p_n_cut_size);

	/* Case of an indirect item. */
	{
	    int blk_size = p_s_sb->s_blocksize;
	    struct item_head s_ih;
	    int need_re_search;
	    int delete = 0;
	    int result = M_CUT;
	    int pos = 0;

	    if ( n_new_file_length == max_reiserfs_offset (inode) ) {
		/* prepare_for_delete_or_cut() is called by
		 * reiserfs_delete_item() */
		n_new_file_length = 0;
		delete = 1;
	    }

	    do {
		need_re_search = 0;
		*p_n_cut_size = 0;
		p_s_bh = PATH_PLAST_BUFFER(p_s_path);
		copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
		pos = I_UNFM_NUM(&s_ih);

		while (le_ih_k_offset (&s_ih) + (pos - 1) * blk_size > n_new_file_length) {
		    __u32 *unfm, block;

		    /* Each unformatted block deletion may involve one additional
		     * bitmap block into the transaction, thereby the initial
		     * journal space reservation might not be enough. */
		    if (!delete && (*p_n_cut_size) != 0 &&
			reiserfs_transaction_free_space(th) < JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD) {
			break;
		    }

		    unfm = (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + pos - 1;
		    block = get_block_num(unfm, 0);

		    if (block != 0) {
			reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
			put_block_num(unfm, 0, 0);
			journal_mark_dirty (th, p_s_sb, p_s_bh);
			reiserfs_free_block(th, inode, block, 1);
		    }

		    cond_resched();

		    if (item_moved (&s_ih, p_s_path))  {
			need_re_search = 1;
			break;
		    }

		    pos --;
		    (*p_n_removed) ++;
		    (*p_n_cut_size) -= UNFM_P_SIZE;

		    if (pos == 0) {
			(*p_n_cut_size) -= IH_SIZE;
			result = M_DELETE;
			break;
		    }
		}
		/* a trick.  If the buffer has been logged, this will do nothing.  If
		** we've broken the loop without logging it, it will restore the
		** buffer */
		reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh);
	    } while (need_re_search &&
		     search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND);
	    pos_in_item(p_s_path) = pos * UNFM_P_SIZE;

	    if (*p_n_cut_size == 0) {
		/* Nothing were cut. maybe convert last unformatted node to the
		 * direct item? */
		result = M_CONVERT;
	    }
	    return result;
	}
}

/* Calculate number of bytes which will be deleted or cut during balance */
static int calc_deleted_bytes_number(struct tree_balance *p_s_tb, char c_mode)
{
	int n_del_size;
	struct item_head *p_le_ih = PATH_PITEM_HEAD(p_s_tb->tb_path);

	if (is_statdata_le_ih(p_le_ih))
		return 0;

	n_del_size =
	    (c_mode ==
	     M_DELETE) ? ih_item_len(p_le_ih) : -p_s_tb->insert_size[0];
	if (is_direntry_le_ih(p_le_ih)) {
		// return EMPTY_DIR_SIZE; /* We delete emty directoris only. */
		// we can't use EMPTY_DIR_SIZE, as old format dirs have a different
		// empty size.  ick. FIXME, is this right?
		//
		return n_del_size;
	}

	if (is_indirect_le_ih(p_le_ih))
		n_del_size = (n_del_size / UNFM_P_SIZE) * (PATH_PLAST_BUFFER(p_s_tb->tb_path)->b_size);	// - get_ih_free_space (p_le_ih);
	return n_del_size;
}

static void init_tb_struct(struct reiserfs_transaction_handle *th,
			   struct tree_balance *p_s_tb,
			   struct super_block *p_s_sb,
			   struct path *p_s_path, int n_size)
{

	BUG_ON(!th->t_trans_id);

	memset(p_s_tb, '\0', sizeof(struct tree_balance));
	p_s_tb->transaction_handle = th;
	p_s_tb->tb_sb = p_s_sb;
	p_s_tb->tb_path = p_s_path;
	PATH_OFFSET_PBUFFER(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = NULL;
	PATH_OFFSET_POSITION(p_s_path, ILLEGAL_PATH_ELEMENT_OFFSET) = 0;
	p_s_tb->insert_size[0] = n_size;
}

void padd_item(char *item, int total_length, int length)
{
	int i;

	for (i = total_length; i > length;)
		item[--i] = 0;
}

#ifdef REISERQUOTA_DEBUG
char key2type(struct reiserfs_key *ih)
{
	if (is_direntry_le_key(2, ih))
		return 'd';
	if (is_direct_le_key(2, ih))
		return 'D';
	if (is_indirect_le_key(2, ih))
		return 'i';
	if (is_statdata_le_key(2, ih))
		return 's';
	return 'u';
}

char head2type(struct item_head *ih)
{
	if (is_direntry_le_ih(ih))
		return 'd';
	if (is_direct_le_ih(ih))
		return 'D';
	if (is_indirect_le_ih(ih))
		return 'i';
	if (is_statdata_le_ih(ih))
		return 's';
	return 'u';
}
#endif

/* Delete object item. */
int reiserfs_delete_item(struct reiserfs_transaction_handle *th, struct path *p_s_path,	/* Path to the deleted item. */
			 const struct cpu_key *p_s_item_key,	/* Key to search for the deleted item.  */
			 struct inode *p_s_inode,	/* inode is here just to update i_blocks and quotas */
			 struct buffer_head *p_s_un_bh)
{				/* NULL or unformatted node pointer.    */
	struct super_block *p_s_sb = p_s_inode->i_sb;
	struct tree_balance s_del_balance;
	struct item_head s_ih;
	struct item_head *q_ih;
	int quota_cut_bytes;
	int n_ret_value, n_del_size, n_removed;

#ifdef CONFIG_REISERFS_CHECK
	char c_mode;
	int n_iter = 0;
#endif

	BUG_ON(!th->t_trans_id);

	init_tb_struct(th, &s_del_balance, p_s_sb, p_s_path,
		       0 /*size is unknown */ );

	while (1) {
		n_removed = 0;

#ifdef CONFIG_REISERFS_CHECK
		n_iter++;
		c_mode =
#endif
		    prepare_for_delete_or_cut(th, p_s_inode, p_s_path,
					      p_s_item_key, &n_removed,
					      &n_del_size,
					      max_reiserfs_offset(p_s_inode));

		RFALSE(c_mode != M_DELETE, "PAP-5320: mode must be M_DELETE");

		copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
		s_del_balance.insert_size[0] = n_del_size;

		n_ret_value = fix_nodes(M_DELETE, &s_del_balance, NULL, NULL);
		if (n_ret_value != REPEAT_SEARCH)
			break;

		PROC_INFO_INC(p_s_sb, delete_item_restarted);

		// file system changed, repeat search
		n_ret_value =
		    search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
		if (n_ret_value == IO_ERROR)
			break;
		if (n_ret_value == FILE_NOT_FOUND) {
			reiserfs_warning(p_s_sb,
					 "vs-5340: reiserfs_delete_item: "
					 "no items of the file %K found",
					 p_s_item_key);
			break;
		}
	}			/* while (1) */

	if (n_ret_value != CARRY_ON) {
		unfix_nodes(&s_del_balance);
		return 0;
	}
	// reiserfs_delete_item returns item length when success
	n_ret_value = calc_deleted_bytes_number(&s_del_balance, M_DELETE);
	q_ih = get_ih(p_s_path);
	quota_cut_bytes = ih_item_len(q_ih);

	/* hack so the quota code doesn't have to guess if the file
	 ** has a tail.  On tail insert, we allocate quota for 1 unformatted node.
	 ** We test the offset because the tail might have been
	 ** split into multiple items, and we only want to decrement for
	 ** the unfm node once
	 */
	if (!S_ISLNK(p_s_inode->i_mode) && is_direct_le_ih(q_ih)) {
		if ((le_ih_k_offset(q_ih) & (p_s_sb->s_blocksize - 1)) == 1) {
			quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE;
		} else {
			quota_cut_bytes = 0;
		}
	}

	if (p_s_un_bh) {
		int off;
		char *data;

		/* We are in direct2indirect conversion, so move tail contents
		   to the unformatted node */
		/* note, we do the copy before preparing the buffer because we
		 ** don't care about the contents of the unformatted node yet.
		 ** the only thing we really care about is the direct item's data
		 ** is in the unformatted node.
		 **
		 ** Otherwise, we would have to call reiserfs_prepare_for_journal on
		 ** the unformatted node, which might schedule, meaning we'd have to
		 ** loop all the way back up to the start of the while loop.
		 **
		 ** The unformatted node must be dirtied later on.  We can't be
		 ** sure here if the entire tail has been deleted yet.
		 **
		 ** p_s_un_bh is from the page cache (all unformatted nodes are
		 ** from the page cache) and might be a highmem page.  So, we
		 ** can't use p_s_un_bh->b_data.
		 ** -clm
		 */

		data = kmap_atomic(p_s_un_bh->b_page, KM_USER0);
		off = ((le_ih_k_offset(&s_ih) - 1) & (PAGE_CACHE_SIZE - 1));
		memcpy(data + off,
		       B_I_PITEM(PATH_PLAST_BUFFER(p_s_path), &s_ih),
		       n_ret_value);
		kunmap_atomic(data, KM_USER0);
	}
	/* Perform balancing after all resources have been collected at once. */
	do_balance(&s_del_balance, NULL, NULL, M_DELETE);

#ifdef REISERQUOTA_DEBUG
	reiserfs_debug(p_s_sb, REISERFS_DEBUG_CODE,
		       "reiserquota delete_item(): freeing %u, id=%u type=%c",
		       quota_cut_bytes, p_s_inode->i_uid, head2type(&s_ih));
#endif
	DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);

	/* Return deleted body length */
	return n_ret_value;
}

/* Summary Of Mechanisms For Handling Collisions Between Processes:

 deletion of the body of the object is performed by iput(), with the
 result that if multiple processes are operating on a file, the
 deletion of the body of the file is deferred until the last process
 that has an open inode performs its iput().

 writes and truncates are protected from collisions by use of
 semaphores.

 creates, linking, and mknod are protected from collisions with other
 processes by making the reiserfs_add_entry() the last step in the
 creation, and then rolling back all changes if there was a collision.
 - Hans
*/

/* this deletes item which never gets split */
void reiserfs_delete_solid_item(struct reiserfs_transaction_handle *th,
				struct inode *inode, struct reiserfs_key *key)
{
	struct tree_balance tb;
	INITIALIZE_PATH(path);
	int item_len = 0;
	int tb_init = 0;
	struct cpu_key cpu_key;
	int retval;
	int quota_cut_bytes = 0;

	BUG_ON(!th->t_trans_id);

	le_key2cpu_key(&cpu_key, key);

	while (1) {
		retval = search_item(th->t_super, &cpu_key, &path);
		if (retval == IO_ERROR) {
			reiserfs_warning(th->t_super,
					 "vs-5350: reiserfs_delete_solid_item: "
					 "i/o failure occurred trying to delete %K",
					 &cpu_key);
			break;
		}
		if (retval != ITEM_FOUND) {
			pathrelse(&path);
			// No need for a warning, if there is just no free space to insert '..' item into the newly-created subdir
			if (!
			    ((unsigned long long)
			     GET_HASH_VALUE(le_key_k_offset
					    (le_key_version(key), key)) == 0
			     && (unsigned long long)
			     GET_GENERATION_NUMBER(le_key_k_offset
						   (le_key_version(key),
						    key)) == 1))
				reiserfs_warning(th->t_super,
						 "vs-5355: reiserfs_delete_solid_item: %k not found",
						 key);
			break;
		}
		if (!tb_init) {
			tb_init = 1;
			item_len = ih_item_len(PATH_PITEM_HEAD(&path));
			init_tb_struct(th, &tb, th->t_super, &path,
				       -(IH_SIZE + item_len));
		}
		quota_cut_bytes = ih_item_len(PATH_PITEM_HEAD(&path));

		retval = fix_nodes(M_DELETE, &tb, NULL, NULL);
		if (retval == REPEAT_SEARCH) {
			PROC_INFO_INC(th->t_super, delete_solid_item_restarted);
			continue;
		}

		if (retval == CARRY_ON) {
			do_balance(&tb, NULL, NULL, M_DELETE);
			if (inode) {	/* Should we count quota for item? (we don't count quotas for save-links) */
#ifdef REISERQUOTA_DEBUG
				reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
					       "reiserquota delete_solid_item(): freeing %u id=%u type=%c",
					       quota_cut_bytes, inode->i_uid,
					       key2type(key));
#endif
				DQUOT_FREE_SPACE_NODIRTY(inode,
							 quota_cut_bytes);
			}
			break;
		}
		// IO_ERROR, NO_DISK_SPACE, etc
		reiserfs_warning(th->t_super,
				 "vs-5360: reiserfs_delete_solid_item: "
				 "could not delete %K due to fix_nodes failure",
				 &cpu_key);
		unfix_nodes(&tb);
		break;
	}

	reiserfs_check_path(&path);
}

int reiserfs_delete_object(struct reiserfs_transaction_handle *th,
			   struct inode *inode)
{
	int err;
	inode->i_size = 0;
	BUG_ON(!th->t_trans_id);

	/* for directory this deletes item containing "." and ".." */
	err =
	    reiserfs_do_truncate(th, inode, NULL, 0 /*no timestamp updates */ );
	if (err)
		return err;

#if defined( USE_INODE_GENERATION_COUNTER )
	if (!old_format_only(th->t_super)) {
		__le32 *inode_generation;

		inode_generation =
		    &REISERFS_SB(th->t_super)->s_rs->s_inode_generation;
		*inode_generation =
		    cpu_to_le32(le32_to_cpu(*inode_generation) + 1);
	}
/* USE_INODE_GENERATION_COUNTER */
#endif
	reiserfs_delete_solid_item(th, inode, INODE_PKEY(inode));

	return err;
}

static void unmap_buffers(struct page *page, loff_t pos)
{
	struct buffer_head *bh;
	struct buffer_head *head;
	struct buffer_head *next;
	unsigned long tail_index;
	unsigned long cur_index;

	if (page) {
		if (page_has_buffers(page)) {
			tail_index = pos & (PAGE_CACHE_SIZE - 1);
			cur_index = 0;
			head = page_buffers(page);
			bh = head;
			do {
				next = bh->b_this_page;

				/* we want to unmap the buffers that contain the tail, and
				 ** all the buffers after it (since the tail must be at the
				 ** end of the file).  We don't want to unmap file data
				 ** before the tail, since it might be dirty and waiting to
				 ** reach disk
				 */
				cur_index += bh->b_size;
				if (cur_index > tail_index) {
					reiserfs_unmap_buffer(bh);
				}
				bh = next;
			} while (bh != head);
			if (PAGE_SIZE == bh->b_size) {
				clear_page_dirty(page);
			}
		}
	}
}

static int maybe_indirect_to_direct(struct reiserfs_transaction_handle *th,
				    struct inode *p_s_inode,
				    struct page *page,
				    struct path *p_s_path,
				    const struct cpu_key *p_s_item_key,
				    loff_t n_new_file_size, char *p_c_mode)
{
	struct super_block *p_s_sb = p_s_inode->i_sb;
	int n_block_size = p_s_sb->s_blocksize;
	int cut_bytes;
	BUG_ON(!th->t_trans_id);

	if (n_new_file_size != p_s_inode->i_size)
		BUG();

	/* the page being sent in could be NULL if there was an i/o error
	 ** reading in the last block.  The user will hit problems trying to
	 ** read the file, but for now we just skip the indirect2direct
	 */
	if (atomic_read(&p_s_inode->i_count) > 1 ||
	    !tail_has_to_be_packed(p_s_inode) ||
	    !page || (REISERFS_I(p_s_inode)->i_flags & i_nopack_mask)) {
		// leave tail in an unformatted node    
		*p_c_mode = M_SKIP_BALANCING;
		cut_bytes =
		    n_block_size - (n_new_file_size & (n_block_size - 1));
		pathrelse(p_s_path);
		return cut_bytes;
	}
	/* Permorm the conversion to a direct_item. */
	/*return indirect_to_direct (p_s_inode, p_s_path, p_s_item_key, n_new_file_size, p_c_mode); */
	return indirect2direct(th, p_s_inode, page, p_s_path, p_s_item_key,
			       n_new_file_size, p_c_mode);
}

/* we did indirect_to_direct conversion. And we have inserted direct
   item successesfully, but there were no disk space to cut unfm
   pointer being converted. Therefore we have to delete inserted
   direct item(s) */
static void indirect_to_direct_roll_back(struct reiserfs_transaction_handle *th,
					 struct inode *inode, struct path *path)
{
	struct cpu_key tail_key;
	int tail_len;
	int removed;
	BUG_ON(!th->t_trans_id);

	make_cpu_key(&tail_key, inode, inode->i_size + 1, TYPE_DIRECT, 4);	// !!!!
	tail_key.key_length = 4;

	tail_len =
	    (cpu_key_k_offset(&tail_key) & (inode->i_sb->s_blocksize - 1)) - 1;
	while (tail_len) {
		/* look for the last byte of the tail */
		if (search_for_position_by_key(inode->i_sb, &tail_key, path) ==
		    POSITION_NOT_FOUND)
			reiserfs_panic(inode->i_sb,
				       "vs-5615: indirect_to_direct_roll_back: found invalid item");
		RFALSE(path->pos_in_item !=
		       ih_item_len(PATH_PITEM_HEAD(path)) - 1,
		       "vs-5616: appended bytes found");
		PATH_LAST_POSITION(path)--;

		removed =
		    reiserfs_delete_item(th, path, &tail_key, inode,
					 NULL /*unbh not needed */ );
		RFALSE(removed <= 0
		       || removed > tail_len,
		       "vs-5617: there was tail %d bytes, removed item length %d bytes",
		       tail_len, removed);
		tail_len -= removed;
		set_cpu_key_k_offset(&tail_key,
				     cpu_key_k_offset(&tail_key) - removed);
	}
	reiserfs_warning(inode->i_sb,
			 "indirect_to_direct_roll_back: indirect_to_direct conversion has been rolled back due to lack of disk space");
	//mark_file_without_tail (inode);
	mark_inode_dirty(inode);
}

/* (Truncate or cut entry) or delete object item. Returns < 0 on failure */
int reiserfs_cut_from_item(struct reiserfs_transaction_handle *th,
			   struct path *p_s_path,
			   struct cpu_key *p_s_item_key,
			   struct inode *p_s_inode,
			   struct page *page, loff_t n_new_file_size)
{
	struct super_block *p_s_sb = p_s_inode->i_sb;
	/* Every function which is going to call do_balance must first
	   create a tree_balance structure.  Then it must fill up this
	   structure by using the init_tb_struct and fix_nodes functions.
	   After that we can make tree balancing. */
	struct tree_balance s_cut_balance;
	struct item_head *p_le_ih;
	int n_cut_size = 0,	/* Amount to be cut. */
	    n_ret_value = CARRY_ON, n_removed = 0,	/* Number of the removed unformatted nodes. */
	    n_is_inode_locked = 0;
	char c_mode;		/* Mode of the balance. */
	int retval2 = -1;
	int quota_cut_bytes;
	loff_t tail_pos = 0;

	BUG_ON(!th->t_trans_id);

	init_tb_struct(th, &s_cut_balance, p_s_inode->i_sb, p_s_path,
		       n_cut_size);

	/* Repeat this loop until we either cut the item without needing
	   to balance, or we fix_nodes without schedule occurring */
	while (1) {
		/* Determine the balance mode, position of the first byte to
		   be cut, and size to be cut.  In case of the indirect item
		   free unformatted nodes which are pointed to by the cut
		   pointers. */

		c_mode =
		    prepare_for_delete_or_cut(th, p_s_inode, p_s_path,
					      p_s_item_key, &n_removed,
					      &n_cut_size, n_new_file_size);
		if (c_mode == M_CONVERT) {
			/* convert last unformatted node to direct item or leave
			   tail in the unformatted node */
			RFALSE(n_ret_value != CARRY_ON,
			       "PAP-5570: can not convert twice");

			n_ret_value =
			    maybe_indirect_to_direct(th, p_s_inode, page,
						     p_s_path, p_s_item_key,
						     n_new_file_size, &c_mode);
			if (c_mode == M_SKIP_BALANCING)
				/* tail has been left in the unformatted node */
				return n_ret_value;

			n_is_inode_locked = 1;

			/* removing of last unformatted node will change value we
			   have to return to truncate. Save it */
			retval2 = n_ret_value;
			/*retval2 = p_s_sb->s_blocksize - (n_new_file_size & (p_s_sb->s_blocksize - 1)); */

			/* So, we have performed the first part of the conversion:
			   inserting the new direct item.  Now we are removing the
			   last unformatted node pointer. Set key to search for
			   it. */
			set_cpu_key_k_type(p_s_item_key, TYPE_INDIRECT);
			p_s_item_key->key_length = 4;
			n_new_file_size -=
			    (n_new_file_size & (p_s_sb->s_blocksize - 1));
			tail_pos = n_new_file_size;
			set_cpu_key_k_offset(p_s_item_key, n_new_file_size + 1);
			if (search_for_position_by_key
			    (p_s_sb, p_s_item_key,
			     p_s_path) == POSITION_NOT_FOUND) {
				print_block(PATH_PLAST_BUFFER(p_s_path), 3,
					    PATH_LAST_POSITION(p_s_path) - 1,
					    PATH_LAST_POSITION(p_s_path) + 1);
				reiserfs_panic(p_s_sb,
					       "PAP-5580: reiserfs_cut_from_item: item to convert does not exist (%K)",
					       p_s_item_key);
			}
			continue;
		}
		if (n_cut_size == 0) {
			pathrelse(p_s_path);
			return 0;
		}

		s_cut_balance.insert_size[0] = n_cut_size;

		n_ret_value = fix_nodes(c_mode, &s_cut_balance, NULL, NULL);
		if (n_ret_value != REPEAT_SEARCH)
			break;

		PROC_INFO_INC(p_s_sb, cut_from_item_restarted);

		n_ret_value =
		    search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path);
		if (n_ret_value == POSITION_FOUND)
			continue;

		reiserfs_warning(p_s_sb,
				 "PAP-5610: reiserfs_cut_from_item: item %K not found",
				 p_s_item_key);
		unfix_nodes(&s_cut_balance);
		return (n_ret_value == IO_ERROR) ? -EIO : -ENOENT;
	}			/* while */

	// check fix_nodes results (IO_ERROR or NO_DISK_SPACE)
	if (n_ret_value != CARRY_ON) {
		if (n_is_inode_locked) {
			// FIXME: this seems to be not needed: we are always able
			// to cut item
			indirect_to_direct_roll_back(th, p_s_inode, p_s_path);
		}
		if (n_ret_value == NO_DISK_SPACE)
			reiserfs_warning(p_s_sb, "NO_DISK_SPACE");
		unfix_nodes(&s_cut_balance);
		return -EIO;
	}

	/* go ahead and perform balancing */

	RFALSE(c_mode == M_PASTE || c_mode == M_INSERT, "invalid mode");

	/* Calculate number of bytes that need to be cut from the item. */
	quota_cut_bytes =
	    (c_mode ==
	     M_DELETE) ? ih_item_len(get_ih(p_s_path)) : -s_cut_balance.
	    insert_size[0];
	if (retval2 == -1)
		n_ret_value = calc_deleted_bytes_number(&s_cut_balance, c_mode);
	else
		n_ret_value = retval2;

	/* For direct items, we only change the quota when deleting the last
	 ** item.
	 */
	p_le_ih = PATH_PITEM_HEAD(s_cut_balance.tb_path);
	if (!S_ISLNK(p_s_inode->i_mode) && is_direct_le_ih(p_le_ih)) {
		if (c_mode == M_DELETE &&
		    (le_ih_k_offset(p_le_ih) & (p_s_sb->s_blocksize - 1)) ==
		    1) {
			// FIXME: this is to keep 3.5 happy
			REISERFS_I(p_s_inode)->i_first_direct_byte = U32_MAX;
			quota_cut_bytes = p_s_sb->s_blocksize + UNFM_P_SIZE;
		} else {
			quota_cut_bytes = 0;
		}
	}
#ifdef CONFIG_REISERFS_CHECK
	if (n_is_inode_locked) {
		struct item_head *le_ih =
		    PATH_PITEM_HEAD(s_cut_balance.tb_path);
		/* we are going to complete indirect2direct conversion. Make
		   sure, that we exactly remove last unformatted node pointer
		   of the item */
		if (!is_indirect_le_ih(le_ih))
			reiserfs_panic(p_s_sb,
				       "vs-5652: reiserfs_cut_from_item: "
				       "item must be indirect %h", le_ih);

		if (c_mode == M_DELETE && ih_item_len(le_ih) != UNFM_P_SIZE)
			reiserfs_panic(p_s_sb,
				       "vs-5653: reiserfs_cut_from_item: "
				       "completing indirect2direct conversion indirect item %h "
				       "being deleted must be of 4 byte long",
				       le_ih);

		if (c_mode == M_CUT
		    && s_cut_balance.insert_size[0] != -UNFM_P_SIZE) {
			reiserfs_panic(p_s_sb,
				       "vs-5654: reiserfs_cut_from_item: "
				       "can not complete indirect2direct conversion of %h (CUT, insert_size==%d)",
				       le_ih, s_cut_balance.insert_size[0]);
		}
		/* it would be useful to make sure, that right neighboring
		   item is direct item of this file */
	}
#endif

	do_balance(&s_cut_balance, NULL, NULL, c_mode);
	if (n_is_inode_locked) {
		/* we've done an indirect->direct conversion.  when the data block
		 ** was freed, it was removed from the list of blocks that must
		 ** be flushed before the transaction commits, make sure to
		 ** unmap and invalidate it
		 */
		unmap_buffers(page, tail_pos);
		REISERFS_I(p_s_inode)->i_flags &= ~i_pack_on_close_mask;
	}
#ifdef REISERQUOTA_DEBUG
	reiserfs_debug(p_s_inode->i_sb, REISERFS_DEBUG_CODE,
		       "reiserquota cut_from_item(): freeing %u id=%u type=%c",
		       quota_cut_bytes, p_s_inode->i_uid, '?');
#endif
	DQUOT_FREE_SPACE_NODIRTY(p_s_inode, quota_cut_bytes);
	return n_ret_value;
}

static void truncate_directory(struct reiserfs_transaction_handle *th,
			       struct inode *inode)
{
	BUG_ON(!th->t_trans_id);
	if (inode->i_nlink)
		reiserfs_warning(inode->i_sb,
				 "vs-5655: truncate_directory: link count != 0");

	set_le_key_k_offset(KEY_FORMAT_3_5, INODE_PKEY(inode), DOT_OFFSET);
	set_le_key_k_type(KEY_FORMAT_3_5, INODE_PKEY(inode), TYPE_DIRENTRY);
	reiserfs_delete_solid_item(th, inode, INODE_PKEY(inode));
	reiserfs_update_sd(th, inode);
	set_le_key_k_offset(KEY_FORMAT_3_5, INODE_PKEY(inode), SD_OFFSET);
	set_le_key_k_type(KEY_FORMAT_3_5, INODE_PKEY(inode), TYPE_STAT_DATA);
}

/* Truncate file to the new size. Note, this must be called with a transaction
   already started */
int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p_s_inode,	/* ->i_size contains new
												   size */
			 struct page *page,	/* up to date for last block */
			 int update_timestamps	/* when it is called by
						   file_release to convert
						   the tail - no timestamps
						   should be updated */
    )
{
	INITIALIZE_PATH(s_search_path);	/* Path to the current object item. */
	struct item_head *p_le_ih;	/* Pointer to an item header. */
	struct cpu_key s_item_key;	/* Key to search for a previous file item. */
	loff_t n_file_size,	/* Old file size. */
	 n_new_file_size;	/* New file size. */
	int n_deleted;		/* Number of deleted or truncated bytes. */
	int retval;
	int err = 0;

	BUG_ON(!th->t_trans_id);
	if (!
	    (S_ISREG(p_s_inode->i_mode) || S_ISDIR(p_s_inode->i_mode)
	     || S_ISLNK(p_s_inode->i_mode)))
		return 0;

	if (S_ISDIR(p_s_inode->i_mode)) {
		// deletion of directory - no need to update timestamps
		truncate_directory(th, p_s_inode);
		return 0;
	}

	/* Get new file size. */
	n_new_file_size = p_s_inode->i_size;

	// FIXME: note, that key type is unimportant here
	make_cpu_key(&s_item_key, p_s_inode, max_reiserfs_offset(p_s_inode),
		     TYPE_DIRECT, 3);

	retval =
	    search_for_position_by_key(p_s_inode->i_sb, &s_item_key,
				       &s_search_path);
	if (retval == IO_ERROR) {
		reiserfs_warning(p_s_inode->i_sb,
				 "vs-5657: reiserfs_do_truncate: "
				 "i/o failure occurred trying to truncate %K",
				 &s_item_key);
		err = -EIO;
		goto out;
	}
	if (retval == POSITION_FOUND || retval == FILE_NOT_FOUND) {
		reiserfs_warning(p_s_inode->i_sb,
				 "PAP-5660: reiserfs_do_truncate: "
				 "wrong result %d of search for %K", retval,
				 &s_item_key);

		err = -EIO;
		goto out;
	}

	s_search_path.pos_in_item--;

	/* Get real file size (total length of all file items) */
	p_le_ih = PATH_PITEM_HEAD(&s_search_path);
	if (is_statdata_le_ih(p_le_ih))
		n_file_size = 0;
	else {
		loff_t offset = le_ih_k_offset(p_le_ih);
		int bytes =
		    op_bytes_number(p_le_ih, p_s_inode->i_sb->s_blocksize);

		/* this may mismatch with real file size: if last direct item
		   had no padding zeros and last unformatted node had no free
		   space, this file would have this file size */
		n_file_size = offset + bytes - 1;
	}
	/*
	 * are we doing a full truncate or delete, if so
	 * kick in the reada code
	 */
	if (n_new_file_size == 0)
		s_search_path.reada = PATH_READA | PATH_READA_BACK;

	if (n_file_size == 0 || n_file_size < n_new_file_size) {
		goto update_and_out;
	}

	/* Update key to search for the last file item. */
	set_cpu_key_k_offset(&s_item_key, n_file_size);

	do {
		/* Cut or delete file item. */
		n_deleted =
		    reiserfs_cut_from_item(th, &s_search_path, &s_item_key,
					   p_s_inode, page, n_new_file_size);
		if (n_deleted < 0) {
			reiserfs_warning(p_s_inode->i_sb,
					 "vs-5665: reiserfs_do_truncate: reiserfs_cut_from_item failed");
			reiserfs_check_path(&s_search_path);
			return 0;
		}

		RFALSE(n_deleted > n_file_size,
		       "PAP-5670: reiserfs_cut_from_item: too many bytes deleted: deleted %d, file_size %lu, item_key %K",
		       n_deleted, n_file_size, &s_item_key);

		/* Change key to search the last file item. */
		n_file_size -= n_deleted;

		set_cpu_key_k_offset(&s_item_key, n_file_size);

		/* While there are bytes to truncate and previous file item is presented in the tree. */

		/*
		 ** This loop could take a really long time, and could log 
		 ** many more blocks than a transaction can hold.  So, we do a polite
		 ** journal end here, and if the transaction needs ending, we make
		 ** sure the file is consistent before ending the current trans
		 ** and starting a new one
		 */
		if (journal_transaction_should_end(th, 0) ||
		    reiserfs_transaction_free_space(th) <= JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD) {
			int orig_len_alloc = th->t_blocks_allocated;
			decrement_counters_in_path(&s_search_path);

			if (update_timestamps) {
				p_s_inode->i_mtime = p_s_inode->i_ctime =
				    CURRENT_TIME_SEC;
			}
			reiserfs_update_sd(th, p_s_inode);

			err = journal_end(th, p_s_inode->i_sb, orig_len_alloc);
			if (err)
				goto out;
			err = journal_begin(th, p_s_inode->i_sb,
					    JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD + JOURNAL_PER_BALANCE_CNT * 4) ;
			if (err)
				goto out;
			reiserfs_update_inode_transaction(p_s_inode);
		}
	} while (n_file_size > ROUND_UP(n_new_file_size) &&
		 search_for_position_by_key(p_s_inode->i_sb, &s_item_key,
					    &s_search_path) == POSITION_FOUND);

	RFALSE(n_file_size > ROUND_UP(n_new_file_size),
	       "PAP-5680: truncate did not finish: new_file_size %Ld, current %Ld, oid %d",
	       n_new_file_size, n_file_size, s_item_key.on_disk_key.k_objectid);

      update_and_out:
	if (update_timestamps) {
		// this is truncate, not file closing
		p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
	}
	reiserfs_update_sd(th, p_s_inode);

      out:
	pathrelse(&s_search_path);
	return err;
}

#ifdef CONFIG_REISERFS_CHECK
// this makes sure, that we __append__, not overwrite or add holes
static void check_research_for_paste(struct path *path,
				     const struct cpu_key *p_s_key)
{
	struct item_head *found_ih = get_ih(path);

	if (is_direct_le_ih(found_ih)) {
		if (le_ih_k_offset(found_ih) +
		    op_bytes_number(found_ih,
				    get_last_bh(path)->b_size) !=
		    cpu_key_k_offset(p_s_key)
		    || op_bytes_number(found_ih,
				       get_last_bh(path)->b_size) !=
		    pos_in_item(path))
			reiserfs_panic(NULL,
				       "PAP-5720: check_research_for_paste: "
				       "found direct item %h or position (%d) does not match to key %K",
				       found_ih, pos_in_item(path), p_s_key);
	}
	if (is_indirect_le_ih(found_ih)) {
		if (le_ih_k_offset(found_ih) +
		    op_bytes_number(found_ih,
				    get_last_bh(path)->b_size) !=
		    cpu_key_k_offset(p_s_key)
		    || I_UNFM_NUM(found_ih) != pos_in_item(path)
		    || get_ih_free_space(found_ih) != 0)
			reiserfs_panic(NULL,
				       "PAP-5730: check_research_for_paste: "
				       "found indirect item (%h) or position (%d) does not match to key (%K)",
				       found_ih, pos_in_item(path), p_s_key);
	}
}
#endif				/* config reiserfs check */

/* Paste bytes to the existing item. Returns bytes number pasted into the item. */
int reiserfs_paste_into_item(struct reiserfs_transaction_handle *th, struct path *p_s_search_path,	/* Path to the pasted item.          */
			     const struct cpu_key *p_s_key,	/* Key to search for the needed item. */
			     struct inode *inode,	/* Inode item belongs to */
			     const char *p_c_body,	/* Pointer to the bytes to paste.    */
			     int n_pasted_size)
{				/* Size of pasted bytes.             */
	struct tree_balance s_paste_balance;
	int retval;
	int fs_gen;

	BUG_ON(!th->t_trans_id);

	fs_gen = get_generation(inode->i_sb);

#ifdef REISERQUOTA_DEBUG
	reiserfs_debug(inode->i_sb, REISERFS_DEBUG_CODE,
		       "reiserquota paste_into_item(): allocating %u id=%u type=%c",
		       n_pasted_size, inode->i_uid,
		       key2type(&(p_s_key->on_disk_key)));
#endif

	if (DQUOT_ALLOC_SPACE_NODIRTY(inode, n_pasted_size)) {
		pathrelse(p_s_search_path);
		return -EDQUOT;
	}
	init_tb_struct(th, &s_paste_balance, th->t_super, p_s_search_path,
		       n_pasted_size);
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
	s_paste_balance.key = p_s_key->on_disk_key;
#endif

	/* DQUOT_* can schedule, must check before the fix_nodes */
	if (fs_changed(fs_gen, inode->i_sb)) {
		goto search_again;
	}

	while ((retval =
		fix_nodes(M_PASTE, &s_paste_balance, NULL,
			  p_c_body)) == REPEAT_SEARCH) {
	      search_again:
		/* file system changed while we were in the fix_nodes */
		PROC_INFO_INC(th->t_super, paste_into_item_restarted);
		retval =
		    search_for_position_by_key(th->t_super, p_s_key,
					       p_s_search_path);
		if (retval == IO_ERROR) {
			retval = -EIO;
			goto error_out;
		}
		if (retval == POSITION_FOUND) {
			reiserfs_warning(inode->i_sb,
					 "PAP-5710: reiserfs_paste_into_item: entry or pasted byte (%K) exists",
					 p_s_key);
			retval = -EEXIST;
			goto error_out;
		}
#ifdef CONFIG_REISERFS_CHECK
		check_research_for_paste(p_s_search_path, p_s_key);
#endif
	}

	/* Perform balancing after all resources are collected by fix_nodes, and
	   accessing them will not risk triggering schedule. */
	if (retval == CARRY_ON) {
		do_balance(&s_paste_balance, NULL /*ih */ , p_c_body, M_PASTE);
		return 0;
	}
	retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
      error_out:
	/* this also releases the path */
	unfix_nodes(&s_paste_balance);
#ifdef REISERQUOTA_DEBUG
	reiserfs_debug(inode->i_sb, REISERFS_DEBUG_CODE,
		       "reiserquota paste_into_item(): freeing %u id=%u type=%c",
		       n_pasted_size, inode->i_uid,
		       key2type(&(p_s_key->on_disk_key)));
#endif
	DQUOT_FREE_SPACE_NODIRTY(inode, n_pasted_size);
	return retval;
}

/* Insert new item into the buffer at the path. */
int reiserfs_insert_item(struct reiserfs_transaction_handle *th, struct path *p_s_path,	/* Path to the inserteded item.         */
			 const struct cpu_key *key, struct item_head *p_s_ih,	/* Pointer to the item header to insert. */
			 struct inode *inode, const char *p_c_body)
{				/* Pointer to the bytes to insert.      */
	struct tree_balance s_ins_balance;
	int retval;
	int fs_gen = 0;
	int quota_bytes = 0;

	BUG_ON(!th->t_trans_id);

	if (inode) {		/* Do we count quotas for item? */
		fs_gen = get_generation(inode->i_sb);
		quota_bytes = ih_item_len(p_s_ih);

		/* hack so the quota code doesn't have to guess if the file has
		 ** a tail, links are always tails, so there's no guessing needed
		 */
		if (!S_ISLNK(inode->i_mode) && is_direct_le_ih(p_s_ih)) {
			quota_bytes = inode->i_sb->s_blocksize + UNFM_P_SIZE;
		}
#ifdef REISERQUOTA_DEBUG
		reiserfs_debug(inode->i_sb, REISERFS_DEBUG_CODE,
			       "reiserquota insert_item(): allocating %u id=%u type=%c",
			       quota_bytes, inode->i_uid, head2type(p_s_ih));
#endif
		/* We can't dirty inode here. It would be immediately written but
		 * appropriate stat item isn't inserted yet... */
		if (DQUOT_ALLOC_SPACE_NODIRTY(inode, quota_bytes)) {
			pathrelse(p_s_path);
			return -EDQUOT;
		}
	}
	init_tb_struct(th, &s_ins_balance, th->t_super, p_s_path,
		       IH_SIZE + ih_item_len(p_s_ih));
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
	s_ins_balance.key = key->on_disk_key;
#endif
	/* DQUOT_* can schedule, must check to be sure calling fix_nodes is safe */
	if (inode && fs_changed(fs_gen, inode->i_sb)) {
		goto search_again;
	}

	while ((retval =
		fix_nodes(M_INSERT, &s_ins_balance, p_s_ih,
			  p_c_body)) == REPEAT_SEARCH) {
	      search_again:
		/* file system changed while we were in the fix_nodes */
		PROC_INFO_INC(th->t_super, insert_item_restarted);
		retval = search_item(th->t_super, key, p_s_path);
		if (retval == IO_ERROR) {
			retval = -EIO;
			goto error_out;
		}
		if (retval == ITEM_FOUND) {
			reiserfs_warning(th->t_super,
					 "PAP-5760: reiserfs_insert_item: "
					 "key %K already exists in the tree",
					 key);
			retval = -EEXIST;
			goto error_out;
		}
	}

	/* make balancing after all resources will be collected at a time */
	if (retval == CARRY_ON) {
		do_balance(&s_ins_balance, p_s_ih, p_c_body, M_INSERT);
		return 0;
	}

	retval = (retval == NO_DISK_SPACE) ? -ENOSPC : -EIO;
      error_out:
	/* also releases the path */
	unfix_nodes(&s_ins_balance);
#ifdef REISERQUOTA_DEBUG
	reiserfs_debug(th->t_super, REISERFS_DEBUG_CODE,
		       "reiserquota insert_item(): freeing %u id=%u type=%c",
		       quota_bytes, inode->i_uid, head2type(p_s_ih));
#endif
	if (inode)
		DQUOT_FREE_SPACE_NODIRTY(inode, quota_bytes);
	return retval;
}
