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

#include <linux/config.h>
#include <linux/time.h>
#include <linux/fs.h>
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <linux/buffer_head.h>
#include <linux/mpage.h>
#include <linux/writeback.h>
#include <linux/quotaops.h>

extern int reiserfs_default_io_size; /* default io size devuned in super.c */

static int reiserfs_commit_write(struct file *f, struct page *page,
                                 unsigned from, unsigned to);
static int reiserfs_prepare_write(struct file *f, struct page *page,
				  unsigned from, unsigned to);

void reiserfs_delete_inode (struct inode * inode)
{
    /* We need blocks for transaction + (user+group) quota update (possibly delete) */
    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 2 + 2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
    struct reiserfs_transaction_handle th ;
  
    reiserfs_write_lock(inode->i_sb);

    /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */
    if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */
	down (&inode->i_sem); 

	reiserfs_delete_xattrs (inode);

	if (journal_begin(&th, inode->i_sb, jbegin_count)) {
	    up (&inode->i_sem);
	    goto out;
	}
	reiserfs_update_inode_transaction(inode) ;

	if (reiserfs_delete_object (&th, inode)) {
	    up (&inode->i_sem);
	    goto out;
	}

	/* Do quota update inside a transaction for journaled quotas. We must do that
	 * after delete_object so that quota updates go into the same transaction as
	 * stat data deletion */
	DQUOT_FREE_INODE(inode);

	if (journal_end(&th, inode->i_sb, jbegin_count)) {
	    up (&inode->i_sem);
	    goto out;
	}

        up (&inode->i_sem);

        /* all items of file are deleted, so we can remove "save" link */
	remove_save_link (inode, 0/* not truncate */); /* we can't do anything
                                                        * about an error here */
    } else {
	/* no object items are in the tree */
	;
    }
out:
    clear_inode (inode); /* note this must go after the journal_end to prevent deadlock */
    inode->i_blocks = 0;
    reiserfs_write_unlock(inode->i_sb);
}

static void _make_cpu_key (struct cpu_key * key, int version, __u32 dirid, __u32 objectid, 
	       loff_t offset, int type, int length )
{
    key->version = version;

    key->on_disk_key.k_dir_id = dirid;
    key->on_disk_key.k_objectid = objectid;
    set_cpu_key_k_offset (key, offset);
    set_cpu_key_k_type (key, type);  
    key->key_length = length;
}


/* take base of inode_key (it comes from inode always) (dirid, objectid) and version from an inode, set
   offset and type of key */
void make_cpu_key (struct cpu_key * key, struct inode * inode, loff_t offset,
	      int type, int length )
{
  _make_cpu_key (key, get_inode_item_key_version (inode), le32_to_cpu (INODE_PKEY (inode)->k_dir_id),
		 le32_to_cpu (INODE_PKEY (inode)->k_objectid), 
		 offset, type, length);
}


//
// when key is 0, do not set version and short key
//
inline void make_le_item_head (struct item_head * ih, const struct cpu_key * key,
			       int version,
			       loff_t offset, int type, int length, 
			       int entry_count/*or ih_free_space*/)
{
    if (key) {
	ih->ih_key.k_dir_id = cpu_to_le32 (key->on_disk_key.k_dir_id);
	ih->ih_key.k_objectid = cpu_to_le32 (key->on_disk_key.k_objectid);
    }
    put_ih_version( ih, version );
    set_le_ih_k_offset (ih, offset);
    set_le_ih_k_type (ih, type);
    put_ih_item_len( ih, length );
    /*    set_ih_free_space (ih, 0);*/
    // for directory items it is entry count, for directs and stat
    // datas - 0xffff, for indirects - 0
    put_ih_entry_count( ih, entry_count );
}

//
// FIXME: we might cache recently accessed indirect item

// Ugh.  Not too eager for that....
//  I cut the code until such time as I see a convincing argument (benchmark).
// I don't want a bloated inode struct..., and I don't like code complexity....

/* cutting the code is fine, since it really isn't in use yet and is easy
** to add back in.  But, Vladimir has a really good idea here.  Think
** about what happens for reading a file.  For each page,
** The VFS layer calls reiserfs_readpage, who searches the tree to find
** an indirect item.  This indirect item has X number of pointers, where
** X is a big number if we've done the block allocation right.  But,
** we only use one or two of these pointers during each call to readpage,
** needlessly researching again later on.
**
** The size of the cache could be dynamic based on the size of the file.
**
** I'd also like to see us cache the location the stat data item, since
** we are needlessly researching for that frequently.
**
** --chris
*/

/* If this page has a file tail in it, and
** it was read in by get_block_create_0, the page data is valid,
** but tail is still sitting in a direct item, and we can't write to
** it.  So, look through this page, and check all the mapped buffers
** to make sure they have valid block numbers.  Any that don't need
** to be unmapped, so that block_prepare_write will correctly call
** reiserfs_get_block to convert the tail into an unformatted node
*/
static inline void fix_tail_page_for_writing(struct page *page) {
    struct buffer_head *head, *next, *bh ;

    if (page && page_has_buffers(page)) {
	head = page_buffers(page) ;
	bh = head ;
	do {
	    next = bh->b_this_page ;
	    if (buffer_mapped(bh) && bh->b_blocknr == 0) {
	        reiserfs_unmap_buffer(bh) ;
	    }
	    bh = next ;
	} while (bh != head) ;
    }
}

/* reiserfs_get_block does not need to allocate a block only if it has been
   done already or non-hole position has been found in the indirect item */
static inline int allocation_needed (int retval, b_blocknr_t allocated, 
				     struct item_head * ih,
				     __le32 * item, int pos_in_item)
{
  if (allocated)
	 return 0;
  if (retval == POSITION_FOUND && is_indirect_le_ih (ih) && 
      get_block_num(item, pos_in_item))
	 return 0;
  return 1;
}

static inline int indirect_item_found (int retval, struct item_head * ih)
{
  return (retval == POSITION_FOUND) && is_indirect_le_ih (ih);
}


static inline void set_block_dev_mapped (struct buffer_head * bh, 
					 b_blocknr_t block, struct inode * inode)
{
	map_bh(bh, inode->i_sb, block);
}


//
// files which were created in the earlier version can not be longer,
// than 2 gb
//
static int file_capable (struct inode * inode, long block)
{
    if (get_inode_item_key_version (inode) != KEY_FORMAT_3_5 || // it is new file.
	block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb
	return 1;

    return 0;
}

/*static*/ int restart_transaction(struct reiserfs_transaction_handle *th,
				struct inode *inode, struct path *path) {
  struct super_block *s = th->t_super ;
  int len = th->t_blocks_allocated ;
  int err;

  BUG_ON (!th->t_trans_id);
  BUG_ON (!th->t_refcount);

  /* we cannot restart while nested */
  if (th->t_refcount > 1) {
      return 0  ;
  }
  pathrelse(path) ;
  reiserfs_update_sd(th, inode) ;
  err = journal_end(th, s, len) ;
  if (!err) {
      err = journal_begin(th, s, JOURNAL_PER_BALANCE_CNT * 6) ;
      if (!err)
        reiserfs_update_inode_transaction(inode) ;
  }
  return err;
}

// it is called by get_block when create == 0. Returns block number
// for 'block'-th logical block of file. When it hits direct item it
// returns 0 (being called from bmap) or read direct item into piece
// of page (bh_result)

// Please improve the english/clarity in the comment above, as it is
// hard to understand.

static int _get_block_create_0 (struct inode * inode, long block,
				 struct buffer_head * bh_result,
				 int args)
{
    INITIALIZE_PATH (path);
    struct cpu_key key;
    struct buffer_head * bh;
    struct item_head * ih, tmp_ih;
    int fs_gen ;
    int blocknr;
    char * p = NULL;
    int chars;
    int ret ;
    int result ;
    int done = 0 ;
    unsigned long offset ;

    // prepare the key to look for the 'block'-th block of file
    make_cpu_key (&key, inode,
		  (loff_t)block * inode->i_sb->s_blocksize + 1, TYPE_ANY, 3);

research:
    result = search_for_position_by_key (inode->i_sb, &key, &path) ;
    if (result != POSITION_FOUND) {
	pathrelse (&path);
        if (p)
            kunmap(bh_result->b_page) ;
	if (result == IO_ERROR)
	    return -EIO;
	// We do not return -ENOENT if there is a hole but page is uptodate, because it means
	// That there is some MMAPED data associated with it that is yet to be written to disk.
	if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) {
	    return -ENOENT ;
	}
        return 0 ;
    }
    
    //
    bh = get_last_bh (&path);
    ih = get_ih (&path);
    if (is_indirect_le_ih (ih)) {
	__le32 * ind_item = (__le32 *)B_I_PITEM (bh, ih);
	
	/* FIXME: here we could cache indirect item or part of it in
	   the inode to avoid search_by_key in case of subsequent
	   access to file */
	blocknr = get_block_num(ind_item, path.pos_in_item) ;
	ret = 0 ;
	if (blocknr) {
	    map_bh(bh_result, inode->i_sb, blocknr);
	    if (path.pos_in_item == ((ih_item_len(ih) / UNFM_P_SIZE) - 1)) {
		set_buffer_boundary(bh_result);
	    }
	} else 
	    // We do not return -ENOENT if there is a hole but page is uptodate, because it means
	    // That there is some MMAPED data associated with it that is yet to  be written to disk.
	    if ((args & GET_BLOCK_NO_HOLE) && !PageUptodate(bh_result->b_page) ) {
	    ret = -ENOENT ;
	    }

	pathrelse (&path);
        if (p)
            kunmap(bh_result->b_page) ;
	return ret ;
    }

    // requested data are in direct item(s)
    if (!(args & GET_BLOCK_READ_DIRECT)) {
	// we are called by bmap. FIXME: we can not map block of file
	// when it is stored in direct item(s)
	pathrelse (&path);	
        if (p)
            kunmap(bh_result->b_page) ;
	return -ENOENT;
    }

    /* if we've got a direct item, and the buffer or page was uptodate,
    ** we don't want to pull data off disk again.  skip to the
    ** end, where we map the buffer and return
    */
    if (buffer_uptodate(bh_result)) {
        goto finished ;
    } else 
	/*
	** grab_tail_page can trigger calls to reiserfs_get_block on up to date
	** pages without any buffers.  If the page is up to date, we don't want
	** read old data off disk.  Set the up to date bit on the buffer instead
	** and jump to the end
	*/
	    if (!bh_result->b_page || PageUptodate(bh_result->b_page)) {
		set_buffer_uptodate(bh_result);
		goto finished ;
    }

    // read file tail into part of page
    offset = (cpu_key_k_offset(&key) - 1) & (PAGE_CACHE_SIZE - 1) ;
    fs_gen = get_generation(inode->i_sb) ;
    copy_item_head (&tmp_ih, ih);

    /* we only want to kmap if we are reading the tail into the page.
    ** this is not the common case, so we don't kmap until we are
    ** sure we need to.  But, this means the item might move if
    ** kmap schedules
    */
    if (!p) {
	p = (char *)kmap(bh_result->b_page) ;
	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
	    goto research;
	}
    }
    p += offset ;
    memset (p, 0, inode->i_sb->s_blocksize);
    do {
	if (!is_direct_le_ih (ih)) {
	    BUG ();
        }
	/* make sure we don't read more bytes than actually exist in
	** the file.  This can happen in odd cases where i_size isn't
	** correct, and when direct item padding results in a few 
	** extra bytes at the end of the direct item
	*/
        if ((le_ih_k_offset(ih) + path.pos_in_item) > inode->i_size)
	    break ;
	if ((le_ih_k_offset(ih) - 1 + ih_item_len(ih)) > inode->i_size) {
	    chars = inode->i_size - (le_ih_k_offset(ih) - 1) - path.pos_in_item;
	    done = 1 ;
	} else {
	    chars = ih_item_len(ih) - path.pos_in_item;
	}
	memcpy (p, B_I_PITEM (bh, ih) + path.pos_in_item, chars);

	if (done) 
	    break ;

	p += chars;

	if (PATH_LAST_POSITION (&path) != (B_NR_ITEMS (bh) - 1))
	    // we done, if read direct item is not the last item of
	    // node FIXME: we could try to check right delimiting key
	    // to see whether direct item continues in the right
	    // neighbor or rely on i_size
	    break;

	// update key to look for the next piece
	set_cpu_key_k_offset (&key, cpu_key_k_offset (&key) + chars);
	result = search_for_position_by_key (inode->i_sb, &key, &path);
	if (result != POSITION_FOUND)
	    // i/o error most likely
	    break;
	bh = get_last_bh (&path);
	ih = get_ih (&path);
    } while (1);

    flush_dcache_page(bh_result->b_page) ;
    kunmap(bh_result->b_page) ;

