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

#include <linux/time.h>
#include <linux/fs.h>
#include "reiserfs.h"
#include "acl.h"
#include "xattr.h"
#include <linux/exportfs.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <linux/buffer_head.h>
#include <linux/mpage.h>
#include <linux/writeback.h>
#include <linux/quotaops.h>
#include <linux/swap.h>
#include <linux/uio.h>
#include <linux/bio.h>

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

void reiserfs_evict_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;
	int err;

	if (!inode->i_nlink && !is_bad_inode(inode))
		dquot_initialize(inode);

	truncate_inode_pages_final(&inode->i_data);
	if (inode->i_nlink)
		goto no_delete;

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

		reiserfs_delete_xattrs(inode);

		reiserfs_write_lock(inode->i_sb);

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

		reiserfs_discard_prealloc(&th, inode);

		err = reiserfs_delete_object(&th, inode);

		/*
		 * 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
		 */
		if (!err) {
			int depth = reiserfs_write_unlock_nested(inode->i_sb);
			dquot_free_inode(inode);
			reiserfs_write_lock_nested(inode->i_sb, depth);
		}

		if (journal_end(&th))
			goto out;

		/*
		 * check return value from reiserfs_delete_object after
		 * ending the transaction
		 */
		if (err)
		    goto out;

		/*
		 * all items of file are deleted, so we can remove
		 * "save" link
		 * we can't do anything about an error here
		 */
		remove_save_link(inode, 0 /* not truncate */);
out:
		reiserfs_write_unlock(inode->i_sb);
	} else {
		/* no object items are in the tree */
		;
	}

	/* note this must go after the journal_end to prevent deadlock */
	clear_inode(inode);

	dquot_drop(inode);
	inode->i_blocks = 0;
	return;

no_delete:
	clear_inode(inode);
	dquot_drop(inode);
}

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_read_folio, 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 read_folio,
 * 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_write_begin 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, sector_t block)
{
	/* it is new file. */
	if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 ||
	    /* old file, but 'block' is inside of 2gb */
	    block < (1 << (31 - inode->i_sb->s_blocksize_bits)))
		return 1;

	return 0;
}

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

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

	pathrelse(path);

	/* we cannot restart while nested */
	if (th->t_refcount > 1) {
		return 0;
	}
	reiserfs_update_sd(th, inode);
	err = journal_end(th);
	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, sector_t 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;
	b_blocknr_t blocknr;
	char *p;
	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);

	result = search_for_position_by_key(inode->i_sb, &key, &path);
	if (result != POSITION_FOUND) {
		pathrelse(&path);
		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 = tp_item_head(&path);
	if (is_indirect_le_ih(ih)) {
		__le32 *ind_item = (__le32 *) ih_item_body(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);
		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);
		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_SIZE - 1);
	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
	 */
	p = (char *)kmap(bh_result->b_page);
	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, ih_item_body(bh, ih) + path.pos_in_item, chars);

		if (done)
			break;

		p += chars;

		/*
		 * 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
		 */
		if (PATH_LAST_POSITION(&path) != (B_NR_ITEMS(bh) - 1))
			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 = tp_item_head(&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_write_begin, 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_write_begin expects to
 * be able to do i/o on the buffers returned, unless an error value
 * is also returned.
 *
 * So, this allows __block_write_begin 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,
					 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 = i_blocksize(inode);

	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;

		reiserfs_write_lock(inode->i_sb);

		err = reiserfs_commit_for_inode(inode);
		REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;

		reiserfs_write_unlock(inode->i_sb);

		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_SIZE - 1);
	tail_end = (tail_start | (bh_result->b_size - 1)) + 1;

	index = tail_offset >> PAGE_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_mutex.
	 *
	 * 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_write_begin won't trigger a get_block in this case.
	 */
	fix_tail_page_for_writing(tail_page);
	retval = __reiserfs_write_begin(tail_page, tail_start,
				      tail_end - tail_start);
	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);
		put_page(tail_page);
	}
out:
	return retval;
}

