/*
 *  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/config.h>
#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. */
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)},}
};

const struct in_core_key  MAX_IN_CORE_KEY = {~0U, ~0U, ~0ULL>>4, 15};

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


/*  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                   n_unfm_number,    /* Number of the item unformatted nodes. */
	    n_counter,
	    n_blk_size;
	__le32               * p_n_unfm_pointer; /* Pointer to the unformatted node number. */
	__u32 tmp;
	struct item_head      s_ih;           /* Item header. */
	char                  c_mode;           /* Returned mode of the balance. */
	int need_research;


	n_blk_size = p_s_sb->s_blocksize;

	/* Search for the needed object indirect item until there are no unformatted nodes to be removed. */
	do  {
	    need_research = 0;
            p_s_bh = PATH_PLAST_BUFFER(p_s_path);
	    /* Copy indirect item header to a temp variable. */
	    copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
	    /* Calculate number of unformatted nodes in this item. */
	    n_unfm_number = I_UNFM_NUM(&s_ih);

	    RFALSE( ! is_indirect_le_ih(&s_ih) || ! n_unfm_number ||
		    pos_in_item (p_s_path) + 1 !=  n_unfm_number,
		    "PAP-5240: invalid item %h "
		    "n_unfm_number = %d *p_n_pos_in_item = %d", 
		    &s_ih, n_unfm_number, pos_in_item (p_s_path));

	    /* Calculate balance mode and position in the item to remove unformatted nodes. */
	    if ( n_new_file_length == max_reiserfs_offset (inode) ) {/* Case of delete. */
		pos_in_item (p_s_path) = 0;
		*p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
		c_mode = M_DELETE;
	    }
	    else  { /* Case of truncate. */
		if ( n_new_file_length < le_ih_k_offset (&s_ih) )  {
		    pos_in_item (p_s_path) = 0;
		    *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
		    c_mode = M_DELETE; /* Delete this item. */
		}
		else  {
		    /* indirect item must be truncated starting from *p_n_pos_in_item-th position */
		    pos_in_item (p_s_path) = (n_new_file_length + n_blk_size - le_ih_k_offset (&s_ih) ) >> p_s_sb->s_blocksize_bits;

		    RFALSE( pos_in_item (p_s_path) > n_unfm_number,
			    "PAP-5250: invalid position in the item");

		    /* Either convert last unformatted node of indirect item to direct item or increase
		       its free space.  */
		    if ( pos_in_item (p_s_path) == n_unfm_number )  {
			*p_n_cut_size = 0; /* Nothing to cut. */
			return M_CONVERT; /* Maybe convert last unformatted node to the direct item. */
		    }
		    /* Calculate size to cut. */
		    *p_n_cut_size = -(ih_item_len(&s_ih) - pos_in_item(p_s_path) * UNFM_P_SIZE);

		    c_mode = M_CUT;     /* Cut from this indirect item. */
		}
	    }

	    RFALSE( n_unfm_number <= pos_in_item (p_s_path),
		    "PAP-5260: invalid position in the indirect item");

	    /* pointers to be cut */
	    n_unfm_number -= pos_in_item (p_s_path);
	    /* Set pointer to the last unformatted node pointer that is to be cut. */
	    p_n_unfm_pointer = (__le32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1 - *p_n_removed;


	    /* We go through the unformatted nodes pointers of the indirect
	       item and look for the unformatted nodes in the cache. If we
	       found some of them we free it, zero corresponding indirect item
	       entry and log buffer containing that indirect item. For this we
	       need to prepare last path element for logging. If some
	       unformatted node has b_count > 1 we must not free this
	       unformatted node since it is in use. */
	    reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
	    // note: path could be changed, first line in for loop takes care
	    // of it

	    for (n_counter = *p_n_removed;
		 n_counter < n_unfm_number; n_counter++, p_n_unfm_pointer-- ) {

		cond_resched();
		if (item_moved (&s_ih, p_s_path)) {
		    need_research = 1 ;
		    break;
		}
		RFALSE( p_n_unfm_pointer < (__le32 *)B_I_PITEM(p_s_bh, &s_ih) ||
			p_n_unfm_pointer > (__le32 *)B_I_PITEM(p_s_bh, &s_ih) + I_UNFM_NUM(&s_ih) - 1,
			"vs-5265: pointer out of range");

		/* Hole, nothing to remove. */
		if ( ! get_block_num(p_n_unfm_pointer,0) )  {
			(*p_n_removed)++;
			continue;
		}

		(*p_n_removed)++;

		tmp = get_block_num(p_n_unfm_pointer,0);
		put_block_num(p_n_unfm_pointer, 0, 0);
		journal_mark_dirty (th, p_s_sb, p_s_bh);
		reiserfs_free_block(th, inode, tmp, 1);
		if ( item_moved (&s_ih, p_s_path) )  {
			need_research = 1;
			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);

	    /* This loop can be optimized. */
	} while ( (*p_n_removed < n_unfm_number || need_research) &&
		  search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND );

	RFALSE( *p_n_removed < n_unfm_number, 
		"PAP-5310: indirect item is not found");
	RFALSE( item_moved (&s_ih, p_s_path), 
		"after while, comp failed, retry") ;

	if (c_mode == M_CUT)
	    pos_in_item (p_s_path) *= UNFM_P_SIZE;
	return c_mode;
    }
}

/* 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, th->t_blocks_allocated)) {
	  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_PER_BALANCE_CNT * 6);
	  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; 
}