finished:
    pathrelse (&path);

    if (result == IO_ERROR)
	return -EIO;

    /* this buffer has valid data, but isn't valid for io.  mapping it to
     * block #0 tells the rest of reiserfs it just has a tail in it
     */
    map_bh(bh_result, inode->i_sb, 0);
    set_buffer_uptodate (bh_result);
    return 0;
}


// this is called to create file map. So, _get_block_create_0 will not
// read direct item
static int reiserfs_bmap (struct inode * inode, sector_t block,
			  struct buffer_head * bh_result, int create)
{
    if (!file_capable (inode, block))
	return -EFBIG;

    reiserfs_write_lock(inode->i_sb);
    /* do not read the direct item */
    _get_block_create_0 (inode, block, bh_result, 0) ;
    reiserfs_write_unlock(inode->i_sb);
    return 0;
}

/* special version of get_block that is only used by grab_tail_page right
** now.  It is sent to block_prepare_write, and when you try to get a
** block past the end of the file (or a block from a hole) it returns
** -ENOENT instead of a valid buffer.  block_prepare_write expects to
** be able to do i/o on the buffers returned, unless an error value
** is also returned.
** 
** So, this allows block_prepare_write to be used for reading a single block
** in a page.  Where it does not produce a valid page for holes, or past the
** end of the file.  This turns out to be exactly what we need for reading
** tails for conversion.
**
** The point of the wrapper is forcing a certain value for create, even
** though the VFS layer is calling this function with create==1.  If you 
** don't want to send create == GET_BLOCK_NO_HOLE to reiserfs_get_block, 
** don't use this function.
*/
static int reiserfs_get_block_create_0 (struct inode * inode, sector_t block,
			struct buffer_head * bh_result, int create) {
    return reiserfs_get_block(inode, block, bh_result, GET_BLOCK_NO_HOLE) ;
}

/* This is special helper for reiserfs_get_block in case we are executing
   direct_IO request. */
static int reiserfs_get_blocks_direct_io(struct inode *inode,
					 sector_t iblock,
					 unsigned long max_blocks,
					 struct buffer_head *bh_result,
					 int create)
{
    int ret ;

    bh_result->b_page = NULL;

    /* We set the b_size before reiserfs_get_block call since it is
       referenced in convert_tail_for_hole() that may be called from
       reiserfs_get_block() */
    bh_result->b_size = (1 << inode->i_blkbits);

    ret = reiserfs_get_block(inode, iblock, bh_result,
                             create | GET_BLOCK_NO_DANGLE) ;
    if (ret)
        goto out;

    /* don't allow direct io onto tail pages */
    if (buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
        /* make sure future calls to the direct io funcs for this offset
        ** in the file fail by unmapping the buffer
        */
        clear_buffer_mapped(bh_result);
        ret = -EINVAL ;
    }
    /* Possible unpacked tail. Flush the data before pages have
       disappeared */
    if (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) {
        int err;
        lock_kernel();
        err = reiserfs_commit_for_inode(inode);
        REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
        unlock_kernel();
        if (err < 0)
            ret = err;
    }
out:
    return ret ;
}


/*
** helper function for when reiserfs_get_block is called for a hole
** but the file tail is still in a direct item
** bh_result is the buffer head for the hole
** tail_offset is the offset of the start of the tail in the file
**
** This calls prepare_write, which will start a new transaction
** you should not be in a transaction, or have any paths held when you
** call this.
*/
static int convert_tail_for_hole(struct inode *inode, 
                                 struct buffer_head *bh_result,
				 loff_t tail_offset) {
    unsigned long index ;
    unsigned long tail_end ; 
    unsigned long tail_start ;
    struct page * tail_page ;
    struct page * hole_page = bh_result->b_page ;
    int retval = 0 ;

    if ((tail_offset & (bh_result->b_size - 1)) != 1) 
        return -EIO ;

    /* always try to read until the end of the block */
    tail_start = tail_offset & (PAGE_CACHE_SIZE - 1) ;
    tail_end = (tail_start | (bh_result->b_size - 1)) + 1 ;

    index = tail_offset >> PAGE_CACHE_SHIFT ;
    /* hole_page can be zero in case of direct_io, we are sure
       that we cannot get here if we write with O_DIRECT into
       tail page */
    if (!hole_page || index != hole_page->index) {
	tail_page = grab_cache_page(inode->i_mapping, index) ;
	retval = -ENOMEM;
	if (!tail_page) {
	    goto out ;
	}
    } else {
        tail_page = hole_page ;
    }

    /* we don't have to make sure the conversion did not happen while
    ** we were locking the page because anyone that could convert
    ** must first take i_sem.
    **
    ** We must fix the tail page for writing because it might have buffers
    ** that are mapped, but have a block number of 0.  This indicates tail
    ** data that has been read directly into the page, and block_prepare_write
    ** won't trigger a get_block in this case.
    */
    fix_tail_page_for_writing(tail_page) ;
    retval = reiserfs_prepare_write(NULL, tail_page, tail_start, tail_end);
    if (retval)
        goto unlock ;

    /* tail conversion might change the data in the page */
    flush_dcache_page(tail_page) ;

    retval = reiserfs_commit_write(NULL, tail_page, tail_start, tail_end) ;

unlock:
    if (tail_page != hole_page) {
        unlock_page(tail_page) ;
	page_cache_release(tail_page) ;
    }
out:
    return retval ;
}

static inline int _allocate_block(struct reiserfs_transaction_handle *th,
			   long block,
                           struct inode *inode, 
			   b_blocknr_t *allocated_block_nr, 
			   struct path * path,
			   int flags) {
    BUG_ON (!th->t_trans_id);
  
#ifdef REISERFS_PREALLOCATE
    if (!(flags & GET_BLOCK_NO_ISEM)) {
	return reiserfs_new_unf_blocknrs2(th, inode, allocated_block_nr, path, block);
    }
#endif
    return reiserfs_new_unf_blocknrs (th, inode, allocated_block_nr, path, block);
}