static inline int _allocate_block(struct reiserfs_transaction_handle *th,
				  sector_t block,
				  struct inode *inode,
				  b_blocknr_t * allocated_block_nr,
				  struct treepath *path, int flags)
{
	BUG_ON(!th->t_trans_id);

#ifdef REISERFS_PREALLOCATE
	if (!(flags & GET_BLOCK_NO_IMUX)) {
		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 is (unsigned) 32 bit int*/
	b_blocknr_t allocated_block_nr = 0;
	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;

	reiserfs_write_lock(inode->i_sb);
	version = get_inode_item_key_version(inode);

	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 = tp_item_head(&path);
	item = tp_item_body(&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);

		/*
		 * 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
		 */
		if (repeat == NO_DISK_SPACE || repeat == QUOTA_EXCEEDED) {
			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, 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 */ );

			/*
			 * we are going to add 'block'-th block to the file.
			 * Use allocated block for that
			 */
			if (cpu_key_k_offset(&key) == 1) {
				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);
				/*
				 * retval == -ENOSPC, -EDQUOT or -EIO
				 * or -EEXIST
				 */
				goto failure;
			}
		} 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;

			/*
			 * direct item we just found fits into block we have
			 * to map. Convert it into unformatted node: use
			 * bh_result for the conversion
			 */
			if (tail_offset == cpu_key_k_offset(&key)) {
				set_block_dev_mapped(bh_result,
						     allocated_block_nr, inode);
				unbh = bh_result;
				done = 1;
			} else {
				/*
				 * we have to pad 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_error(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 read_folio, 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;
			/*
			 * We use this in case we need to allocate
			 * only one block which is a fastpath
			 */
			unp_t unf_single = 0;
			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
			 * (key type is unimportant)
			 */
			make_cpu_key(&tmp_key, inode,
				     le_key_k_offset(version,
						     &ih->ih_key) +
				     op_bytes_number(ih,
						     inode->i_sb->s_blocksize),
				     TYPE_INDIRECT, 3);

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

			if (blocks_needed == 1) {
				un = &unf_single;
			} else {
				un = kcalloc(min(blocks_needed, max_to_insert),
					     UNFM_P_SIZE, GFP_NOFS);
				if (!un) {
					un = &unf_single;
					blocks_needed = 1;
					max_to_insert = 0;
				}
			}
			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 kcalloc 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 and also release the write
		 * lock for others.
		 */
		reiserfs_cond_resched(inode->i_sb);

		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",
					 "%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 = tp_item_head(&path);
		item = tp_item_body(&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 void reiserfs_readahead(struct readahead_control *rac)
{
	mpage_readahead(rac, 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 treepath *path)
{
	struct buffer_head *bh;
	struct item_head *ih;
	__u32 rdev;

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

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

	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_init_xattr_rwsem(inode);

	if (stat_data_v1(ih)) {
		struct stat_data_v1 *sd =
		    (struct stat_data_v1 *)ih_item_body(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);
		set_nlink(inode, sd_v1_nlink(sd));
		i_uid_write(inode, sd_v1_uid(sd));
		i_gid_write(inode, 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);

		/*
		 * 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 sparse files. On-disk value will be only
		 * updated if file's inode will ever change
		 */
		if (inode->i_blocks > blocks) {
			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 *)ih_item_body(bh, ih);

		inode->i_mode = sd_v2_mode(sd);
		set_nlink(inode, sd_v2_nlink(sd));
		i_uid_write(inode, sd_v2_uid(sd));
		inode->i_size = sd_v2_size(sd);
		i_gid_write(inode, 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 initialise
		 * 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_nohighmem(inode);
		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;

	set_sd_v2_mode(sd_v2, inode->i_mode);
	set_sd_v2_nlink(sd_v2, inode->i_nlink);
	set_sd_v2_uid(sd_v2, i_uid_read(inode));
	set_sd_v2_size(sd_v2, size);
	set_sd_v2_gid(sd_v2, i_gid_read(inode));
	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);
	set_sd_v2_attrs(sd_v2, REISERFS_I(inode)->i_attrs);
}

/* 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, i_uid_read(inode));
	set_sd_v1_gid(sd_v1, i_gid_read(inode));
	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 treepath *path, struct inode *inode,
			     loff_t size)
{
	struct buffer_head *bh;
	struct item_head *ih;

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

	if (!is_statdata_le_ih(ih))
		reiserfs_panic(inode->i_sb, "vs-13065", "key %k, found item %h",
			       INODE_PKEY(inode), ih);

	/* path points to old stat data */
	if (stat_data_v1(ih)) {
		inode2sd_v1(ih_item_body(bh, ih), inode, size);
	} else {
		inode2sd(ih_item_body(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);

	/* key type is unimportant */
	make_cpu_key(&key, inode, SD_OFFSET, TYPE_STAT_DATA, 3);

	for (;;) {
		int pos;
		/* look for the object's stat data */
		retval = search_item(inode->i_sb, &key, &path);
		if (retval == IO_ERROR) {
			reiserfs_error(inode->i_sb, "vs-13050",
				       "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",
					 "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 = tp_item_head(&path);
		copy_item_head(&tmp_ih, ih);
		fs_gen = get_generation(inode->i_sb);
		reiserfs_prepare_for_journal(inode->i_sb, bh, 1);

		/* Stat_data item has been moved after scheduling. */
		if (fs_changed(fs_gen, inode->i_sb)
		    && item_moved(&tmp_ih, &path)) {
			reiserfs_restore_prepared_buffer(inode->i_sb, bh);
			continue;
		}
		break;
	}
	update_stat_data(&path, inode, size);
	journal_mark_dirty(th, 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
	 */
	_make_cpu_key(&key, KEY_FORMAT_3_5, dirino, inode->i_ino, 0, 0, 3);

	/* look for the object's stat data */
	retval = search_item(inode->i_sb, &key, &path_to_sd);
	if (retval == IO_ERROR) {
		reiserfs_error(inode->i_sb, "vs-13070",
			       "i/o failure occurred trying to find "
			       "stat data of %K", &key);
		reiserfs_make_bad_inode(inode);
		return;
	}

	/* a stale NFS handle can trigger this without it being an error */
	if (retval != ITEM_FOUND) {
		pathrelse(&path_to_sd);
		reiserfs_make_bad_inode(inode);
		clear_nlink(inode);
		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",
				 "dead inode read from disk %K. "
				 "This is likely to be race with knfsd. Ignore",
				 &key);
		reiserfs_make_bad_inode(inode);
	}

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

	/*
	 * Stat data v1 doesn't support ACLs.
	 */
	if (get_inode_sd_version(inode) == STAT_DATA_V1)
		cache_no_acl(inode);
}

/*
 * 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;
	int depth;

	args.objectid = key->on_disk_key.k_objectid;
	args.dirid = key->on_disk_key.k_dir_id;
	depth = reiserfs_write_unlock_nested(s);
	inode = iget5_locked(s, key->on_disk_key.k_objectid,
			     reiserfs_find_actor, reiserfs_init_locked_inode,
			     (void *)(&args));
	reiserfs_write_lock_nested(s, depth);
	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;
}

static struct dentry *reiserfs_get_dentry(struct super_block *sb,
	u32 objectid, u32 dir_id, u32 generation)

{
	struct cpu_key key;
	struct inode *inode;

	key.on_disk_key.k_objectid = objectid;
	key.on_disk_key.k_dir_id = dir_id;
	reiserfs_write_lock(sb);
	inode = reiserfs_iget(sb, &key);
	if (inode && !IS_ERR(inode) && generation != 0 &&
	    generation != inode->i_generation) {
		iput(inode);
		inode = NULL;
	}
	reiserfs_write_unlock(sb);

	return d_obtain_alias(inode);
}

struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
		int fh_len, int fh_type)
{
	/*
	 * 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 (fh_type > fh_len) {
		if (fh_type != 6 || fh_len != 5)
			reiserfs_warning(sb, "reiserfs-13077",
				"nfsd/reiserfs, fhtype=%d, len=%d - odd",
				fh_type, fh_len);
		fh_type = fh_len;
	}
	if (fh_len < 2)
		return NULL;

	return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
		(fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
}

struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
		int fh_len, int fh_type)
{
	if (fh_type > fh_len)
		fh_type = fh_len;
	if (fh_type < 4)
		return NULL;

	return reiserfs_get_dentry(sb,
		(fh_type >= 5) ? fid->raw[3] : fid->raw[2],
		(fh_type >= 5) ? fid->raw[4] : fid->raw[3],
		(fh_type == 6) ? fid->raw[5] : 0);
}

int reiserfs_encode_fh(struct inode *inode, __u32 * data, int *lenp,
		       struct inode *parent)
{
	int maxlen = *lenp;

	if (parent && (maxlen < 5)) {
		*lenp = 5;
		return FILEID_INVALID;
	} else if (maxlen < 3) {
		*lenp = 3;
		return FILEID_INVALID;
	}

	data[0] = inode->i_ino;
	data[1] = le32_to_cpu(INODE_PKEY(inode)->k_dir_id);
	data[2] = inode->i_generation;
	*lenp = 3;
	if (parent) {
		data[3] = parent->i_ino;
		data[4] = le32_to_cpu(INODE_PKEY(parent)->k_dir_id);
		*lenp = 5;
		if (maxlen >= 6) {
			data[5] = parent->i_generation;
			*lenp = 6;
		}
	}
	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, struct writeback_control *wbc)
{
	struct reiserfs_transaction_handle th;
	int jbegin_count = 1;

	if (sb_rdonly(inode->i_sb))
		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 (wbc->sync_mode == WB_SYNC_ALL && !(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);
		}
		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 treepath *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_error(sb, "vs-13080",
			       "i/o failure occurred creating new directory");
		return -EIO;
	}
	if (retval == ITEM_FOUND) {
		pathrelse(path);
		reiserfs_warning(sb, "vs-13070",
				 "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,
				struct item_head *ih,
				struct treepath *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_error(sb, "vs-13080",
			       "i/o failure occurred creating new symlink");
		return -EIO;
	}
	if (retval == ITEM_FOUND) {
		pathrelse(path);
		reiserfs_warning(sb, "vs-13080",
				 "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.
 *
 * @th: active transaction handle
 * @dir: parent directory for new inode
 * @mode: mode of new inode
 * @symname: symlink contents if inode is symlink
 * @isize: 0 for regular file, EMPTY_DIR_SIZE for dirs, strlen(symname) for
 *         symlinks
 * @inode: inode to be filled
 * @security: optional security context to associate with this inode
 */
int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
		       struct inode *dir, umode_t 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 reiserfs_security_handle *security)
{
	struct super_block *sb = dir->i_sb;
	struct reiserfs_iget_args args;
	INITIALIZE_PATH(path_to_key);
	struct cpu_key key;
	struct item_head ih;
	struct stat_data sd;
	int retval;
	int err;
	int depth;

	BUG_ON(!th->t_trans_id);

	depth = reiserfs_write_unlock_nested(sb);
	err = dquot_alloc_inode(inode);
	reiserfs_write_lock_nested(sb, depth);
	if (err)
		goto out_end_trans;
	if (!dir->i_nlink) {
		err = -EPERM;
		goto out_bad_inode;
	}

	/* 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;
	}
	args.objectid = inode->i_ino = le32_to_cpu(ih.ih_key.k_objectid);
	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);
	memcpy(INODE_PKEY(inode), &ih.ih_key, KEY_SIZE);
	args.dirid = le32_to_cpu(ih.ih_key.k_dir_id);

	depth = reiserfs_write_unlock_nested(inode->i_sb);
	err = insert_inode_locked4(inode, args.objectid,
			     reiserfs_find_actor, &args);
	reiserfs_write_lock_nested(inode->i_sb, depth);
	if (err) {
		err = -EINVAL;
		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 */
	set_nlink(inode, (S_ISDIR(mode) ? 2 : 1));

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

	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
	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_init_xattr_rwsem(inode);

	/* 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)) {
		/* i_uid or i_gid is too big to be stored in stat data v3.5 */
		if (i_uid_read(inode) & ~0xffff || i_gid_read(inode) & ~0xffff) {
			pathrelse(&path_to_key);
			err = -EINVAL;
			goto out_bad_inode;
		}
		inode2sd_v1(&sd, inode, inode->i_size);
	} else {
		inode2sd(&sd, inode, inode->i_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)
	 */
	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);
		goto out_inserted_sd;
	}

	/*
	 * Mark it private if we're creating the privroot
	 * or something under it.
	 */
	if (IS_PRIVATE(dir) || dentry == REISERFS_SB(sb)->priv_root) {
		inode->i_flags |= S_PRIVATE;
		inode->i_opflags &= ~IOP_XATTR;
	}

	if (reiserfs_posixacl(inode->i_sb)) {
		reiserfs_write_unlock(inode->i_sb);
		retval = reiserfs_inherit_default_acl(th, dir, dentry, inode);
		reiserfs_write_lock(inode->i_sb);
		if (retval) {
			err = retval;
			reiserfs_check_path(&path_to_key);
			journal_end(th);
			goto out_inserted_sd;
		}
	} else if (inode->i_sb->s_flags & SB_POSIXACL) {
		reiserfs_warning(inode->i_sb, "jdm-13090",
				 "ACLs aren't enabled in the fs, "
				 "but vfs thinks they are!");
	}

	if (security->name) {
		reiserfs_write_unlock(inode->i_sb);
		retval = reiserfs_security_write(th, inode, security);
		reiserfs_write_lock(inode->i_sb);
		if (retval) {
			err = retval;
			reiserfs_check_path(&path_to_key);
			retval = journal_end(th);
			if (retval)
				err = retval;
			goto out_inserted_sd;
		}
	}

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

	return 0;

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 */
	depth = reiserfs_write_unlock_nested(inode->i_sb);
	dquot_free_inode(inode);
	reiserfs_write_lock_nested(inode->i_sb, depth);

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

out_inserted_sd:
	clear_nlink(inode);
	th->t_trans_id = 0;	/* so the caller can't use this handle later */
	if (inode->i_state & I_NEW)
		unlock_new_inode(inode);
	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 *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 = (inode->i_size - 1) >> PAGE_SHIFT;
	unsigned long pos = 0;
	unsigned long start = 0;
	unsigned long blocksize = inode->i_sb->s_blocksize;
	unsigned long offset = (inode->i_size) & (PAGE_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(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_write_begin(page, start, offset - start,
				    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_error(inode->i_sb, "clm-6000",
			       "error reading block %lu", bh->b_blocknr);
		error = -EIO;
		goto unlock;
	}
	*bh_result = bh;
	*page_result = page;

out:
	return error;

unlock:
	unlock_page(page);
	put_page(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 *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 = inode->i_size & (PAGE_SIZE - 1);
	unsigned blocksize = inode->i_sb->s_blocksize;
	unsigned length;
	struct page *page = NULL;
	int error;
	struct buffer_head *bh = NULL;
	int err2;

	reiserfs_write_lock(inode->i_sb);

	if (inode->i_size > 0) {
		error = grab_tail_page(inode, &page, &bh);
		if (error) {
			/*
			 * -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_error(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, inode->i_sb,
			      JOURNAL_PER_BALANCE_CNT * 2 + 1);
	if (error)
		goto out;
	reiserfs_update_inode_transaction(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, inode, 1);
	err2 = reiserfs_do_truncate(&th, inode, page, update_timestamps);
	error = journal_end(&th);
	if (error)
		goto out;

	/* check reiserfs_do_truncate after ending the transaction */
	if (err2) {
		error = err2;
  		goto out;
	}
	
	if (update_timestamps) {
		error = remove_save_link(inode, 1 /* truncate */);
		if (error)
			goto out;
	}

	if (page) {
		length = offset & (blocksize - 1);
		/* if we are not on a block boundary */
		if (length) {
			length = blocksize - length;
			zero_user(page, offset, length);
			if (buffer_mapped(bh) && bh->b_blocknr != 0) {
				mark_buffer_dirty(bh);
			}
		}
		unlock_page(page);
		put_page(page);
	}

	reiserfs_write_unlock(inode->i_sb);

	return 0;
out:
	if (page) {
		unlock_page(page);
		put_page(page);
	}

	reiserfs_write_unlock(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 = ((loff_t)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 = tp_item_head(&path);
	item = tp_item_body(&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_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(ih_item_body(bh, ih) + pos_in_item, p + bytes_copied,
		       copy_size);

		journal_mark_dirty(&th, 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", inode->i_ino);
		retval = -EIO;
		goto out;
	}
	retval = 0;

out:
	pathrelse(&path);
	if (trans_running) {
		int err = journal_end(&th);
		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_IMUX
					    | 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_SHIFT;
	int error = 0;
	unsigned long block;
	sector_t last_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_SIZE / s->s_blocksize;
	th.t_trans_id = 0;

	/* no logging allowed when nonblocking or from PF_MEMALLOC */
	if (checked && (current->flags & PF_MEMALLOC)) {
		redirty_page_for_writepage(wbc, page);
		unlock_page(page);
		return 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) {
		unsigned last_offset;

		last_offset = inode->i_size & (PAGE_SIZE - 1);
		/* no file contents in this page */
		if (page->index >= end_index + 1 || !last_offset) {
			unlock_page(page);
			return 0;
		}
		zero_user_segment(page, last_offset, PAGE_SIZE);
	}
	bh = head;
	block = page->index << (PAGE_SHIFT - s->s_blocksize_bits);
	last_block = (i_size_read(inode) - 1) >> inode->i_blkbits;
	/* first map all the buffers, logging any direct items we find */
	do {
		if (block > last_block) {
			/*
			 * This can happen when the block size is less than
			 * the page size.  The corresponding bytes in the page
			 * were zero filled above
			 */
			clear_buffer_dirty(bh);
			set_buffer_uptodate(bh);
		} else if ((checked || buffer_dirty(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, 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) {
			lock_buffer(bh);
		} else {
			if (!trylock_buffer(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);
		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(REQ_OP_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(REQ_OP_WRITE, bh);
			nr++;
		}
		put_bh(bh);
		bh = next;
	} while (bh != head);
	goto done;
}

static int reiserfs_read_folio(struct file *f, struct folio *folio)
{
	return block_read_full_folio(folio, 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 void reiserfs_truncate_failed_write(struct inode *inode)
{
	truncate_inode_pages(inode->i_mapping, inode->i_size);
	reiserfs_truncate_file(inode, 0);
}

static int reiserfs_write_begin(struct file *file,
				struct address_space *mapping,
				loff_t pos, unsigned len,
				struct page **pagep, void **fsdata)
{
	struct inode *inode;
	struct page *page;
	pgoff_t index;
	int ret;
	int old_ref = 0;

 	inode = mapping->host;
	index = pos >> PAGE_SHIFT;
	page = grab_cache_page_write_begin(mapping, index);
	if (!page)
		return -ENOMEM;
	*pagep = page;

	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_write_begin(page, pos, len, 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;
			}
		}
	}
	if (ret) {
		unlock_page(page);
		put_page(page);
		/* Truncate allocated blocks */
		reiserfs_truncate_failed_write(inode);
	}
	return ret;
}

int __reiserfs_write_begin(struct page *page, unsigned from, unsigned len)
{
	struct inode *inode = page->mapping->host;
	int ret;
	int old_ref = 0;
	int depth;

	depth = reiserfs_write_unlock_nested(inode->i_sb);
	reiserfs_wait_on_write_block(inode->i_sb);
	reiserfs_write_lock_nested(inode->i_sb, depth);

	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_write_begin(page, from, len, 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_write_end(struct file *file, struct address_space *mapping,
			      loff_t pos, unsigned len, unsigned copied,
			      struct page *page, void *fsdata)
{
	struct inode *inode = page->mapping->host;
	int ret = 0;
	int update_sd = 0;
	struct reiserfs_transaction_handle *th;
	unsigned start;
	bool locked = false;

	reiserfs_wait_on_write_block(inode->i_sb);
	if (reiserfs_transaction_running(inode->i_sb))
		th = current->journal_info;
	else
		th = NULL;

	start = pos & (PAGE_SIZE - 1);
	if (unlikely(copied < len)) {
		if (!PageUptodate(page))
			copied = 0;

		page_zero_new_buffers(page, start + copied, start + len);
	}
	flush_dcache_page(page);

	reiserfs_commit_page(inode, page, start, start + copied);

	/*
	 * 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 + copied > inode->i_size) {
		struct reiserfs_transaction_handle myth;
		reiserfs_write_lock(inode->i_sb);
		locked = true;
		/*
		 * 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)
			goto journal_error;

		reiserfs_update_inode_transaction(inode);
		inode->i_size = pos + copied;
		/*
		 * this will just nest into our transaction.  It's important
		 * to use mark_inode_dirty so the inode gets pushed around on
		 * the dirty lists, and so that O_SYNC works as expected
		 */
		mark_inode_dirty(inode);
		reiserfs_update_sd(&myth, inode);
		update_sd = 1;
		ret = journal_end(&myth);
		if (ret)
			goto journal_error;
	}
	if (th) {
		if (!locked) {
			reiserfs_write_lock(inode->i_sb);
			locked = true;
		}
		if (!update_sd)
			mark_inode_dirty(inode);
		ret = reiserfs_end_persistent_transaction(th);
		if (ret)
			goto out;
	}

out:
	if (locked)
		reiserfs_write_unlock(inode->i_sb);
	unlock_page(page);
	put_page(page);

	if (pos + len > inode->i_size)
		reiserfs_truncate_failed_write(inode);

	return ret == 0 ? copied : ret;

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

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_SHIFT) + to;
	int ret = 0;
	int update_sd = 0;
	struct reiserfs_transaction_handle *th = NULL;
	int depth;

	depth = reiserfs_write_unlock_nested(inode->i_sb);
	reiserfs_wait_on_write_block(inode->i_sb);
	reiserfs_write_lock_nested(inode->i_sb, depth);

	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;
		/*
		 * 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)
			goto journal_error;

		reiserfs_update_inode_transaction(inode);
		inode->i_size = pos;
		/*
		 * this will just nest into our transaction.  It's important
		 * to use mark_inode_dirty so the inode gets pushed around
		 * on the dirty lists, and so that O_SYNC works as expected
		 */
		mark_inode_dirty(inode);
		reiserfs_update_sd(&myth, inode);
		update_sd = 1;
		ret = journal_end(&myth);
		if (ret)
			goto journal_error;
	}
	if (th) {
		if (!update_sd)
			mark_inode_dirty(inode);
		ret = reiserfs_end_persistent_transaction(th);
		if (ret)
			goto out;
	}

out:
	return ret;

journal_error:
	if (th) {
		if (!update_sd)
			reiserfs_update_sd(th, inode);
		ret = reiserfs_end_persistent_transaction(th);
	}

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

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

	lock_buffer(bh);
	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)) {
		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);
	unlock_buffer(bh);
	return ret;
}

/* clm -- taken from fs/buffer.c:block_invalidate_folio */
static void reiserfs_invalidate_folio(struct folio *folio, size_t offset,
				    size_t length)
{
	struct buffer_head *head, *bh, *next;
	struct inode *inode = folio->mapping->host;
	unsigned int curr_off = 0;
	unsigned int stop = offset + length;
	int partial_page = (offset || length < folio_size(folio));
	int ret = 1;

	BUG_ON(!folio_test_locked(folio));

	if (!partial_page)
		folio_clear_checked(folio);

	head = folio_buffers(folio);
	if (!head)
		goto out;

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

		if (next_off > stop)
			goto out;

		/*
		 * is this block fully invalidated?
		 */
		if (offset <= curr_off) {
			if (invalidate_folio_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 (!partial_page && ret) {
		ret = filemap_release_folio(folio, 0);
		/* maybe should BUG_ON(!ret); - neilb */
	}
out:
	return;
}

static bool reiserfs_dirty_folio(struct address_space *mapping,
		struct folio *folio)
{
	if (reiserfs_file_data_log(mapping->host)) {
		folio_set_checked(folio);
		return filemap_dirty_folio(mapping, folio);
	}
	return block_dirty_folio(mapping, folio);
}

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

	WARN_ON(folio_test_checked(folio));
	spin_lock(&j->j_dirty_buffers_lock);
	head = folio_buffers(folio);
	bh = head;
	do {
		if (bh->b_private) {
			if (!buffer_dirty(bh) && !buffer_locked(bh)) {
				reiserfs_free_jh(bh);
			} else {
				ret = false;
				break;
			}
		}
		bh = bh->b_this_page;
	} while (bh != head);
	if (ret)
		ret = try_to_free_buffers(folio);
	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(struct kiocb *iocb, struct iov_iter *iter)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file->f_mapping->host;
	size_t count = iov_iter_count(iter);
	ssize_t ret;

	ret = blockdev_direct_IO(iocb, inode, iter,
				 reiserfs_get_blocks_direct_io);

	/*
	 * In case of error extending write may have instantiated a few
	 * blocks outside i_size. Trim these off again.
	 */
	if (unlikely(iov_iter_rw(iter) == WRITE && ret < 0)) {
		loff_t isize = i_size_read(inode);
		loff_t end = iocb->ki_pos + count;

		if ((end > isize) && inode_newsize_ok(inode, isize) == 0) {
			truncate_setsize(inode, isize);
			reiserfs_vfs_truncate_file(inode);
		}
	}

	return ret;
}

int reiserfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
		     struct iattr *attr)
{
	struct inode *inode = d_inode(dentry);
	unsigned int ia_valid;
	int error;

	error = setattr_prepare(&init_user_ns, dentry, attr);
	if (error)
		return error;

	/* must be turned off for recursive notify_change calls */
	ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);

	if (is_quota_modification(mnt_userns, inode, attr)) {
		error = dquot_initialize(inode);
		if (error)
			return error;
	}
	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) {
			reiserfs_write_unlock(inode->i_sb);
			error = -EFBIG;
			goto out;
		}

		inode_dio_wait(inode);

		/* fill in hole pointers in the expanding truncate case. */
		if (attr->ia_size > inode->i_size) {
			loff_t pos = attr->ia_size;

			if ((pos & (inode->i_sb->s_blocksize - 1)) == 0)
				pos++;
			error = generic_cont_expand_simple(inode, pos);
			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);
				}
				if (err)
					error = err;
			}
			if (error) {
				reiserfs_write_unlock(inode->i_sb);
				goto out;
			}
			/*
			 * file size is changed, ctime and mtime are
			 * to be updated
			 */
			attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME);
		}
	}
	reiserfs_write_unlock(inode->i_sb);

	if ((((attr->ia_valid & ATTR_UID) && (from_kuid(&init_user_ns, attr->ia_uid) & ~0xffff)) ||
	     ((attr->ia_valid & ATTR_GID) && (from_kgid(&init_user_ns, 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;
	}

	if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) ||
	    (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) {
		struct reiserfs_transaction_handle th;
		int jbegin_count =
		    2 *
		    (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) +
		     REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) +
		    2;

		error = reiserfs_chown_xattrs(inode, attr);

		if (error)
			return error;

		/*
		 * (user+group)*(old+new) structure - we count quota
		 * info and , inode write (sb, inode)
		 */
		reiserfs_write_lock(inode->i_sb);
		error = journal_begin(&th, inode->i_sb, jbegin_count);
		reiserfs_write_unlock(inode->i_sb);
		if (error)
			goto out;
		error = dquot_transfer(mnt_userns, inode, attr);
		reiserfs_write_lock(inode->i_sb);
		if (error) {
			journal_end(&th);
			reiserfs_write_unlock(inode->i_sb);
			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);
		reiserfs_write_unlock(inode->i_sb);
		if (error)
			goto out;
	}

	if ((attr->ia_valid & ATTR_SIZE) &&
	    attr->ia_size != i_size_read(inode)) {
		error = inode_newsize_ok(inode, attr->ia_size);
		if (!error) {
			/*
			 * Could race against reiserfs_file_release
			 * if called from NFS, so take tailpack mutex.
			 */
			mutex_lock(&REISERFS_I(inode)->tailpack);
			truncate_setsize(inode, attr->ia_size);
			reiserfs_truncate_file(inode, 1);
			mutex_unlock(&REISERFS_I(inode)->tailpack);
		}
	}

	if (!error) {
		setattr_copy(&init_user_ns, inode, attr);
		mark_inode_dirty(inode);
	}

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

out:
	return error;
}

const struct address_space_operations reiserfs_address_space_operations = {
	.writepage = reiserfs_writepage,
	.read_folio = reiserfs_read_folio,
	.readahead = reiserfs_readahead,
	.release_folio = reiserfs_release_folio,
	.invalidate_folio = reiserfs_invalidate_folio,
	.write_begin = reiserfs_write_begin,
	.write_end = reiserfs_write_end,
	.bmap = reiserfs_aop_bmap,
	.direct_IO = reiserfs_direct_IO,
	.dirty_folio = reiserfs_dirty_folio,
};