int reiserfs_get_block (struct inode * inode, sector_t block,
			struct buffer_head * bh_result, int create)
{
    int repeat, retval = 0;
    b_blocknr_t allocated_block_nr = 0;// b_blocknr_t is (unsigned) 32 bit int
    INITIALIZE_PATH(path);
    int pos_in_item;
    struct cpu_key key;
    struct buffer_head * bh, * unbh = NULL;
    struct item_head * ih, tmp_ih;
    __le32 * item;
    int done;
    int fs_gen;
    struct reiserfs_transaction_handle *th = NULL;
    /* space reserved in transaction batch: 
        . 3 balancings in direct->indirect conversion
        . 1 block involved into reiserfs_update_sd()
       XXX in practically impossible worst case direct2indirect()
       can incur (much) more than 3 balancings.
       quota update for user, group */
    int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb);
    int version;
    int dangle = 1;
    loff_t new_offset = (((loff_t)block) << inode->i_sb->s_blocksize_bits) + 1 ;

				/* bad.... */
    reiserfs_write_lock(inode->i_sb);
    version = get_inode_item_key_version (inode);

    if (block < 0) {
	reiserfs_write_unlock(inode->i_sb);
	return -EIO;
    }

    if (!file_capable (inode, block)) {
	reiserfs_write_unlock(inode->i_sb);
	return -EFBIG;
    }

    /* if !create, we aren't changing the FS, so we don't need to
    ** log anything, so we don't need to start a transaction
    */
    if (!(create & GET_BLOCK_CREATE)) {
	int ret ;
	/* find number of block-th logical block of the file */
	ret = _get_block_create_0 (inode, block, bh_result, 
	                           create | GET_BLOCK_READ_DIRECT) ;
	reiserfs_write_unlock(inode->i_sb);
	return ret;
    }
    /*
     * if we're already in a transaction, make sure to close
     * any new transactions we start in this func
     */
    if ((create & GET_BLOCK_NO_DANGLE) ||
        reiserfs_transaction_running(inode->i_sb))
        dangle = 0;

    /* If file is of such a size, that it might have a tail and tails are enabled
    ** we should mark it as possibly needing tail packing on close
    */
    if ( (have_large_tails (inode->i_sb) && inode->i_size < i_block_size (inode)*4) ||
	 (have_small_tails (inode->i_sb) && inode->i_size < i_block_size(inode)) )
	REISERFS_I(inode)->i_flags |= i_pack_on_close_mask ;

    /* set the key of the first byte in the 'block'-th block of file */
    make_cpu_key (&key, inode, new_offset,
		  TYPE_ANY, 3/*key length*/);
    if ((new_offset + inode->i_sb->s_blocksize - 1) > inode->i_size) {
start_trans:
	th = reiserfs_persistent_transaction(inode->i_sb, jbegin_count);
	if (!th) {
	    retval = -ENOMEM;
	    goto failure;
	}
	reiserfs_update_inode_transaction(inode) ;
    }
 research:

    retval = search_for_position_by_key (inode->i_sb, &key, &path);
    if (retval == IO_ERROR) {
	retval = -EIO;
	goto failure;
    }
	
    bh = get_last_bh (&path);
    ih = get_ih (&path);
    item = get_item (&path);
    pos_in_item = path.pos_in_item;

    fs_gen = get_generation (inode->i_sb);
    copy_item_head (&tmp_ih, ih);

    if (allocation_needed (retval, allocated_block_nr, ih, item, pos_in_item)) {
	/* we have to allocate block for the unformatted node */
	if (!th) {
	    pathrelse(&path) ;
	    goto start_trans;
	}

	repeat = _allocate_block(th, block, inode, &allocated_block_nr, &path, create);

	if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) {
	    /* restart the transaction to give the journal a chance to free
	    ** some blocks.  releases the path, so we have to go back to
	    ** research if we succeed on the second try
	    */
	    SB_JOURNAL(inode->i_sb)->j_next_async_flush = 1;
	    retval = restart_transaction(th, inode, &path) ;
            if (retval)
                goto failure;
	    repeat = _allocate_block(th, block, inode, &allocated_block_nr, NULL, create);

	    if (repeat != NO_DISK_SPACE && repeat != QUOTA_EXCEEDED) {
		goto research ;
	    }
	    if (repeat == QUOTA_EXCEEDED)
		retval = -EDQUOT;
	    else
		retval = -ENOSPC;
	    goto failure;
	}

	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
	    goto research;
	}
    }

    if (indirect_item_found (retval, ih)) {
        b_blocknr_t unfm_ptr;
	/* 'block'-th block is in the file already (there is
	   corresponding cell in some indirect item). But it may be
	   zero unformatted node pointer (hole) */
        unfm_ptr = get_block_num (item, pos_in_item);
	if (unfm_ptr == 0) {
	    /* use allocated block to plug the hole */
	    reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;
	    if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
		reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
		goto research;
	    }
	    set_buffer_new(bh_result);
	    if (buffer_dirty(bh_result) && reiserfs_data_ordered(inode->i_sb))
	    	reiserfs_add_ordered_list(inode, bh_result);
	    put_block_num(item, pos_in_item, allocated_block_nr) ;
            unfm_ptr = allocated_block_nr;
	    journal_mark_dirty (th, inode->i_sb, bh);
	    reiserfs_update_sd(th, inode) ;
	}
	set_block_dev_mapped(bh_result, unfm_ptr, inode);
	pathrelse (&path);
        retval = 0;
	if (!dangle && th)
	    retval = reiserfs_end_persistent_transaction(th);

	reiserfs_write_unlock(inode->i_sb);
	 
	/* the item was found, so new blocks were not added to the file
	** there is no need to make sure the inode is updated with this 
	** transaction
	*/
	return retval;
    }

    if (!th) {
	pathrelse(&path) ;
	goto start_trans;
    }

    /* desired position is not found or is in the direct item. We have
       to append file with holes up to 'block'-th block converting
       direct items to indirect one if necessary */
    done = 0;
    do {
	if (is_statdata_le_ih (ih)) {
	    __le32 unp = 0;
	    struct cpu_key tmp_key;

	    /* indirect item has to be inserted */
	    make_le_item_head (&tmp_ih, &key, version, 1, TYPE_INDIRECT, 
			       UNFM_P_SIZE, 0/* free_space */);

	    if (cpu_key_k_offset (&key) == 1) {
		/* we are going to add 'block'-th block to the file. Use
		   allocated block for that */
		unp = cpu_to_le32 (allocated_block_nr);
		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
		set_buffer_new(bh_result);
		done = 1;
	    }
	    tmp_key = key; // ;)
	    set_cpu_key_k_offset (&tmp_key, 1);
	    PATH_LAST_POSITION(&path) ++;

	    retval = reiserfs_insert_item (th, &path, &tmp_key, &tmp_ih, inode, (char *)&unp);
	    if (retval) {
		reiserfs_free_block (th, inode, allocated_block_nr, 1);
		goto failure; // retval == -ENOSPC, -EDQUOT or -EIO or -EEXIST
	    }
	    //mark_tail_converted (inode);
	} else if (is_direct_le_ih (ih)) {
	    /* direct item has to be converted */
	    loff_t tail_offset;

	    tail_offset = ((le_ih_k_offset (ih) - 1) & ~(inode->i_sb->s_blocksize - 1)) + 1;
	    if (tail_offset == cpu_key_k_offset (&key)) {
		/* direct item we just found fits into block we have
                   to map. Convert it into unformatted node: use
                   bh_result for the conversion */
		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
		unbh = bh_result;
		done = 1;
	    } else {
		/* we have to padd file tail stored in direct item(s)
		   up to block size and convert it to unformatted
		   node. FIXME: this should also get into page cache */

		pathrelse(&path) ;
		/*
		 * ugly, but we can only end the transaction if
		 * we aren't nested
		 */
		BUG_ON (!th->t_refcount);
		if (th->t_refcount == 1) {
		    retval = reiserfs_end_persistent_transaction(th);
		    th = NULL;
		    if (retval)
			goto failure;
		}

		retval = convert_tail_for_hole(inode, bh_result, tail_offset) ;
		if (retval) {
		    if ( retval != -ENOSPC )
			reiserfs_warning (inode->i_sb, "clm-6004: convert tail failed inode %lu, error %d", inode->i_ino, retval) ;
		    if (allocated_block_nr) {
			/* the bitmap, the super, and the stat data == 3 */
			if (!th)
			    th = reiserfs_persistent_transaction(inode->i_sb,3);
			if (th)
			    reiserfs_free_block (th,inode,allocated_block_nr,1);
		    }
		    goto failure ;
		}
		goto research ;
	    }
	    retval = direct2indirect (th, inode, &path, unbh, tail_offset);
	    if (retval) {
		reiserfs_unmap_buffer(unbh);
		reiserfs_free_block (th, inode, allocated_block_nr, 1);
		goto failure;
	    }
	    /* it is important the set_buffer_uptodate is done after
	    ** the direct2indirect.  The buffer might contain valid
	    ** data newer than the data on disk (read by readpage, changed,
	    ** and then sent here by writepage).  direct2indirect needs
	    ** to know if unbh was already up to date, so it can decide
	    ** if the data in unbh needs to be replaced with data from
	    ** the disk
	    */
	    set_buffer_uptodate (unbh);

	    /* unbh->b_page == NULL in case of DIRECT_IO request, this means
	       buffer will disappear shortly, so it should not be added to
	     */
	    if ( unbh->b_page ) {
		/* we've converted the tail, so we must
		** flush unbh before the transaction commits
		*/
		reiserfs_add_tail_list(inode, unbh) ;

		/* mark it dirty now to prevent commit_write from adding
		** this buffer to the inode's dirty buffer list
		*/
		/*
		 * AKPM: changed __mark_buffer_dirty to mark_buffer_dirty().
		 * It's still atomic, but it sets the page dirty too,
		 * which makes it eligible for writeback at any time by the
		 * VM (which was also the case with __mark_buffer_dirty())
		 */
		mark_buffer_dirty(unbh) ;
	    }
	} else {
	    /* append indirect item with holes if needed, when appending
	       pointer to 'block'-th block use block, which is already
	       allocated */
	    struct cpu_key tmp_key;
	    unp_t unf_single=0; // We use this in case we need to allocate only
				// one block which is a fastpath
	    unp_t *un;
	    __u64 max_to_insert=MAX_ITEM_LEN(inode->i_sb->s_blocksize)/UNFM_P_SIZE;
	    __u64 blocks_needed;

	    RFALSE( pos_in_item != ih_item_len(ih) / UNFM_P_SIZE,
		    "vs-804: invalid position for append");
	    /* indirect item has to be appended, set up key of that position */
	    make_cpu_key (&tmp_key, inode,
			  le_key_k_offset (version, &(ih->ih_key)) + op_bytes_number (ih, inode->i_sb->s_blocksize),
			  //pos_in_item * inode->i_sb->s_blocksize,
			  TYPE_INDIRECT, 3);// key type is unimportant

	    blocks_needed = 1 + ((cpu_key_k_offset (&key) - cpu_key_k_offset (&tmp_key)) >> inode->i_sb->s_blocksize_bits);
	    RFALSE( blocks_needed < 0, "green-805: invalid offset");

	    if ( blocks_needed == 1 ) {
		un = &unf_single;
	    } else {
		un=kmalloc( min(blocks_needed,max_to_insert)*UNFM_P_SIZE,
			    GFP_ATOMIC); // We need to avoid scheduling.
		if ( !un) {
		    un = &unf_single;
		    blocks_needed = 1;
		    max_to_insert = 0;
		} else
		    memset(un, 0, UNFM_P_SIZE * min(blocks_needed,max_to_insert));
	    }
	    if ( blocks_needed <= max_to_insert) {
		/* we are going to add target block to the file. Use allocated
		   block for that */
		un[blocks_needed-1] = cpu_to_le32 (allocated_block_nr);
		set_block_dev_mapped (bh_result, allocated_block_nr, inode);
		set_buffer_new(bh_result);
		done = 1;
	    } else {
		/* paste hole to the indirect item */
		/* If kmalloc failed, max_to_insert becomes zero and it means we
		   only have space for one block */
		blocks_needed=max_to_insert?max_to_insert:1;
	    }
	    retval = reiserfs_paste_into_item (th, &path, &tmp_key, inode, (char *)un, UNFM_P_SIZE * blocks_needed);

	    if (blocks_needed != 1)
		kfree(un);

	    if (retval) {
		reiserfs_free_block (th, inode, allocated_block_nr, 1);
		goto failure;
	    }
	    if (!done) {
		/* We need to mark new file size in case this function will be
		   interrupted/aborted later on. And we may do this only for
		   holes. */
		inode->i_size += inode->i_sb->s_blocksize * blocks_needed;
	    }
	}

	if (done == 1)
	    break;

	/* this loop could log more blocks than we had originally asked
	** for.  So, we have to allow the transaction to end if it is
	** too big or too full.  Update the inode so things are 
	** consistent if we crash before the function returns
	**
	** release the path so that anybody waiting on the path before
	** ending their transaction will be able to continue.
	*/
	if (journal_transaction_should_end(th, th->t_blocks_allocated)) {
	  retval = restart_transaction(th, inode, &path) ;
	  if (retval)
	    goto failure;
	}
	/* inserting indirect pointers for a hole can take a 
	** long time.  reschedule if needed
	*/
	cond_resched();

	retval = search_for_position_by_key (inode->i_sb, &key, &path);
	if (retval == IO_ERROR) {
	    retval = -EIO;
	    goto failure;
	}
	if (retval == POSITION_FOUND) {
	    reiserfs_warning (inode->i_sb, "vs-825: reiserfs_get_block: "
			      "%K should not be found", &key);
	    retval = -EEXIST;
	    if (allocated_block_nr)
	        reiserfs_free_block (th, inode, allocated_block_nr, 1);
	    pathrelse(&path) ;
	    goto failure;
	}
	bh = get_last_bh (&path);
	ih = get_ih (&path);
	item = get_item (&path);
	pos_in_item = path.pos_in_item;
    } while (1);


    retval = 0;

 failure:
    if (th && (!dangle || (retval && !th->t_trans_id))) {
        int err;
        if (th->t_trans_id)
            reiserfs_update_sd(th, inode);
        err = reiserfs_end_persistent_transaction(th);
        if (err)
            retval = err;
    }

    reiserfs_write_unlock(inode->i_sb);
    reiserfs_check_path(&path) ;
    return retval;
}

static int
reiserfs_readpages(struct file *file, struct address_space *mapping,
		struct list_head *pages, unsigned nr_pages)
{
    return mpage_readpages(mapping, pages, nr_pages, reiserfs_get_block);
}

/* Compute real number of used bytes by file
 * Following three functions can go away when we'll have enough space in stat item
 */
static int real_space_diff(struct inode *inode, int sd_size)
{
    int bytes;
    loff_t blocksize = inode->i_sb->s_blocksize ;

    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode))
        return sd_size ;

    /* End of file is also in full block with indirect reference, so round
    ** up to the next block.
    **
    ** there is just no way to know if the tail is actually packed
    ** on the file, so we have to assume it isn't.  When we pack the
    ** tail, we add 4 bytes to pretend there really is an unformatted
    ** node pointer
    */
    bytes = ((inode->i_size + (blocksize-1)) >> inode->i_sb->s_blocksize_bits) * UNFM_P_SIZE + sd_size;
    return bytes ;
}

static inline loff_t to_real_used_space(struct inode *inode, ulong blocks,
                                        int sd_size)
{
    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
        return inode->i_size + (loff_t)(real_space_diff(inode, sd_size)) ;
    }
    return ((loff_t)real_space_diff(inode, sd_size)) + (((loff_t)blocks) << 9);
}

/* Compute number of blocks used by file in ReiserFS counting */
static inline ulong to_fake_used_blocks(struct inode *inode, int sd_size)
{
    loff_t bytes = inode_get_bytes(inode) ;
    loff_t real_space = real_space_diff(inode, sd_size) ;

    /* keeps fsck and non-quota versions of reiserfs happy */
    if (S_ISLNK(inode->i_mode) || S_ISDIR(inode->i_mode)) {
        bytes += (loff_t)511 ;
    }

    /* files from before the quota patch might i_blocks such that
    ** bytes < real_space.  Deal with that here to prevent it from
    ** going negative.
    */
    if (bytes < real_space)
        return 0 ;
    return (bytes - real_space) >> 9;
}

//
// BAD: new directories have stat data of new type and all other items
// of old type. Version stored in the inode says about body items, so
// in update_stat_data we can not rely on inode, but have to check
// item version directly
//

// called by read_locked_inode
static void init_inode (struct inode * inode, struct path * path)
{
    struct buffer_head * bh;
    struct item_head * ih;
    __u32 rdev;
    //int version = ITEM_VERSION_1;

    bh = PATH_PLAST_BUFFER (path);
    ih = PATH_PITEM_HEAD (path);


    copy_key (INODE_PKEY (inode), &(ih->ih_key));
    inode->i_blksize = reiserfs_default_io_size;

    INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list ));
    REISERFS_I(inode)->i_flags = 0;
    REISERFS_I(inode)->i_prealloc_block = 0;
    REISERFS_I(inode)->i_prealloc_count = 0;
    REISERFS_I(inode)->i_trans_id = 0;
    REISERFS_I(inode)->i_jl = NULL;
    REISERFS_I(inode)->i_acl_access = NULL;
    REISERFS_I(inode)->i_acl_default = NULL;
    init_rwsem (&REISERFS_I(inode)->xattr_sem);

    if (stat_data_v1 (ih)) {
	struct stat_data_v1 * sd = (struct stat_data_v1 *)B_I_PITEM (bh, ih);
	unsigned long blocks;

	set_inode_item_key_version (inode, KEY_FORMAT_3_5);
        set_inode_sd_version (inode, STAT_DATA_V1);
	inode->i_mode  = sd_v1_mode(sd);
	inode->i_nlink = sd_v1_nlink(sd);
	inode->i_uid   = sd_v1_uid(sd);
	inode->i_gid   = sd_v1_gid(sd);
	inode->i_size  = sd_v1_size(sd);
	inode->i_atime.tv_sec = sd_v1_atime(sd);
	inode->i_mtime.tv_sec = sd_v1_mtime(sd);
	inode->i_ctime.tv_sec = sd_v1_ctime(sd);
	inode->i_atime.tv_nsec = 0;
	inode->i_ctime.tv_nsec = 0;
	inode->i_mtime.tv_nsec = 0;

	inode->i_blocks = sd_v1_blocks(sd);
	inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
	blocks = (inode->i_size + 511) >> 9;
	blocks = _ROUND_UP (blocks, inode->i_sb->s_blocksize >> 9);
	if (inode->i_blocks > blocks) {
	    // there was a bug in <=3.5.23 when i_blocks could take negative
	    // values. Starting from 3.5.17 this value could even be stored in
	    // stat data. For such files we set i_blocks based on file
	    // size. Just 2 notes: this can be wrong for sparce files. On-disk value will be
	    // only updated if file's inode will ever change
	    inode->i_blocks = blocks;
	}

        rdev = sd_v1_rdev(sd);
	REISERFS_I(inode)->i_first_direct_byte = sd_v1_first_direct_byte(sd);
	/* an early bug in the quota code can give us an odd number for the
	** block count.  This is incorrect, fix it here.
	*/
	if (inode->i_blocks & 1) {
	    inode->i_blocks++ ;
	}
	inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks,
	                                          SD_V1_SIZE));
	/* nopack is initially zero for v1 objects. For v2 objects,
	   nopack is initialised from sd_attrs */
	REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
    } else {
	// new stat data found, but object may have old items
	// (directories and symlinks)
	struct stat_data * sd = (struct stat_data *)B_I_PITEM (bh, ih);

	inode->i_mode   = sd_v2_mode(sd);
	inode->i_nlink  = sd_v2_nlink(sd);
	inode->i_uid    = sd_v2_uid(sd);
	inode->i_size   = sd_v2_size(sd);
	inode->i_gid    = sd_v2_gid(sd);
	inode->i_mtime.tv_sec  = sd_v2_mtime(sd);
	inode->i_atime.tv_sec = sd_v2_atime(sd);
	inode->i_ctime.tv_sec  = sd_v2_ctime(sd);
	inode->i_ctime.tv_nsec = 0;
	inode->i_mtime.tv_nsec = 0;
	inode->i_atime.tv_nsec = 0;
	inode->i_blocks = sd_v2_blocks(sd);
        rdev            = sd_v2_rdev(sd);
	if( S_ISCHR( inode -> i_mode ) || S_ISBLK( inode -> i_mode ) )
	    inode->i_generation = le32_to_cpu (INODE_PKEY (inode)->k_dir_id);
	else
            inode->i_generation = sd_v2_generation(sd);

	if (S_ISDIR (inode->i_mode) || S_ISLNK (inode->i_mode))
	    set_inode_item_key_version (inode, KEY_FORMAT_3_5);
	else
	    set_inode_item_key_version (inode, KEY_FORMAT_3_6);
	REISERFS_I(inode)->i_first_direct_byte = 0;
	set_inode_sd_version (inode, STAT_DATA_V2);
	inode_set_bytes(inode, to_real_used_space(inode, inode->i_blocks,
	                                          SD_V2_SIZE));
	/* read persistent inode attributes from sd and initalise
	   generic inode flags from them */
	REISERFS_I(inode)->i_attrs = sd_v2_attrs( sd );
	sd_attrs_to_i_attrs( sd_v2_attrs( sd ), inode );
    }

    pathrelse (path);
    if (S_ISREG (inode->i_mode)) {
	inode->i_op = &reiserfs_file_inode_operations;
	inode->i_fop = &reiserfs_file_operations;
	inode->i_mapping->a_ops = &reiserfs_address_space_operations ;
    } else if (S_ISDIR (inode->i_mode)) {
	inode->i_op = &reiserfs_dir_inode_operations;
	inode->i_fop = &reiserfs_dir_operations;
    } else if (S_ISLNK (inode->i_mode)) {
	inode->i_op = &reiserfs_symlink_inode_operations;
	inode->i_mapping->a_ops = &reiserfs_address_space_operations;
    } else {
	inode->i_blocks = 0;
	inode->i_op = &reiserfs_special_inode_operations;
	init_special_inode(inode, inode->i_mode, new_decode_dev(rdev));
    }
}


// update new stat data with inode fields
static void inode2sd (void * sd, struct inode * inode, loff_t size)
{
    struct stat_data * sd_v2 = (struct stat_data *)sd;
    __u16 flags;

    set_sd_v2_mode(sd_v2, inode->i_mode );
    set_sd_v2_nlink(sd_v2, inode->i_nlink );
    set_sd_v2_uid(sd_v2, inode->i_uid );
    set_sd_v2_size(sd_v2, size );
    set_sd_v2_gid(sd_v2, inode->i_gid );
    set_sd_v2_mtime(sd_v2, inode->i_mtime.tv_sec );
    set_sd_v2_atime(sd_v2, inode->i_atime.tv_sec );
    set_sd_v2_ctime(sd_v2, inode->i_ctime.tv_sec );
    set_sd_v2_blocks(sd_v2, to_fake_used_blocks(inode, SD_V2_SIZE));
    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
	set_sd_v2_rdev(sd_v2, new_encode_dev(inode->i_rdev));
    else
	set_sd_v2_generation(sd_v2, inode->i_generation);
    flags = REISERFS_I(inode)->i_attrs;
    i_attrs_to_sd_attrs( inode, &flags );
    set_sd_v2_attrs( sd_v2, flags );
}


// used to copy inode's fields to old stat data
static void inode2sd_v1 (void * sd, struct inode * inode, loff_t size)
{
    struct stat_data_v1 * sd_v1 = (struct stat_data_v1 *)sd;

    set_sd_v1_mode(sd_v1, inode->i_mode );
    set_sd_v1_uid(sd_v1, inode->i_uid );
    set_sd_v1_gid(sd_v1, inode->i_gid );
    set_sd_v1_nlink(sd_v1, inode->i_nlink );
    set_sd_v1_size(sd_v1, size );
    set_sd_v1_atime(sd_v1, inode->i_atime.tv_sec );
    set_sd_v1_ctime(sd_v1, inode->i_ctime.tv_sec );
    set_sd_v1_mtime(sd_v1, inode->i_mtime.tv_sec );

    if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
        set_sd_v1_rdev(sd_v1, new_encode_dev(inode->i_rdev));
    else
        set_sd_v1_blocks(sd_v1, to_fake_used_blocks(inode, SD_V1_SIZE));

    // Sigh. i_first_direct_byte is back
    set_sd_v1_first_direct_byte(sd_v1, REISERFS_I(inode)->i_first_direct_byte);
}


/* NOTE, you must prepare the buffer head before sending it here,
** and then log it after the call
*/
static void update_stat_data (struct path * path, struct inode * inode,
                              loff_t size)
{
    struct buffer_head * bh;
    struct item_head * ih;
  
    bh = PATH_PLAST_BUFFER (path);
    ih = PATH_PITEM_HEAD (path);

    if (!is_statdata_le_ih (ih))
	reiserfs_panic (inode->i_sb, "vs-13065: update_stat_data: key %k, found item %h",
			INODE_PKEY (inode), ih);
  
    if (stat_data_v1 (ih)) {
	// path points to old stat data
	inode2sd_v1 (B_I_PITEM (bh, ih), inode, size);
    } else {
	inode2sd (B_I_PITEM (bh, ih), inode, size);
    }

    return;
}


void reiserfs_update_sd_size (struct reiserfs_transaction_handle *th,
			      struct inode * inode, loff_t size)
{
    struct cpu_key key;
    INITIALIZE_PATH(path);
    struct buffer_head *bh ;
    int fs_gen ;
    struct item_head *ih, tmp_ih ;
    int retval;

    BUG_ON (!th->t_trans_id);

    make_cpu_key (&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3);//key type is unimportant
    
    for(;;) {
	int pos;
	/* look for the object's stat data */
	retval = search_item (inode->i_sb, &key, &path);
	if (retval == IO_ERROR) {
	    reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: "
			      "i/o failure occurred trying to update %K stat data",
			      &key);
	    return;
	}
	if (retval == ITEM_NOT_FOUND) {
	    pos = PATH_LAST_POSITION (&path);
	    pathrelse(&path) ;
	    if (inode->i_nlink == 0) {
		/*reiserfs_warning (inode->i_sb, "vs-13050: reiserfs_update_sd: i_nlink == 0, stat data not found");*/
		return;
	    }
	    reiserfs_warning (inode->i_sb, "vs-13060: reiserfs_update_sd: "
			      "stat data of object %k (nlink == %d) not found (pos %d)",
			      INODE_PKEY (inode), inode->i_nlink, pos);
	    reiserfs_check_path(&path) ;
	    return;
	}
	
	/* sigh, prepare_for_journal might schedule.  When it schedules the
	** FS might change.  We have to detect that, and loop back to the
	** search if the stat data item has moved
	*/
	bh = get_last_bh(&path) ;
	ih = get_ih(&path) ;
	copy_item_head (&tmp_ih, ih);
	fs_gen = get_generation (inode->i_sb);
	reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;
	if (fs_changed (fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) {
	    reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
	    continue ;	/* Stat_data item has been moved after scheduling. */
	}
	break;
    }
    update_stat_data (&path, inode, size);
    journal_mark_dirty(th, th->t_super, bh) ; 
    pathrelse (&path);
    return;
}

/* reiserfs_read_locked_inode is called to read the inode off disk, and it
** does a make_bad_inode when things go wrong.  But, we need to make sure
** and clear the key in the private portion of the inode, otherwise a
** corresponding iput might try to delete whatever object the inode last
** represented.
*/
static void reiserfs_make_bad_inode(struct inode *inode) {
    memset(INODE_PKEY(inode), 0, KEY_SIZE);
    make_bad_inode(inode);
}

//
// initially this function was derived from minix or ext2's analog and
// evolved as the prototype did
//

int reiserfs_init_locked_inode (struct inode * inode, void *p)
{
    struct reiserfs_iget_args *args = (struct reiserfs_iget_args *)p ;
    inode->i_ino = args->objectid;
    INODE_PKEY(inode)->k_dir_id = cpu_to_le32(args->dirid);
    return 0;
}

/* looks for stat data in the tree, and fills up the fields of in-core
   inode stat data fields */
void reiserfs_read_locked_inode (struct inode * inode, struct reiserfs_iget_args *args)
{
    INITIALIZE_PATH (path_to_sd);
    struct cpu_key key;
    unsigned long dirino;
    int retval;

    dirino = args->dirid ;

    /* set version 1, version 2 could be used too, because stat data
       key is the same in both versions */
    key.version = KEY_FORMAT_3_5;
    key.on_disk_key.k_dir_id = dirino;
    key.on_disk_key.k_objectid = inode->i_ino;
    key.on_disk_key.k_offset = 0;
    key.on_disk_key.k_type = 0;

    /* look for the object's stat data */
    retval = search_item (inode->i_sb, &key, &path_to_sd);
    if (retval == IO_ERROR) {
	reiserfs_warning (inode->i_sb, "vs-13070: reiserfs_read_locked_inode: "
			  "i/o failure occurred trying to find stat data of %K",
			  &key);
	reiserfs_make_bad_inode(inode) ;
	return;
    }
    if (retval != ITEM_FOUND) {
	/* a stale NFS handle can trigger this without it being an error */
	pathrelse (&path_to_sd);
	reiserfs_make_bad_inode(inode) ;
	inode->i_nlink = 0;
	return;
    }

    init_inode (inode, &path_to_sd);
   
    /* It is possible that knfsd is trying to access inode of a file
       that is being removed from the disk by some other thread. As we
       update sd on unlink all that is required is to check for nlink
       here. This bug was first found by Sizif when debugging
       SquidNG/Butterfly, forgotten, and found again after Philippe
       Gramoulle <philippe.gramoulle@mmania.com> reproduced it. 

       More logical fix would require changes in fs/inode.c:iput() to
       remove inode from hash-table _after_ fs cleaned disk stuff up and
       in iget() to return NULL if I_FREEING inode is found in
       hash-table. */
    /* Currently there is one place where it's ok to meet inode with
       nlink==0: processing of open-unlinked and half-truncated files
       during mount (fs/reiserfs/super.c:finish_unfinished()). */
    if( ( inode -> i_nlink == 0 ) && 
	! REISERFS_SB(inode -> i_sb) -> s_is_unlinked_ok ) {
	    reiserfs_warning (inode->i_sb,
			      "vs-13075: reiserfs_read_locked_inode: "
			      "dead inode read from disk %K. "
			      "This is likely to be race with knfsd. Ignore",
			      &key );
	    reiserfs_make_bad_inode( inode );
    }

    reiserfs_check_path(&path_to_sd) ; /* init inode should be relsing */

}

/**
 * reiserfs_find_actor() - "find actor" reiserfs supplies to iget5_locked().
 *
 * @inode:    inode from hash table to check
 * @opaque:   "cookie" passed to iget5_locked(). This is &reiserfs_iget_args.
 *
 * This function is called by iget5_locked() to distinguish reiserfs inodes
 * having the same inode numbers. Such inodes can only exist due to some
 * error condition. One of them should be bad. Inodes with identical
 * inode numbers (objectids) are distinguished by parent directory ids.
 *
 */
int reiserfs_find_actor( struct inode *inode, void *opaque )
{
    struct reiserfs_iget_args *args;

    args = opaque;
    /* args is already in CPU order */
    return (inode->i_ino == args->objectid) &&
	(le32_to_cpu(INODE_PKEY(inode)->k_dir_id) == args->dirid);
}

struct inode * reiserfs_iget (struct super_block * s, const struct cpu_key * key)
{
    struct inode * inode;
    struct reiserfs_iget_args args ;

    args.objectid = key->on_disk_key.k_objectid ;
    args.dirid = key->on_disk_key.k_dir_id ;
    inode = iget5_locked (s, key->on_disk_key.k_objectid, 
		   reiserfs_find_actor, reiserfs_init_locked_inode, (void *)(&args));
    if (!inode) 
	return ERR_PTR(-ENOMEM) ;

    if (inode->i_state & I_NEW) {
	reiserfs_read_locked_inode(inode, &args);
	unlock_new_inode(inode);
    }

    if (comp_short_keys (INODE_PKEY (inode), key) || is_bad_inode (inode)) {
	/* either due to i/o error or a stale NFS handle */
	iput (inode);
	inode = NULL;
    }
    return inode;
}

struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
{
    __u32 *data = vobjp;
    struct cpu_key key ;
    struct dentry *result;
    struct inode *inode;
    
    key.on_disk_key.k_objectid = data[0] ;
    key.on_disk_key.k_dir_id = data[1] ;
    reiserfs_write_lock(sb);
    inode = reiserfs_iget(sb, &key) ;
    if (inode && !IS_ERR(inode) && data[2] != 0 &&
	data[2] != inode->i_generation) {
	    iput(inode) ;
	    inode = NULL ;
    }
    reiserfs_write_unlock(sb);
    if (!inode)
	    inode = ERR_PTR(-ESTALE);
    if (IS_ERR(inode))
	    return ERR_PTR(PTR_ERR(inode));
    result = d_alloc_anon(inode);
    if (!result) {
	    iput(inode);
	    return ERR_PTR(-ENOMEM);
    }
    return result;
}

struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 *data,
                                     int len, int fhtype,
				  int (*acceptable)(void *contect, struct dentry *de),
				  void *context) {
    __u32 obj[3], parent[3];

    /* fhtype happens to reflect the number of u32s encoded.
     * due to a bug in earlier code, fhtype might indicate there
     * are more u32s then actually fitted.
     * so if fhtype seems to be more than len, reduce fhtype.
     * Valid types are:
     *   2 - objectid + dir_id - legacy support
     *   3 - objectid + dir_id + generation
     *   4 - objectid + dir_id + objectid and dirid of parent - legacy
     *   5 - objectid + dir_id + generation + objectid and dirid of parent
     *   6 - as above plus generation of directory
     * 6 does not fit in NFSv2 handles
     */
    if (fhtype > len) {
	    if (fhtype != 6 || len != 5)
		    reiserfs_warning (sb, "nfsd/reiserfs, fhtype=%d, len=%d - odd",
			   fhtype, len);
	    fhtype = 5;
    }

    obj[0] = data[0];
    obj[1] = data[1];
    if (fhtype == 3 || fhtype >= 5)
	    obj[2] = data[2];
    else    obj[2] = 0; /* generation number */

    if (fhtype >= 4) {
	    parent[0] = data[fhtype>=5?3:2] ;
	    parent[1] = data[fhtype>=5?4:3] ;
	    if (fhtype == 6)
		    parent[2] = data[5];
	    else    parent[2] = 0;
    }
    return sb->s_export_op->find_exported_dentry(sb, obj, fhtype < 4 ? NULL : parent,
			       acceptable, context);
}

int reiserfs_encode_fh(struct dentry *dentry, __u32 *data, int *lenp, int need_parent) {
    struct inode *inode = dentry->d_inode ;
    int maxlen = *lenp;
    
    if (maxlen < 3)
        return 255 ;

    data[0] = inode->i_ino ;
    data[1] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
    data[2] = inode->i_generation ;
    *lenp = 3 ;
    /* no room for directory info? return what we've stored so far */
    if (maxlen < 5 || ! need_parent)
        return 3 ;

    spin_lock(&dentry->d_lock);
    inode = dentry->d_parent->d_inode ;
    data[3] = inode->i_ino ;
    data[4] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
    *lenp = 5 ;
    if (maxlen >= 6) {
	    data[5] = inode->i_generation ;
	    *lenp = 6 ;
    }
    spin_unlock(&dentry->d_lock);
    return *lenp ;
}


/* looks for stat data, then copies fields to it, marks the buffer
   containing stat data as dirty */
/* reiserfs inodes are never really dirty, since the dirty inode call
** always logs them.  This call allows the VFS inode marking routines
** to properly mark inodes for datasync and such, but only actually
** does something when called for a synchronous update.
*/
int reiserfs_write_inode (struct inode * inode, int do_sync) {
    struct reiserfs_transaction_handle th ;
    int jbegin_count = 1 ;

    if (inode->i_sb->s_flags & MS_RDONLY)
        return -EROFS;
    /* memory pressure can sometimes initiate write_inode calls with sync == 1,
    ** these cases are just when the system needs ram, not when the 
    ** inode needs to reach disk for safety, and they can safely be
    ** ignored because the altered inode has already been logged.
    */
    if (do_sync && !(current->flags & PF_MEMALLOC)) {
	reiserfs_write_lock(inode->i_sb);
	if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
            reiserfs_update_sd (&th, inode);
            journal_end_sync(&th, inode->i_sb, jbegin_count) ;
        }
	reiserfs_write_unlock(inode->i_sb);
    }
    return 0;
}

/* stat data of new object is inserted already, this inserts the item
   containing "." and ".." entries */
static int reiserfs_new_directory (struct reiserfs_transaction_handle *th, 
				   struct inode *inode,
				   struct item_head * ih, struct path * path,
				   struct inode * dir)
{
    struct super_block * sb = th->t_super;
    char empty_dir [EMPTY_DIR_SIZE];
    char * body = empty_dir;
    struct cpu_key key;
    int retval;

    BUG_ON (!th->t_trans_id);
    
    _make_cpu_key (&key, KEY_FORMAT_3_5, le32_to_cpu (ih->ih_key.k_dir_id),
		   le32_to_cpu (ih->ih_key.k_objectid), DOT_OFFSET, TYPE_DIRENTRY, 3/*key length*/);
    
    /* compose item head for new item. Directories consist of items of
       old type (ITEM_VERSION_1). Do not set key (second arg is 0), it
       is done by reiserfs_new_inode */
    if (old_format_only (sb)) {
	make_le_item_head (ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE_V1, 2);
	
	make_empty_dir_item_v1 (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
				INODE_PKEY (dir)->k_dir_id, 
				INODE_PKEY (dir)->k_objectid );
    } else {
	make_le_item_head (ih, NULL, KEY_FORMAT_3_5, DOT_OFFSET, TYPE_DIRENTRY, EMPTY_DIR_SIZE, 2);
	
	make_empty_dir_item (body, ih->ih_key.k_dir_id, ih->ih_key.k_objectid,
		   		INODE_PKEY (dir)->k_dir_id, 
		   		INODE_PKEY (dir)->k_objectid );
    }
    
    /* look for place in the tree for new item */
    retval = search_item (sb, &key, path);
    if (retval == IO_ERROR) {
	reiserfs_warning (sb, "vs-13080: reiserfs_new_directory: "
			  "i/o failure occurred creating new directory");
	return -EIO;
    }
    if (retval == ITEM_FOUND) {
	pathrelse (path);
	reiserfs_warning (sb, "vs-13070: reiserfs_new_directory: "
			  "object with this key exists (%k)", &(ih->ih_key));
	return -EEXIST;
    }

    /* insert item, that is empty directory item */
    return reiserfs_insert_item (th, path, &key, ih, inode, body);
}


/* stat data of object has been inserted, this inserts the item
   containing the body of symlink */
static int reiserfs_new_symlink (struct reiserfs_transaction_handle *th, 
				 struct inode *inode,	/* Inode of symlink */
				 struct item_head * ih,
				 struct path * path, const char * symname, int item_len)
{
    struct super_block * sb = th->t_super;
    struct cpu_key key;
    int retval;

    BUG_ON (!th->t_trans_id);

    _make_cpu_key (&key, KEY_FORMAT_3_5, 
		   le32_to_cpu (ih->ih_key.k_dir_id), 
		   le32_to_cpu (ih->ih_key.k_objectid),
		   1, TYPE_DIRECT, 3/*key length*/);

    make_le_item_head (ih, NULL, KEY_FORMAT_3_5, 1, TYPE_DIRECT, item_len, 0/*free_space*/);

    /* look for place in the tree for new item */
    retval = search_item (sb, &key, path);
    if (retval == IO_ERROR) {
	reiserfs_warning (sb, "vs-13080: reiserfs_new_symlinik: "
			  "i/o failure occurred creating new symlink");
	return -EIO;
    }
    if (retval == ITEM_FOUND) {
	pathrelse (path);
	reiserfs_warning (sb, "vs-13080: reiserfs_new_symlink: "
			  "object with this key exists (%k)", &(ih->ih_key));
	return -EEXIST;
    }

    /* insert item, that is body of symlink */
    return reiserfs_insert_item (th, path, &key, ih, inode, symname);
}


/* inserts the stat data into the tree, and then calls
   reiserfs_new_directory (to insert ".", ".." item if new object is
   directory) or reiserfs_new_symlink (to insert symlink body if new
   object is symlink) or nothing (if new object is regular file) 

   NOTE! uid and gid must already be set in the inode.  If we return
   non-zero due to an error, we have to drop the quota previously allocated
   for the fresh inode.  This can only be done outside a transaction, so
   if we return non-zero, we also end the transaction.  */
int reiserfs_new_inode (struct reiserfs_transaction_handle *th,
			struct inode * dir, int mode, 
			const char * symname, 
                        /* 0 for regular, EMTRY_DIR_SIZE for dirs, 
			   strlen (symname) for symlinks)*/
		         loff_t i_size, struct dentry *dentry, 
			 struct inode *inode)
{
    struct super_block * sb;
    INITIALIZE_PATH (path_to_key);
    struct cpu_key key;
    struct item_head ih;
    struct stat_data sd;
    int retval;
    int err;

    BUG_ON (!th->t_trans_id);
  
    if (DQUOT_ALLOC_INODE(inode)) {
	err = -EDQUOT;
	goto out_end_trans;
    }
    if (!dir || !dir->i_nlink) {
	err = -EPERM;
	goto out_bad_inode;
    }

    sb = dir->i_sb;

    /* item head of new item */
    ih.ih_key.k_dir_id = reiserfs_choose_packing(dir);
    ih.ih_key.k_objectid = cpu_to_le32 (reiserfs_get_unused_objectid (th));
    if (!ih.ih_key.k_objectid) {
	err = -ENOMEM;
	goto out_bad_inode ;
    }
    if (old_format_only (sb))
	/* not a perfect generation count, as object ids can be reused, but 
	** this is as good as reiserfs can do right now.
	** note that the private part of inode isn't filled in yet, we have
	** to use the directory.
	*/
	inode->i_generation = le32_to_cpu (INODE_PKEY (dir)->k_objectid);
    else
#if defined( USE_INODE_GENERATION_COUNTER )
	inode->i_generation = le32_to_cpu(REISERFS_SB(sb)->s_rs->s_inode_generation);
#else
	inode->i_generation = ++event;
#endif

    /* fill stat data */
    inode->i_nlink = (S_ISDIR (mode) ? 2 : 1);

    /* uid and gid must already be set by the caller for quota init */

    /* symlink cannot be immutable or append only, right? */
    if( S_ISLNK( inode -> i_mode ) )
	    inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );

    inode->i_mtime = inode->i_atime = inode->i_ctime =
	    CURRENT_TIME_SEC;
    inode->i_size = i_size;
    inode->i_blocks = 0;
    inode->i_bytes = 0;
    REISERFS_I(inode)->i_first_direct_byte = S_ISLNK(mode) ? 1 : 
      U32_MAX/*NO_BYTES_IN_DIRECT_ITEM*/;

    INIT_LIST_HEAD(&(REISERFS_I(inode)->i_prealloc_list ));
    REISERFS_I(inode)->i_flags = 0;
    REISERFS_I(inode)->i_prealloc_block = 0;
    REISERFS_I(inode)->i_prealloc_count = 0;
    REISERFS_I(inode)->i_trans_id = 0;
    REISERFS_I(inode)->i_jl = NULL;
    REISERFS_I(inode)->i_attrs =
	REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
    sd_attrs_to_i_attrs( REISERFS_I(inode) -> i_attrs, inode );
    REISERFS_I(inode)->i_acl_access = NULL;
    REISERFS_I(inode)->i_acl_default = NULL;
    init_rwsem (&REISERFS_I(inode)->xattr_sem);

    if (old_format_only (sb))
	make_le_item_head (&ih, NULL, KEY_FORMAT_3_5, SD_OFFSET, TYPE_STAT_DATA, SD_V1_SIZE, MAX_US_INT);
    else
	make_le_item_head (&ih, NULL, KEY_FORMAT_3_6, SD_OFFSET, TYPE_STAT_DATA, SD_SIZE, MAX_US_INT);

    /* key to search for correct place for new stat data */
    _make_cpu_key (&key, KEY_FORMAT_3_6, le32_to_cpu (ih.ih_key.k_dir_id),
		   le32_to_cpu (ih.ih_key.k_objectid), SD_OFFSET, TYPE_STAT_DATA, 3/*key length*/);

    /* find proper place for inserting of stat data */
    retval = search_item (sb, &key, &path_to_key);
    if (retval == IO_ERROR) {
	err = -EIO;
	goto out_bad_inode;
    }
    if (retval == ITEM_FOUND) {
	pathrelse (&path_to_key);
	err = -EEXIST;
	goto out_bad_inode;
    }
    if (old_format_only (sb)) {
	if (inode->i_uid & ~0xffff || inode->i_gid & ~0xffff) {
	    pathrelse (&path_to_key);
	    /* i_uid or i_gid is too big to be stored in stat data v3.5 */
	    err = -EINVAL;
	    goto out_bad_inode;
	}
	inode2sd_v1 (&sd, inode, inode->i_size);
    } else {
	inode2sd (&sd, inode, inode->i_size);
    }
    // these do not go to on-disk stat data
    inode->i_ino = le32_to_cpu (ih.ih_key.k_objectid);
    inode->i_blksize = reiserfs_default_io_size;
  
    // store in in-core inode the key of stat data and version all
    // object items will have (directory items will have old offset
    // format, other new objects will consist of new items)
    memcpy (INODE_PKEY (inode), &(ih.ih_key), KEY_SIZE);
    if (old_format_only (sb) || S_ISDIR(mode) || S_ISLNK(mode))
        set_inode_item_key_version (inode, KEY_FORMAT_3_5);
    else
        set_inode_item_key_version (inode, KEY_FORMAT_3_6);
    if (old_format_only (sb))
	set_inode_sd_version (inode, STAT_DATA_V1);
    else
	set_inode_sd_version (inode, STAT_DATA_V2);
    
    /* insert the stat data into the tree */
#ifdef DISPLACE_NEW_PACKING_LOCALITIES
    if (REISERFS_I(dir)->new_packing_locality)
	th->displace_new_blocks = 1;
#endif
    retval = reiserfs_insert_item (th, &path_to_key, &key, &ih, inode, (char *)(&sd));
    if (retval) {
	err = retval;
	reiserfs_check_path(&path_to_key) ;
	goto out_bad_inode;
    }

#ifdef DISPLACE_NEW_PACKING_LOCALITIES
    if (!th->displace_new_blocks)
	REISERFS_I(dir)->new_packing_locality = 0;
#endif
    if (S_ISDIR(mode)) {
	/* insert item with "." and ".." */
	retval = reiserfs_new_directory (th, inode, &ih, &path_to_key, dir);
    }

    if (S_ISLNK(mode)) {
	/* insert body of symlink */
	if (!old_format_only (sb))
	    i_size = ROUND_UP(i_size);
	retval = reiserfs_new_symlink (th, inode, &ih, &path_to_key, symname, i_size);
    }
    if (retval) {
	err = retval;
	reiserfs_check_path(&path_to_key) ;
	journal_end(th, th->t_super, th->t_blocks_allocated);
	goto out_inserted_sd;
    }

    /* XXX CHECK THIS */
    if (reiserfs_posixacl (inode->i_sb)) {
        retval = reiserfs_inherit_default_acl (dir, dentry, inode);
        if (retval) {
            err = retval;
            reiserfs_check_path(&path_to_key) ;
            journal_end(th, th->t_super, th->t_blocks_allocated);
            goto out_inserted_sd;
        }
    } else if (inode->i_sb->s_flags & MS_POSIXACL) {
	reiserfs_warning (inode->i_sb, "ACLs aren't enabled in the fs, "
			  "but vfs thinks they are!");
    } else if (is_reiserfs_priv_object (dir)) {
	reiserfs_mark_inode_private (inode);
    }

    insert_inode_hash (inode);
    reiserfs_update_sd(th, inode);
    reiserfs_check_path(&path_to_key) ;

    return 0;

/* it looks like you can easily compress these two goto targets into
 * one.  Keeping it like this doesn't actually hurt anything, and they
 * are place holders for what the quota code actually needs.
 */
out_bad_inode:
    /* Invalidate the object, nothing was inserted yet */
    INODE_PKEY(inode)->k_objectid = 0;

    /* Quota change must be inside a transaction for journaling */
    DQUOT_FREE_INODE(inode);

out_end_trans:
    journal_end(th, th->t_super, th->t_blocks_allocated) ;
    /* Drop can be outside and it needs more credits so it's better to have it outside */
    DQUOT_DROP(inode);
    inode->i_flags |= S_NOQUOTA;
    make_bad_inode(inode);

out_inserted_sd:
    inode->i_nlink = 0;
    th->t_trans_id = 0; /* so the caller can't use this handle later */
    iput(inode);
    return err;
}

/*
** finds the tail page in the page cache,
** reads the last block in.
**
** On success, page_result is set to a locked, pinned page, and bh_result
** is set to an up to date buffer for the last block in the file.  returns 0.
**
** tail conversion is not done, so bh_result might not be valid for writing
** check buffer_mapped(bh_result) and bh_result->b_blocknr != 0 before
** trying to write the block.
**
** on failure, nonzero is returned, page_result and bh_result are untouched.
*/
static int grab_tail_page(struct inode *p_s_inode, 
			  struct page **page_result, 
			  struct buffer_head **bh_result) {

    /* we want the page with the last byte in the file,
    ** not the page that will hold the next byte for appending
    */
    unsigned long index = (p_s_inode->i_size-1) >> PAGE_CACHE_SHIFT ;
    unsigned long pos = 0 ;
    unsigned long start = 0 ;
    unsigned long blocksize = p_s_inode->i_sb->s_blocksize ;
    unsigned long offset = (p_s_inode->i_size) & (PAGE_CACHE_SIZE - 1) ;
    struct buffer_head *bh ;
    struct buffer_head *head ;
    struct page * page ;
    int error ;
    
    /* we know that we are only called with inode->i_size > 0.
    ** we also know that a file tail can never be as big as a block
    ** If i_size % blocksize == 0, our file is currently block aligned
    ** and it won't need converting or zeroing after a truncate.
    */
    if ((offset & (blocksize - 1)) == 0) {
        return -ENOENT ;
    }
    page = grab_cache_page(p_s_inode->i_mapping, index) ;
    error = -ENOMEM ;
    if (!page) {
        goto out ;
    }
    /* start within the page of the last block in the file */
    start = (offset / blocksize) * blocksize ;

    error = block_prepare_write(page, start, offset, 
				reiserfs_get_block_create_0) ;
    if (error)
	goto unlock ;

    head = page_buffers(page) ;      
    bh = head;
    do {
	if (pos >= start) {
	    break ;
	}
	bh = bh->b_this_page ;
	pos += blocksize ;
    } while(bh != head) ;

    if (!buffer_uptodate(bh)) {
	/* note, this should never happen, prepare_write should
	** be taking care of this for us.  If the buffer isn't up to date,
	** I've screwed up the code to find the buffer, or the code to
	** call prepare_write
	*/
	reiserfs_warning (p_s_inode->i_sb,
			  "clm-6000: error reading block %lu on dev %s",
			  bh->b_blocknr,
			  reiserfs_bdevname (p_s_inode->i_sb)) ;
	error = -EIO ;
	goto unlock ;
    }
    *bh_result = bh ;
    *page_result = page ;

out:
    return error ;

unlock:
    unlock_page(page) ;
    page_cache_release(page) ;
    return error ;
}

/*
** vfs version of truncate file.  Must NOT be called with
** a transaction already started.
**
** some code taken from block_truncate_page
*/
int reiserfs_truncate_file(struct inode *p_s_inode, int update_timestamps) {
    struct reiserfs_transaction_handle th ;
    /* we want the offset for the first byte after the end of the file */
    unsigned long offset = p_s_inode->i_size & (PAGE_CACHE_SIZE - 1) ;
    unsigned blocksize = p_s_inode->i_sb->s_blocksize ;
    unsigned length ;
    struct page *page = NULL ;
    int error ;
    struct buffer_head *bh = NULL ;

    reiserfs_write_lock(p_s_inode->i_sb);

    if (p_s_inode->i_size > 0) {
        if ((error = grab_tail_page(p_s_inode, &page, &bh))) {
	    // -ENOENT means we truncated past the end of the file, 
	    // and get_block_create_0 could not find a block to read in,
	    // which is ok.
	    if (error != -ENOENT)
	        reiserfs_warning (p_s_inode->i_sb,
				  "clm-6001: grab_tail_page failed %d",
				  error);
	    page = NULL ;
	    bh = NULL ;
	}
    }

    /* so, if page != NULL, we have a buffer head for the offset at 
    ** the end of the file. if the bh is mapped, and bh->b_blocknr != 0, 
    ** then we have an unformatted node.  Otherwise, we have a direct item, 
    ** and no zeroing is required on disk.  We zero after the truncate, 
    ** because the truncate might pack the item anyway 
    ** (it will unmap bh if it packs).
    */
    /* it is enough to reserve space in transaction for 2 balancings:
       one for "save" link adding and another for the first
       cut_from_item. 1 is for update_sd */
    error = journal_begin (&th, p_s_inode->i_sb,
                           JOURNAL_PER_BALANCE_CNT * 2 + 1);
    if (error)
        goto out;
    reiserfs_update_inode_transaction(p_s_inode) ;
    if (update_timestamps)
	    /* we are doing real truncate: if the system crashes before the last
	       transaction of truncating gets committed - on reboot the file
	       either appears truncated properly or not truncated at all */
	add_save_link (&th, p_s_inode, 1);
    error = reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
    if (error)
        goto out;
    error = journal_end (&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1);
    if (error)
        goto out;

    if (update_timestamps) {
	error = remove_save_link (p_s_inode, 1/* truncate */);
        if (error)
            goto out;
    }

    if (page) {
        length = offset & (blocksize - 1) ;
	/* if we are not on a block boundary */
	if (length) {
	    char *kaddr;

	    length = blocksize - length ;
	    kaddr = kmap_atomic(page, KM_USER0) ;
	    memset(kaddr + offset, 0, length) ;   
	    flush_dcache_page(page) ;
	    kunmap_atomic(kaddr, KM_USER0) ;
	    if (buffer_mapped(bh) && bh->b_blocknr != 0) {
	        mark_buffer_dirty(bh) ;
	    }
	}
	unlock_page(page) ;
	page_cache_release(page) ;
    }

    reiserfs_write_unlock(p_s_inode->i_sb);
    return 0;
out:
    if (page) {
        unlock_page (page);
        page_cache_release (page);
    }
    reiserfs_write_unlock(p_s_inode->i_sb);
    return error;
}

static int map_block_for_writepage(struct inode *inode, 
			       struct buffer_head *bh_result, 
                               unsigned long block) {
    struct reiserfs_transaction_handle th ;
    int fs_gen ;
    struct item_head tmp_ih ;
    struct item_head *ih ;
    struct buffer_head *bh ;
    __le32 *item ;
    struct cpu_key key ;
    INITIALIZE_PATH(path) ;
    int pos_in_item ;
    int jbegin_count = JOURNAL_PER_BALANCE_CNT ;
    loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1 ;
    int retval ;
    int use_get_block = 0 ;
    int bytes_copied = 0 ;
    int copy_size ;
    int trans_running = 0;

    /* catch places below that try to log something without starting a trans */
    th.t_trans_id = 0;

    if (!buffer_uptodate(bh_result)) {
	return -EIO;
    }

    kmap(bh_result->b_page) ;
start_over:
    reiserfs_write_lock(inode->i_sb);
    make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3) ;

research:
    retval = search_for_position_by_key(inode->i_sb, &key, &path) ;
    if (retval != POSITION_FOUND) {
        use_get_block = 1;
	goto out ;
    } 

    bh = get_last_bh(&path) ;
    ih = get_ih(&path) ;
    item = get_item(&path) ;
    pos_in_item = path.pos_in_item ;

    /* we've found an unformatted node */
    if (indirect_item_found(retval, ih)) {
	if (bytes_copied > 0) {
	    reiserfs_warning (inode->i_sb, "clm-6002: bytes_copied %d",
			      bytes_copied) ;
	}
        if (!get_block_num(item, pos_in_item)) {
	    /* crap, we are writing to a hole */
	    use_get_block = 1;
	    goto out ;
	}
	set_block_dev_mapped(bh_result, get_block_num(item,pos_in_item),inode);
    } else if (is_direct_le_ih(ih)) {
        char *p ; 
        p = page_address(bh_result->b_page) ;
        p += (byte_offset -1) & (PAGE_CACHE_SIZE - 1) ;
        copy_size = ih_item_len(ih) - pos_in_item;

	fs_gen = get_generation(inode->i_sb) ;
	copy_item_head(&tmp_ih, ih) ;

	if (!trans_running) {
	    /* vs-3050 is gone, no need to drop the path */
	    retval = journal_begin(&th, inode->i_sb, jbegin_count) ;
            if (retval)
                goto out;
	    reiserfs_update_inode_transaction(inode) ;
	    trans_running = 1;
	    if (fs_changed(fs_gen, inode->i_sb) && item_moved(&tmp_ih, &path)) {
		reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
		goto research;
	    }
	}

	reiserfs_prepare_for_journal(inode->i_sb, bh, 1) ;

	if (fs_changed (fs_gen, inode->i_sb) && item_moved (&tmp_ih, &path)) {
	    reiserfs_restore_prepared_buffer(inode->i_sb, bh) ;
	    goto research;
	}

	memcpy( B_I_PITEM(bh, ih) + pos_in_item, p + bytes_copied, copy_size) ;

	journal_mark_dirty(&th, inode->i_sb, bh) ;
	bytes_copied += copy_size ;
	set_block_dev_mapped(bh_result, 0, inode);

	/* are there still bytes left? */
        if (bytes_copied < bh_result->b_size && 
	    (byte_offset + bytes_copied) < inode->i_size) {
	    set_cpu_key_k_offset(&key, cpu_key_k_offset(&key) + copy_size) ;
	    goto research ;
	}
    } else {
        reiserfs_warning (inode->i_sb,
			  "clm-6003: bad item inode %lu, device %s",
			  inode->i_ino, reiserfs_bdevname (inode->i_sb)) ;
        retval = -EIO ;
	goto out ;
    }
    retval = 0 ;
    
out:
    pathrelse(&path) ;
    if (trans_running) {
        int err = journal_end(&th, inode->i_sb, jbegin_count) ;
        if (err)
            retval = err;
	trans_running = 0;
    }
    reiserfs_write_unlock(inode->i_sb);

    /* this is where we fill in holes in the file. */
    if (use_get_block) {
	retval = reiserfs_get_block(inode, block, bh_result, 
	                            GET_BLOCK_CREATE | GET_BLOCK_NO_ISEM |
				    GET_BLOCK_NO_DANGLE);
	if (!retval) {
	    if (!buffer_mapped(bh_result) || bh_result->b_blocknr == 0) {
	        /* get_block failed to find a mapped unformatted node. */
		use_get_block = 0 ;
		goto start_over ;
	    }
	}
    }
    kunmap(bh_result->b_page) ;

    if (!retval && buffer_mapped(bh_result) && bh_result->b_blocknr == 0) {
	/* we've copied data from the page into the direct item, so the
	 * buffer in the page is now clean, mark it to reflect that.
	 */
        lock_buffer(bh_result);
	clear_buffer_dirty(bh_result);
	unlock_buffer(bh_result);
    }
    return retval ;
}

/* 
 * mason@suse.com: updated in 2.5.54 to follow the same general io 
 * start/recovery path as __block_write_full_page, along with special
 * code to handle reiserfs tails.
 */
static int reiserfs_write_full_page(struct page *page, struct writeback_control *wbc) {
    struct inode *inode = page->mapping->host ;
    unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT ;
    int error = 0;
    unsigned long block ;
    struct buffer_head *head, *bh;
    int partial = 0 ;
    int nr = 0;
    int checked = PageChecked(page);
    struct reiserfs_transaction_handle th;
    struct super_block *s = inode->i_sb;
    int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
    th.t_trans_id = 0;

    /* The page dirty bit is cleared before writepage is called, which
     * means we have to tell create_empty_buffers to make dirty buffers
     * The page really should be up to date at this point, so tossing
     * in the BH_Uptodate is just a sanity check.
     */
    if (!page_has_buffers(page)) {
	create_empty_buffers(page, s->s_blocksize,
	                    (1 << BH_Dirty) | (1 << BH_Uptodate));
    }
    head = page_buffers(page) ;

    /* last page in the file, zero out any contents past the
    ** last byte in the file
    */
    if (page->index >= end_index) {
	char *kaddr;
	unsigned last_offset;

        last_offset = inode->i_size & (PAGE_CACHE_SIZE - 1) ;
	/* no file contents in this page */
	if (page->index >= end_index + 1 || !last_offset) {
    	    unlock_page(page);
	    return 0;
	}
	kaddr = kmap_atomic(page, KM_USER0);
	memset(kaddr + last_offset, 0, PAGE_CACHE_SIZE-last_offset) ;
	flush_dcache_page(page) ;
	kunmap_atomic(kaddr, KM_USER0) ;
    }
    bh = head ;
    block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits) ;
    /* first map all the buffers, logging any direct items we find */
    do {
	if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) ||
	   (buffer_mapped(bh) && bh->b_blocknr == 0))) {
	    /* not mapped yet, or it points to a direct item, search
	     * the btree for the mapping info, and log any direct
	     * items found
	     */
	    if ((error = map_block_for_writepage(inode, bh, block))) {
		goto fail ;
	    }
	}
        bh = bh->b_this_page;
	block++;
    } while(bh != head) ;

    /*
     * we start the transaction after map_block_for_writepage,
     * because it can create holes in the file (an unbounded operation).
     * starting it here, we can make a reliable estimate for how many
     * blocks we're going to log
     */
    if (checked) {
	ClearPageChecked(page);
	reiserfs_write_lock(s);
	error = journal_begin(&th, s, bh_per_page + 1);
	if (error) {
	    reiserfs_write_unlock(s);
	    goto fail;
	}
	reiserfs_update_inode_transaction(inode);
    }
    /* now go through and lock any dirty buffers on the page */
    do {
	get_bh(bh);
	if (!buffer_mapped(bh))
	    continue;
	if (buffer_mapped(bh) && bh->b_blocknr == 0)
	    continue;

	if (checked) {
	    reiserfs_prepare_for_journal(s, bh, 1);
	    journal_mark_dirty(&th, s, bh);
	    continue;
	}
	/* from this point on, we know the buffer is mapped to a
	 * real block and not a direct item
	 */
	if (wbc->sync_mode != WB_SYNC_NONE || !wbc->nonblocking) {
	    lock_buffer(bh);
	} else {
	    if (test_set_buffer_locked(bh)) {
		redirty_page_for_writepage(wbc, page);
		continue;
	    }
	}
	if (test_clear_buffer_dirty(bh)) {
	    mark_buffer_async_write(bh);
	} else {
	    unlock_buffer(bh);
	}
    } while((bh = bh->b_this_page) != head);

    if (checked) {
	error = journal_end(&th, s, bh_per_page + 1);
	reiserfs_write_unlock(s);
	if (error)
	    goto fail;
    }
    BUG_ON(PageWriteback(page));
    set_page_writeback(page);
    unlock_page(page);

    /*
     * since any buffer might be the only dirty buffer on the page, 
     * the first submit_bh can bring the page out of writeback.
     * be careful with the buffers.
     */
    do {
        struct buffer_head *next = bh->b_this_page;
	if (buffer_async_write(bh)) {
	    submit_bh(WRITE, bh);
	    nr++;
	}
	put_bh(bh);
	bh = next;
    } while(bh != head);

    error = 0;
done:
    if (nr == 0) {
        /*
         * if this page only had a direct item, it is very possible for
         * no io to be required without there being an error.  Or, 
	 * someone else could have locked them and sent them down the 
	 * pipe without locking the page
	 */
	bh = head ;
	do {
	    if (!buffer_uptodate(bh)) {
	        partial = 1;
		break;
	    }
	    bh = bh->b_this_page;
	} while(bh != head);
	if (!partial)
	    SetPageUptodate(page);
	end_page_writeback(page);
    }
    return error;

fail:
    /* catches various errors, we need to make sure any valid dirty blocks
     * get to the media.  The page is currently locked and not marked for 
     * writeback
     */
    ClearPageUptodate(page);
    bh = head;
    do {
	get_bh(bh);
	if (buffer_mapped(bh) && buffer_dirty(bh) && bh->b_blocknr) {
	    lock_buffer(bh);
	    mark_buffer_async_write(bh);
	} else {
	    /*
	     * clear any dirty bits that might have come from getting
	     * attached to a dirty page
	     */
	     clear_buffer_dirty(bh);
	}
        bh = bh->b_this_page;
    } while(bh != head);
    SetPageError(page);
    BUG_ON(PageWriteback(page));
    set_page_writeback(page);
    unlock_page(page);
    do {
        struct buffer_head *next = bh->b_this_page;
	if (buffer_async_write(bh)) {
	    clear_buffer_dirty(bh);
	    submit_bh(WRITE, bh);
	    nr++;
	}
	put_bh(bh);
	bh = next;
    } while(bh != head);
    goto done;
}


static int reiserfs_readpage (struct file *f, struct page * page)
{
    return block_read_full_page (page, reiserfs_get_block);
}


static int reiserfs_writepage (struct page * page, struct writeback_control *wbc)
{
    struct inode *inode = page->mapping->host ;
    reiserfs_wait_on_write_block(inode->i_sb) ;
    return reiserfs_write_full_page(page, wbc) ;
}

static int reiserfs_prepare_write(struct file *f, struct page *page,
			   unsigned from, unsigned to) {
    struct inode *inode = page->mapping->host ;
    int ret;
    int old_ref = 0;

    reiserfs_wait_on_write_block(inode->i_sb) ;
    fix_tail_page_for_writing(page) ;
    if (reiserfs_transaction_running(inode->i_sb)) {
	struct reiserfs_transaction_handle *th;
	th = (struct reiserfs_transaction_handle *)current->journal_info;
        BUG_ON (!th->t_refcount);
        BUG_ON (!th->t_trans_id);
	old_ref = th->t_refcount;
	th->t_refcount++;
    }

    ret = block_prepare_write(page, from, to, reiserfs_get_block) ;
    if (ret && reiserfs_transaction_running(inode->i_sb)) {
    	struct reiserfs_transaction_handle *th = current->journal_info;
	/* this gets a little ugly.  If reiserfs_get_block returned an
	 * error and left a transacstion running, we've got to close it,
	 * and we've got to free handle if it was a persistent transaction.
	 *
	 * But, if we had nested into an existing transaction, we need
	 * to just drop the ref count on the handle.
	 *
	 * If old_ref == 0, the transaction is from reiserfs_get_block,
	 * and it was a persistent trans.  Otherwise, it was nested above.
	 */
	if (th->t_refcount > old_ref) {
	    if (old_ref)
	    	th->t_refcount--;
	    else {
                int err;
		reiserfs_write_lock(inode->i_sb);
		err = reiserfs_end_persistent_transaction(th);
		reiserfs_write_unlock(inode->i_sb);
                if (err)
                    ret = err;
	    }
	}
    }
    return ret;

}


static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block) {
  return generic_block_bmap(as, block, reiserfs_bmap) ;
}

static int reiserfs_commit_write(struct file *f, struct page *page, 
                                 unsigned from, unsigned to) {
    struct inode *inode = page->mapping->host ;
    loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
    int ret = 0;
    int update_sd = 0;
    struct reiserfs_transaction_handle *th = NULL;
    
    reiserfs_wait_on_write_block(inode->i_sb) ;
    if (reiserfs_transaction_running(inode->i_sb)) {
        th = current->journal_info;
    }
    reiserfs_commit_page(inode, page, from, to);
 
    /* generic_commit_write does this for us, but does not update the
    ** transaction tracking stuff when the size changes.  So, we have
    ** to do the i_size updates here.
    */
    if (pos > inode->i_size) {
	struct reiserfs_transaction_handle myth ;
	reiserfs_write_lock(inode->i_sb);
	/* If the file have grown beyond the border where it
	   can have a tail, unmark it as needing a tail
	   packing */
	if ( (have_large_tails (inode->i_sb) && inode->i_size > i_block_size (inode)*4) ||
	     (have_small_tails (inode->i_sb) && inode->i_size > i_block_size(inode)) )
	    REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask ;

	ret = journal_begin(&myth, inode->i_sb, 1) ;
	if (ret) {
	    reiserfs_write_unlock(inode->i_sb);
	    goto journal_error;
	}
	reiserfs_update_inode_transaction(inode) ;
	inode->i_size = pos ;
	reiserfs_update_sd(&myth, inode) ;
	update_sd = 1;
	ret = journal_end(&myth, inode->i_sb, 1) ;
	reiserfs_write_unlock(inode->i_sb);
	if (ret)
	    goto journal_error;
    }
    if (th) {
	reiserfs_write_lock(inode->i_sb);
	if (!update_sd)
	    reiserfs_update_sd(th, inode) ;
	ret = reiserfs_end_persistent_transaction(th);
	reiserfs_write_unlock(inode->i_sb);
	if (ret)
	    goto out;
    }
 
    /* we test for O_SYNC here so we can commit the transaction
    ** for any packed tails the file might have had
    */
    if (f && (f->f_flags & O_SYNC)) {
	reiserfs_write_lock(inode->i_sb);
 	ret = reiserfs_commit_for_inode(inode) ;
	reiserfs_write_unlock(inode->i_sb);
    }
out:
    return ret ;

journal_error:
    if (th) {
	reiserfs_write_lock(inode->i_sb);
	if (!update_sd)
	    reiserfs_update_sd(th, inode) ;
        ret = reiserfs_end_persistent_transaction(th);
	reiserfs_write_unlock(inode->i_sb);
    }

    return ret;
}

void sd_attrs_to_i_attrs( __u16 sd_attrs, struct inode *inode )
{
	if( reiserfs_attrs( inode -> i_sb ) ) {
		if( sd_attrs & REISERFS_SYNC_FL )
			inode -> i_flags |= S_SYNC;
		else
			inode -> i_flags &= ~S_SYNC;
		if( sd_attrs & REISERFS_IMMUTABLE_FL )
			inode -> i_flags |= S_IMMUTABLE;
		else
			inode -> i_flags &= ~S_IMMUTABLE;
		if( sd_attrs & REISERFS_APPEND_FL )
			inode -> i_flags |= S_APPEND;
		else
			inode -> i_flags &= ~S_APPEND;
		if( sd_attrs & REISERFS_NOATIME_FL )
			inode -> i_flags |= S_NOATIME;
		else
			inode -> i_flags &= ~S_NOATIME;
		if( sd_attrs & REISERFS_NOTAIL_FL )
			REISERFS_I(inode)->i_flags |= i_nopack_mask;
		else
			REISERFS_I(inode)->i_flags &= ~i_nopack_mask;
	}
}

void i_attrs_to_sd_attrs( struct inode *inode, __u16 *sd_attrs )
{
	if( reiserfs_attrs( inode -> i_sb ) ) {
		if( inode -> i_flags & S_IMMUTABLE )
			*sd_attrs |= REISERFS_IMMUTABLE_FL;
		else
			*sd_attrs &= ~REISERFS_IMMUTABLE_FL;
		if( inode -> i_flags & S_SYNC )
			*sd_attrs |= REISERFS_SYNC_FL;
		else
			*sd_attrs &= ~REISERFS_SYNC_FL;
		if( inode -> i_flags & S_NOATIME )
			*sd_attrs |= REISERFS_NOATIME_FL;
		else
			*sd_attrs &= ~REISERFS_NOATIME_FL;
		if( REISERFS_I(inode)->i_flags & i_nopack_mask )
			*sd_attrs |= REISERFS_NOTAIL_FL;
		else
			*sd_attrs &= ~REISERFS_NOTAIL_FL;
	}
}

/* decide if this buffer needs to stay around for data logging or ordered
** write purposes
*/
static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh)
{
    int ret = 1 ;
    struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb) ;

    spin_lock(&j->j_dirty_buffers_lock) ;
    if (!buffer_mapped(bh)) {
        goto free_jh;
    }
    /* the page is locked, and the only places that log a data buffer
     * also lock the page.
     */
    if (reiserfs_file_data_log(inode)) {
	/*
	 * very conservative, leave the buffer pinned if
	 * anyone might need it.
	 */
        if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
	    ret = 0 ;
	}
    } else
    if (buffer_dirty(bh) || buffer_locked(bh)) {
	struct reiserfs_journal_list *jl;
	struct reiserfs_jh *jh = bh->b_private;

	/* why is this safe?
	 * reiserfs_setattr updates i_size in the on disk
	 * stat data before allowing vmtruncate to be called.
	 *
	 * If buffer was put onto the ordered list for this
	 * transaction, we know for sure either this transaction
	 * or an older one already has updated i_size on disk,
	 * and this ordered data won't be referenced in the file
	 * if we crash.
	 *
	 * if the buffer was put onto the ordered list for an older
	 * transaction, we need to leave it around
	 */
	if (jh && (jl = jh->jl) && jl != SB_JOURNAL(inode->i_sb)->j_current_jl)
	    ret = 0;
    }
free_jh:
    if (ret && bh->b_private) {
        reiserfs_free_jh(bh);
    }
    spin_unlock(&j->j_dirty_buffers_lock) ;
    return ret ;
}

/* clm -- taken from fs/buffer.c:block_invalidate_page */
static int reiserfs_invalidatepage(struct page *page, unsigned long offset)
{
    struct buffer_head *head, *bh, *next;
    struct inode *inode = page->mapping->host;
    unsigned int curr_off = 0;
    int ret = 1;

    BUG_ON(!PageLocked(page));

    if (offset == 0)
	ClearPageChecked(page);

    if (!page_has_buffers(page))
	goto out;

    head = page_buffers(page);
    bh = head;
    do {
	unsigned int next_off = curr_off + bh->b_size;
	next = bh->b_this_page;

	/*
	 * is this block fully invalidated?
	 */
	if (offset <= curr_off) {
	    if (invalidatepage_can_drop(inode, bh))
		reiserfs_unmap_buffer(bh);
	    else
	        ret = 0;
	}
	curr_off = next_off;
	bh = next;
    } while (bh != head);

    /*
     * We release buffers only if the entire page is being invalidated.
     * The get_block cached value has been unconditionally invalidated,
     * so real IO is not possible anymore.
     */
    if (!offset && ret)
	ret = try_to_release_page(page, 0);
out:
    return ret;
}

static int reiserfs_set_page_dirty(struct page *page) {
    struct inode *inode = page->mapping->host;
    if (reiserfs_file_data_log(inode)) {
	SetPageChecked(page);
	return __set_page_dirty_nobuffers(page);
    }
    return __set_page_dirty_buffers(page);
}

/*
 * Returns 1 if the page's buffers were dropped.  The page is locked.
 *
 * Takes j_dirty_buffers_lock to protect the b_assoc_buffers list_heads
 * in the buffers at page_buffers(page).
 *
 * even in -o notail mode, we can't be sure an old mount without -o notail
 * didn't create files with tails.
 */
static int reiserfs_releasepage(struct page *page, int unused_gfp_flags)
{
    struct inode *inode = page->mapping->host ;
    struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb) ;
    struct buffer_head *head ;
    struct buffer_head *bh ;
    int ret = 1 ;

    WARN_ON(PageChecked(page));
    spin_lock(&j->j_dirty_buffers_lock) ;
    head = page_buffers(page) ;
    bh = head ;
    do {
	if (bh->b_private) {
	    if (!buffer_dirty(bh) && !buffer_locked(bh)) {
		reiserfs_free_jh(bh);
	    } else {
		ret = 0 ;
		break ;
	    }
	}
	bh = bh->b_this_page ;
    } while (bh != head) ;
    if (ret)
	ret = try_to_free_buffers(page) ;
    spin_unlock(&j->j_dirty_buffers_lock) ;
    return ret ;
}

/* We thank Mingming Cao for helping us understand in great detail what
   to do in this section of the code. */
static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
		const struct iovec *iov, loff_t offset, unsigned long nr_segs)
{
    struct file *file = iocb->ki_filp;
    struct inode *inode = file->f_mapping->host;

    return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
			offset, nr_segs, reiserfs_get_blocks_direct_io, NULL);
}

int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) {
    struct inode *inode = dentry->d_inode ;
    int error ;
    unsigned int ia_valid = attr->ia_valid;
    reiserfs_write_lock(inode->i_sb);
    if (attr->ia_valid & ATTR_SIZE) {
	/* version 2 items will be caught by the s_maxbytes check
	** done for us in vmtruncate
	*/
	if (get_inode_item_key_version(inode) == KEY_FORMAT_3_5 &&
	    attr->ia_size > MAX_NON_LFS) {
	    error = -EFBIG ;
	    goto out;
	}
	/* fill in hole pointers in the expanding truncate case. */
        if (attr->ia_size > inode->i_size) {
	    error = generic_cont_expand(inode, attr->ia_size) ;
	    if (REISERFS_I(inode)->i_prealloc_count > 0) {
		int err;
		struct reiserfs_transaction_handle th ;
		/* we're changing at most 2 bitmaps, inode + super */
		err = journal_begin(&th, inode->i_sb, 4) ;
		if (!err) {
		    reiserfs_discard_prealloc (&th, inode);
		    err = journal_end(&th, inode->i_sb, 4) ;
		}
		if (err)
		    error = err;
	    }
	    if (error)
	        goto out;
	}
    }

    if ((((attr->ia_valid & ATTR_UID) && (attr->ia_uid & ~0xffff)) ||
	 ((attr->ia_valid & ATTR_GID) && (attr->ia_gid & ~0xffff))) &&
	(get_inode_sd_version (inode) == STAT_DATA_V1)) {
		/* stat data of format v3.5 has 16 bit uid and gid */
	    error = -EINVAL;
	    goto out;
	}

    error = inode_change_ok(inode, attr) ;
    if (!error) {
	if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
	    (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
                error = reiserfs_chown_xattrs (inode, attr);

                if (!error) {
		    struct reiserfs_transaction_handle th;
		    int jbegin_count = 2*(REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb)+REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb))+2;

		    /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
		    error = journal_begin(&th, inode->i_sb, jbegin_count);
 		    if (error)
 			goto out;
                    error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
		    if (error) {
			journal_end(&th, inode->i_sb, jbegin_count);
			goto out;
		    }
		    /* Update corresponding info in inode so that everything is in
		     * one transaction */
		    if (attr->ia_valid & ATTR_UID)
			inode->i_uid = attr->ia_uid;
		    if (attr->ia_valid & ATTR_GID)
			inode->i_gid = attr->ia_gid;
		    mark_inode_dirty(inode);
		    error = journal_end(&th, inode->i_sb, jbegin_count);
		}
        }
        if (!error)
            error = inode_setattr(inode, attr) ;
    }


    if (!error && reiserfs_posixacl (inode->i_sb)) {
        if (attr->ia_valid & ATTR_MODE)
            error = reiserfs_acl_chmod (inode);
    }

out:
    reiserfs_write_unlock(inode->i_sb);
    return error ;
}



struct address_space_operations reiserfs_address_space_operations = {
    .writepage = reiserfs_writepage,
    .readpage = reiserfs_readpage, 
    .readpages = reiserfs_readpages, 
    .releasepage = reiserfs_releasepage,
    .invalidatepage = reiserfs_invalidatepage,
    .sync_page = block_sync_page,
    .prepare_write = reiserfs_prepare_write,
    .commit_write = reiserfs_commit_write,
    .bmap = reiserfs_aop_bmap,
    .direct_IO = reiserfs_direct_IO,
    .set_page_dirty = reiserfs_set_page_dirty,
} ;
