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

#include <linux/time.h>
#include <linux/reiserfs_fs.h>
#include <linux/reiserfs_acl.h>
#include <linux/reiserfs_xattr.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
#include <linux/writeback.h>
#include <linux/blkdev.h>
#include <linux/buffer_head.h>
#include <linux/quotaops.h>

/*
** We pack the tails of files on file close, not at the time they are written.
** This implies an unnecessary copy of the tail and an unnecessary indirect item
** insertion/balancing, for files that are written in one write.
** It avoids unnecessary tail packings (balances) for files that are written in
** multiple writes and are small enough to have tails.
** 
** file_release is called by the VFS layer when the file is closed.  If
** this is the last open file descriptor, and the file
** small enough to have a tail, and the tail is currently in an
** unformatted node, the tail is converted back into a direct item.
** 
** We use reiserfs_truncate_file to pack the tail, since it already has
** all the conditions coded.  
*/
static int reiserfs_file_release(struct inode *inode, struct file *filp)
{

	struct reiserfs_transaction_handle th;
	int err;
	int jbegin_failure = 0;

	if (!S_ISREG(inode->i_mode))
		BUG();

	/* fast out for when nothing needs to be done */
	if ((atomic_read(&inode->i_count) > 1 ||
	     !(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
	     !tail_has_to_be_packed(inode)) &&
	    REISERFS_I(inode)->i_prealloc_count <= 0) {
		return 0;
	}

	reiserfs_write_lock(inode->i_sb);
	down(&inode->i_sem);
	/* freeing preallocation only involves relogging blocks that
	 * are already in the current transaction.  preallocation gets
	 * freed at the end of each transaction, so it is impossible for
	 * us to log any additional blocks (including quota blocks)
	 */
	err = journal_begin(&th, inode->i_sb, 1);
	if (err) {
		/* uh oh, we can't allow the inode to go away while there
		 * is still preallocation blocks pending.  Try to join the
		 * aborted transaction
		 */
		jbegin_failure = err;
		err = journal_join_abort(&th, inode->i_sb, 1);

		if (err) {
			/* hmpf, our choices here aren't good.  We can pin the inode
			 * which will disallow unmount from every happening, we can
			 * do nothing, which will corrupt random memory on unmount,
			 * or we can forcibly remove the file from the preallocation
			 * list, which will leak blocks on disk.  Lets pin the inode
			 * and let the admin know what is going on.
			 */
			igrab(inode);
			reiserfs_warning(inode->i_sb,
					 "pinning inode %lu because the "
					 "preallocation can't be freed");
			goto out;
		}
	}
	reiserfs_update_inode_transaction(inode);

#ifdef REISERFS_PREALLOCATE
	reiserfs_discard_prealloc(&th, inode);
#endif
	err = journal_end(&th, inode->i_sb, 1);

	/* copy back the error code from journal_begin */
	if (!err)
		err = jbegin_failure;

	if (!err && atomic_read(&inode->i_count) <= 1 &&
	    (REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
	    tail_has_to_be_packed(inode)) {
		/* if regular file is released by last holder and it has been
		   appended (we append by unformatted node only) or its direct
		   item(s) had to be converted, then it may have to be
		   indirect2direct converted */
		err = reiserfs_truncate_file(inode, 0);
	}
      out:
	up(&inode->i_sem);
	reiserfs_write_unlock(inode->i_sb);
	return err;
}

static void reiserfs_vfs_truncate_file(struct inode *inode)
{
	reiserfs_truncate_file(inode, 1);
}

/* Sync a reiserfs file. */

/*
 * FIXME: sync_mapping_buffers() never has anything to sync.  Can
 * be removed...
 */

static int reiserfs_sync_file(struct file *p_s_filp,
			      struct dentry *p_s_dentry, int datasync)
{
	struct inode *p_s_inode = p_s_dentry->d_inode;
	int n_err;
	int barrier_done;

	if (!S_ISREG(p_s_inode->i_mode))
		BUG();
	n_err = sync_mapping_buffers(p_s_inode->i_mapping);
	reiserfs_write_lock(p_s_inode->i_sb);
	barrier_done = reiserfs_commit_for_inode(p_s_inode);
	reiserfs_write_unlock(p_s_inode->i_sb);
	if (barrier_done != 1)
		blkdev_issue_flush(p_s_inode->i_sb->s_bdev, NULL);
	if (barrier_done < 0)
		return barrier_done;
	return (n_err < 0) ? -EIO : 0;
}

/* I really do not want to play with memory shortage right now, so
   to simplify the code, we are not going to write more than this much pages at
   a time. This still should considerably improve performance compared to 4k
   at a time case. This is 32 pages of 4k size. */
#define REISERFS_WRITE_PAGES_AT_A_TIME (128 * 1024) / PAGE_CACHE_SIZE

/* Allocates blocks for a file to fulfil write request.
   Maps all unmapped but prepared pages from the list.
   Updates metadata with newly allocated blocknumbers as needed */
static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handle *th, struct inode *inode,	/* Inode we work with */
					       loff_t pos,	/* Writing position */
					       int num_pages,	/* number of pages write going
								   to touch */
					       int write_bytes,	/* amount of bytes to write */
					       struct page **prepared_pages,	/* array of
										   prepared pages
										 */
					       int blocks_to_allocate	/* Amount of blocks we
									   need to allocate to
									   fit the data into file
									 */
    )
{
	struct cpu_key key;	// cpu key of item that we are going to deal with
	struct item_head *ih;	// pointer to item head that we are going to deal with
	struct buffer_head *bh;	// Buffer head that contains items that we are going to deal with
	__le32 *item;		// pointer to item we are going to deal with
	INITIALIZE_PATH(path);	// path to item, that we are going to deal with.
	b_blocknr_t *allocated_blocks;	// Pointer to a place where allocated blocknumbers would be stored.
	reiserfs_blocknr_hint_t hint;	// hint structure for block allocator.
	size_t res;		// return value of various functions that we call.
	int curr_block;		// current block used to keep track of unmapped blocks.
	int i;			// loop counter
	int itempos;		// position in item
	unsigned int from = (pos & (PAGE_CACHE_SIZE - 1));	// writing position in
	// first page
	unsigned int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;	/* last modified byte offset in last page */
	__u64 hole_size;	// amount of blocks for a file hole, if it needed to be created.
	int modifying_this_item = 0;	// Flag for items traversal code to keep track
	// of the fact that we already prepared
	// current block for journal
	int will_prealloc = 0;
	RFALSE(!blocks_to_allocate,
	       "green-9004: tried to allocate zero blocks?");

	/* only preallocate if this is a small write */
	if (REISERFS_I(inode)->i_prealloc_count ||
	    (!(write_bytes & (inode->i_sb->s_blocksize - 1)) &&
	     blocks_to_allocate <
	     REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize))
		will_prealloc =
		    REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize;

	allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
				   sizeof(b_blocknr_t), GFP_NOFS);

	/* First we compose a key to point at the writing position, we want to do
	   that outside of any locking region. */
	make_cpu_key(&key, inode, pos + 1, TYPE_ANY, 3 /*key length */ );

	/* If we came here, it means we absolutely need to open a transaction,
	   since we need to allocate some blocks */
	reiserfs_write_lock(inode->i_sb);	// Journaling stuff and we need that.
	res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb));	// Wish I know if this number enough
	if (res)
		goto error_exit;
	reiserfs_update_inode_transaction(inode);

	/* Look for the in-tree position of our write, need path for block allocator */
	res = search_for_position_by_key(inode->i_sb, &key, &path);
	if (res == IO_ERROR) {
		res = -EIO;
		goto error_exit;
	}

	/* Allocate blocks */
	/* First fill in "hint" structure for block allocator */
	hint.th = th;		// transaction handle.
	hint.path = &path;	// Path, so that block allocator can determine packing locality or whatever it needs to determine.
	hint.inode = inode;	// Inode is needed by block allocator too.
	hint.search_start = 0;	// We have no hint on where to search free blocks for block allocator.
	hint.key = key.on_disk_key;	// on disk key of file.
	hint.block = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9);	// Number of disk blocks this file occupies already.
	hint.formatted_node = 0;	// We are allocating blocks for unformatted node.
	hint.preallocate = will_prealloc;

	/* Call block allocator to allocate blocks */
	res =
	    reiserfs_allocate_blocknrs(&hint, allocated_blocks,
				       blocks_to_allocate, blocks_to_allocate);
	if (res != CARRY_ON) {
		if (res == NO_DISK_SPACE) {
			/* We flush the transaction in case of no space. This way some
			   blocks might become free */
			SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
			res = restart_transaction(th, inode, &path);
			if (res)
				goto error_exit;

			/* We might have scheduled, so search again */
			res =
			    search_for_position_by_key(inode->i_sb, &key,
						       &path);
			if (res == IO_ERROR) {
				res = -EIO;
				goto error_exit;
			}

			/* update changed info for hint structure. */
			res =
			    reiserfs_allocate_blocknrs(&hint, allocated_blocks,
						       blocks_to_allocate,
						       blocks_to_allocate);
			if (res != CARRY_ON) {
				res = -ENOSPC;
				pathrelse(&path);
				goto error_exit;
			}
		} else {
			res = -ENOSPC;
			pathrelse(&path);
			goto error_exit;
		}
	}
#ifdef __BIG_ENDIAN
	// Too bad, I have not found any way to convert a given region from
	// cpu format to little endian format
	{
		int i;
		for (i = 0; i < blocks_to_allocate; i++)
			allocated_blocks[i] = cpu_to_le32(allocated_blocks[i]);
	}
#endif

	/* Blocks allocating well might have scheduled and tree might have changed,
	   let's search the tree again */
	/* find where in the tree our write should go */
	res = search_for_position_by_key(inode->i_sb, &key, &path);
	if (res == IO_ERROR) {
		res = -EIO;
		goto error_exit_free_blocks;
	}

	bh = get_last_bh(&path);	// Get a bufferhead for last element in path.
	ih = get_ih(&path);	// Get a pointer to last item head in path.
	item = get_item(&path);	// Get a pointer to last item in path

	/* Let's see what we have found */
	if (res != POSITION_FOUND) {	/* position not found, this means that we
					   might need to append file with holes
					   first */
		// Since we are writing past the file's end, we need to find out if
		// there is a hole that needs to be inserted before our writing
		// position, and how many blocks it is going to cover (we need to
		//  populate pointers to file blocks representing the hole with zeros)

		{
			int item_offset = 1;
			/*
			 * if ih is stat data, its offset is 0 and we don't want to
			 * add 1 to pos in the hole_size calculation
			 */
			if (is_statdata_le_ih(ih))
				item_offset = 0;
			hole_size = (pos + item_offset -
				     (le_key_k_offset
				      (get_inode_item_key_version(inode),
				       &(ih->ih_key)) + op_bytes_number(ih,
									inode->
									i_sb->
									s_blocksize)))
			    >> inode->i_sb->s_blocksize_bits;
		}

		if (hole_size > 0) {
			int to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize) / UNFM_P_SIZE);	// How much data to insert first time.
			/* area filled with zeroes, to supply as list of zero blocknumbers
			   We allocate it outside of loop just in case loop would spin for
			   several iterations. */
			char *zeros = kmalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC);	// We cannot insert more than MAX_ITEM_LEN bytes anyway.
			if (!zeros) {
				res = -ENOMEM;
				goto error_exit_free_blocks;
			}
			memset(zeros, 0, to_paste * UNFM_P_SIZE);
			do {
				to_paste =
				    min_t(__u64, hole_size,
					  MAX_ITEM_LEN(inode->i_sb->
						       s_blocksize) /
					  UNFM_P_SIZE);
				if (is_indirect_le_ih(ih)) {
					/* Ok, there is existing indirect item already. Need to append it */
					/* Calculate position past inserted item */
					make_cpu_key(&key, inode,
						     le_key_k_offset
						     (get_inode_item_key_version
						      (inode),
						      &(ih->ih_key)) +
						     op_bytes_number(ih,
								     inode->
								     i_sb->
								     s_blocksize),
						     TYPE_INDIRECT, 3);
					res =
					    reiserfs_paste_into_item(th, &path,
								     &key,
								     inode,
								     (char *)
								     zeros,
								     UNFM_P_SIZE
								     *
								     to_paste);
					if (res) {
						kfree(zeros);
						goto error_exit_free_blocks;
					}
				} else if (is_statdata_le_ih(ih)) {
					/* No existing item, create it */
					/* item head for new item */
					struct item_head ins_ih;

					/* create a key for our new item */
					make_cpu_key(&key, inode, 1,
						     TYPE_INDIRECT, 3);

					/* Create new item head for our new item */
					make_le_item_head(&ins_ih, &key,
							  key.version, 1,
							  TYPE_INDIRECT,
							  to_paste *
							  UNFM_P_SIZE,
							  0 /* free space */ );

					/* Find where such item should live in the tree */
					res =
					    search_item(inode->i_sb, &key,
							&path);
					if (res != ITEM_NOT_FOUND) {
						/* item should not exist, otherwise we have error */
						if (res != -ENOSPC) {
							reiserfs_warning(inode->
									 i_sb,
									 "green-9008: search_by_key (%K) returned %d",
									 &key,
									 res);
						}
						res = -EIO;
						kfree(zeros);
						goto error_exit_free_blocks;
					}
					res =
					    reiserfs_insert_item(th, &path,
								 &key, &ins_ih,
								 inode,
								 (char *)zeros);
				} else {
					reiserfs_panic(inode->i_sb,
						       "green-9011: Unexpected key type %K\n",
						       &key);
				}
				if (res) {
					kfree(zeros);
					goto error_exit_free_blocks;
				}
				/* Now we want to check if transaction is too full, and if it is
				   we restart it. This will also free the path. */
				if (journal_transaction_should_end
				    (th, th->t_blocks_allocated)) {
					res =
					    restart_transaction(th, inode,
								&path);
					if (res) {
						pathrelse(&path);
						kfree(zeros);
						goto error_exit;
					}
				}

				/* Well, need to recalculate path and stuff */
				set_cpu_key_k_offset(&key,
						     cpu_key_k_offset(&key) +
						     (to_paste << inode->
						      i_blkbits));
				res =
				    search_for_position_by_key(inode->i_sb,
							       &key, &path);
				if (res == IO_ERROR) {
					res = -EIO;
					kfree(zeros);
					goto error_exit_free_blocks;
				}
				bh = get_last_bh(&path);
				ih = get_ih(&path);
				item = get_item(&path);
				hole_size -= to_paste;
			} while (hole_size);
			kfree(zeros);
		}
	}
	// Go through existing indirect items first
	// replace all zeroes with blocknumbers from list
	// Note that if no corresponding item was found, by previous search,
	// it means there are no existing in-tree representation for file area
	// we are going to overwrite, so there is nothing to scan through for holes.
	for (curr_block = 0, itempos = path.pos_in_item;
	     curr_block < blocks_to_allocate && res == POSITION_FOUND;) {
	      retry:

		if (itempos >= ih_item_len(ih) / UNFM_P_SIZE) {
			/* We run out of data in this indirect item, let's look for another
			   one. */
			/* First if we are already modifying current item, log it */
			if (modifying_this_item) {
				journal_mark_dirty(th, inode->i_sb, bh);
				modifying_this_item = 0;
			}
			/* Then set the key to look for a new indirect item (offset of old
			   item is added to old item length */
			set_cpu_key_k_offset(&key,
					     le_key_k_offset
					     (get_inode_item_key_version(inode),
					      &(ih->ih_key)) +
					     op_bytes_number(ih,
							     inode->i_sb->
							     s_blocksize));
			/* Search ofor position of new key in the tree. */
			res =
			    search_for_position_by_key(inode->i_sb, &key,
						       &path);
			if (res == IO_ERROR) {
				res = -EIO;
				goto error_exit_free_blocks;
			}
			bh = get_last_bh(&path);
			ih = get_ih(&path);
			item = get_item(&path);
			itempos = path.pos_in_item;
			continue;	// loop to check all kinds of conditions and so on.
		}
		/* Ok, we have correct position in item now, so let's see if it is
		   representing file hole (blocknumber is zero) and fill it if needed */
		if (!item[itempos]) {
			/* Ok, a hole. Now we need to check if we already prepared this
			   block to be journaled */
			while (!modifying_this_item) {	// loop until succeed
				/* Well, this item is not journaled yet, so we must prepare
				   it for journal first, before we can change it */
				struct item_head tmp_ih;	// We copy item head of found item,
				// here to detect if fs changed under
				// us while we were preparing for
				// journal.
				int fs_gen;	// We store fs generation here to find if someone
				// changes fs under our feet

				copy_item_head(&tmp_ih, ih);	// Remember itemhead
				fs_gen = get_generation(inode->i_sb);	// remember fs generation
				reiserfs_prepare_for_journal(inode->i_sb, bh, 1);	// Prepare a buffer within which indirect item is stored for changing.
				if (fs_changed(fs_gen, inode->i_sb)
				    && item_moved(&tmp_ih, &path)) {
					// Sigh, fs was changed under us, we need to look for new
					// location of item we are working with

					/* unmark prepaerd area as journaled and search for it's
					   new position */
					reiserfs_restore_prepared_buffer(inode->
									 i_sb,
									 bh);
					res =
					    search_for_position_by_key(inode->
								       i_sb,
								       &key,
								       &path);
					if (res == IO_ERROR) {
						res = -EIO;
						goto error_exit_free_blocks;
					}
					bh = get_last_bh(&path);
					ih = get_ih(&path);
					item = get_item(&path);
					itempos = path.pos_in_item;
					goto retry;
				}
				modifying_this_item = 1;
			}
			item[itempos] = allocated_blocks[curr_block];	// Assign new block
			curr_block++;
		}
		itempos++;
	}

	if (modifying_this_item) {	// We need to log last-accessed block, if it
		// was modified, but not logged yet.
		journal_mark_dirty(th, inode->i_sb, bh);
	}

	if (curr_block < blocks_to_allocate) {
		// Oh, well need to append to indirect item, or to create indirect item
		// if there weren't any
		if (is_indirect_le_ih(ih)) {
			// Existing indirect item - append. First calculate key for append
			// position. We do not need to recalculate path as it should
			// already point to correct place.
			make_cpu_key(&key, inode,
				     le_key_k_offset(get_inode_item_key_version
						     (inode),
						     &(ih->ih_key)) +
				     op_bytes_number(ih,
						     inode->i_sb->s_blocksize),
				     TYPE_INDIRECT, 3);
			res =
			    reiserfs_paste_into_item(th, &path, &key, inode,
						     (char *)(allocated_blocks +
							      curr_block),
						     UNFM_P_SIZE *
						     (blocks_to_allocate -
						      curr_block));
			if (res) {
				goto error_exit_free_blocks;
			}
		} else if (is_statdata_le_ih(ih)) {
			// Last found item was statdata. That means we need to create indirect item.
			struct item_head ins_ih;	/* itemhead for new item */

			/* create a key for our new item */
			make_cpu_key(&key, inode, 1, TYPE_INDIRECT, 3);	// Position one,
			// because that's
			// where first
			// indirect item
			// begins
			/* Create new item head for our new item */
			make_le_item_head(&ins_ih, &key, key.version, 1,
					  TYPE_INDIRECT,
					  (blocks_to_allocate -
					   curr_block) * UNFM_P_SIZE,
					  0 /* free space */ );
			/* Find where such item should live in the tree */
			res = search_item(inode->i_sb, &key, &path);
			if (res != ITEM_NOT_FOUND) {
				/* Well, if we have found such item already, or some error
				   occured, we need to warn user and return error */
				if (res != -ENOSPC) {
					reiserfs_warning(inode->i_sb,
							 "green-9009: search_by_key (%K) "
							 "returned %d", &key,
							 res);
				}
				res = -EIO;
				goto error_exit_free_blocks;
			}
			/* Insert item into the tree with the data as its body */
			res =
			    reiserfs_insert_item(th, &path, &key, &ins_ih,
						 inode,
						 (char *)(allocated_blocks +
							  curr_block));
		} else {
			reiserfs_panic(inode->i_sb,
				       "green-9010: unexpected item type for key %K\n",
				       &key);
		}
	}
	// the caller is responsible for closing the transaction
	// unless we return an error, they are also responsible for logging
	// the inode.
	//
	pathrelse(&path);
	/*
	 * cleanup prellocation from previous writes
	 * if this is a partial block write
	 */
	if (write_bytes & (inode->i_sb->s_blocksize - 1))
		reiserfs_discard_prealloc(th, inode);
	reiserfs_write_unlock(inode->i_sb);

	// go through all the pages/buffers and map the buffers to newly allocated
	// blocks (so that system knows where to write these pages later).
	curr_block = 0;
	for (i = 0; i < num_pages; i++) {
		struct page *page = prepared_pages[i];	//current page
		struct buffer_head *head = page_buffers(page);	// first buffer for a page
		int block_start, block_end;	// in-page offsets for buffers.

		if (!page_buffers(page))
			reiserfs_panic(inode->i_sb,
				       "green-9005: No buffers for prepared page???");

		/* For each buffer in page */
		for (bh = head, block_start = 0; bh != head || !block_start;
		     block_start = block_end, bh = bh->b_this_page) {
			if (!bh)
				reiserfs_panic(inode->i_sb,
					       "green-9006: Allocated but absent buffer for a page?");
			block_end = block_start + inode->i_sb->s_blocksize;
			if (i == 0 && block_end <= from)
				/* if this buffer is before requested data to map, skip it */
				continue;
			if (i == num_pages - 1 && block_start >= to)
				/* If this buffer is after requested data to map, abort
				   processing of current page */
				break;

			if (!buffer_mapped(bh)) {	// Ok, unmapped buffer, need to map it
				map_bh(bh, inode->i_sb,
				       le32_to_cpu(allocated_blocks
						   [curr_block]));
				curr_block++;
				set_buffer_new(bh);
			}
		}
	}

	RFALSE(curr_block > blocks_to_allocate,
	       "green-9007: Used too many blocks? weird");

	kfree(allocated_blocks);
	return 0;

// Need to deal with transaction here.
      error_exit_free_blocks:
	pathrelse(&path);
	// free blocks
	for (i = 0; i < blocks_to_allocate; i++)
		reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]),
				    1);

      error_exit:
	if (th->t_trans_id) {
		int err;
		// update any changes we made to blk count
		reiserfs_update_sd(th, inode);
		err =
		    journal_end(th, inode->i_sb,
				JOURNAL_PER_BALANCE_CNT * 3 + 1 +
				2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb));
		if (err)
			res = err;
	}
	reiserfs_write_unlock(inode->i_sb);
	kfree(allocated_blocks);

	return res;
}

/* Unlock pages prepared by reiserfs_prepare_file_region_for_write */
static void reiserfs_unprepare_pages(struct page **prepared_pages,	/* list of locked pages */
				     size_t num_pages /* amount of pages */ )
{
	int i;			// loop counter

	for (i = 0; i < num_pages; i++) {
		struct page *page = prepared_pages[i];

		try_to_free_buffers(page);
		unlock_page(page);
		page_cache_release(page);
	}
}

/* This function will copy data from userspace to specified pages within
   supplied byte range */
static int reiserfs_copy_from_user_to_file_region(loff_t pos,	/* In-file position */
						  int num_pages,	/* Number of pages affected */
						  int write_bytes,	/* Amount of bytes to write */
						  struct page **prepared_pages,	/* pointer to 
										   array to
										   prepared pages
										 */
						  const char __user * buf	/* Pointer to user-supplied
										   data */
    )
{
	long page_fault = 0;	// status of copy_from_user.
	int i;			// loop counter.
	int offset;		// offset in page

	for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
	     i++, offset = 0) {
		size_t count = min_t(size_t, PAGE_CACHE_SIZE - offset, write_bytes);	// How much of bytes to write to this page
		struct page *page = prepared_pages[i];	// Current page we process.

		fault_in_pages_readable(buf, count);

		/* Copy data from userspace to the current page */
		kmap(page);
		page_fault = __copy_from_user(page_address(page) + offset, buf, count);	// Copy the data.
		/* Flush processor's dcache for this page */
		flush_dcache_page(page);
		kunmap(page);
		buf += count;
		write_bytes -= count;

		if (page_fault)
			break;	// Was there a fault? abort.
	}

	return page_fault ? -EFAULT : 0;
}

/* taken fs/buffer.c:__block_commit_write */
int reiserfs_commit_page(struct inode *inode, struct page *page,
			 unsigned from, unsigned to)
{
	unsigned block_start, block_end;
	int partial = 0;
	unsigned blocksize;
	struct buffer_head *bh, *head;
	unsigned long i_size_index = inode->i_size >> PAGE_CACHE_SHIFT;
	int new;
	int logit = reiserfs_file_data_log(inode);
	struct super_block *s = inode->i_sb;
	int bh_per_page = PAGE_CACHE_SIZE / s->s_blocksize;
	struct reiserfs_transaction_handle th;
	int ret = 0;

	th.t_trans_id = 0;
	blocksize = 1 << inode->i_blkbits;

	if (logit) {
		reiserfs_write_lock(s);
		ret = journal_begin(&th, s, bh_per_page + 1);
		if (ret)
			goto drop_write_lock;
		reiserfs_update_inode_transaction(inode);
	}
	for (bh = head = page_buffers(page), block_start = 0;
	     bh != head || !block_start;
	     block_start = block_end, bh = bh->b_this_page) {

		new = buffer_new(bh);
		clear_buffer_new(bh);
		block_end = block_start + blocksize;
		if (block_end <= from || block_start >= to) {
			if (!buffer_uptodate(bh))
				partial = 1;
		} else {
			set_buffer_uptodate(bh);
			if (logit) {
				reiserfs_prepare_for_journal(s, bh, 1);
				journal_mark_dirty(&th, s, bh);
			} else if (!buffer_dirty(bh)) {
				mark_buffer_dirty(bh);
				/* do data=ordered on any page past the end
				 * of file and any buffer marked BH_New.
				 */
				if (reiserfs_data_ordered(inode->i_sb) &&
				    (new || page->index >= i_size_index)) {
					reiserfs_add_ordered_list(inode, bh);
				}
			}
		}
	}
	if (logit) {
		ret = journal_end(&th, s, bh_per_page + 1);
	      drop_write_lock:
		reiserfs_write_unlock(s);
	}
	/*
	 * If this is a partial write which happened to make all buffers
	 * uptodate then we can optimize away a bogus readpage() for
	 * the next read(). Here we 'discover' whether the page went
	 * uptodate as a result of this (potentially partial) write.
	 */
	if (!partial)
		SetPageUptodate(page);
	return ret;
}

/* Submit pages for write. This was separated from actual file copying
   because we might want to allocate block numbers in-between.
   This function assumes that caller will adjust file size to correct value. */
static int reiserfs_submit_file_region_for_write(struct reiserfs_transaction_handle *th, struct inode *inode, loff_t pos,	/* Writing position offset */
						 size_t num_pages,	/* Number of pages to write */
						 size_t write_bytes,	/* number of bytes to write */
						 struct page **prepared_pages	/* list of pages */
    )
{
	int status;		// return status of block_commit_write.
	int retval = 0;		// Return value we are going to return.
	int i;			// loop counter
	int offset;		// Writing offset in page.
	int orig_write_bytes = write_bytes;
	int sd_update = 0;

	for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
	     i++, offset = 0) {
		int count = min_t(int, PAGE_CACHE_SIZE - offset, write_bytes);	// How much of bytes to write to this page
		struct page *page = prepared_pages[i];	// Current page we process.

		status =
		    reiserfs_commit_page(inode, page, offset, offset + count);
		if (status)
			retval = status;	// To not overcomplicate matters We are going to
		// submit all the pages even if there was error.
		// we only remember error status to report it on
		// exit.
		write_bytes -= count;
	}
	/* now that we've gotten all the ordered buffers marked dirty,
	 * we can safely update i_size and close any running transaction
	 */
	if (pos + orig_write_bytes > inode->i_size) {
		inode->i_size = pos + orig_write_bytes;	// Set new size
		/* If the file have grown so much that tail packing is no
		 * longer possible, reset "need to pack" flag */
		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;
		else 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;

		if (th->t_trans_id) {
			reiserfs_write_lock(inode->i_sb);
			reiserfs_update_sd(th, inode);	// And update on-disk metadata
			reiserfs_write_unlock(inode->i_sb);
		} else
			inode->i_sb->s_op->dirty_inode(inode);

		sd_update = 1;
	}
	if (th->t_trans_id) {
		reiserfs_write_lock(inode->i_sb);
		if (!sd_update)
			reiserfs_update_sd(th, inode);
		status = journal_end(th, th->t_super, th->t_blocks_allocated);
		if (status)
			retval = status;
		reiserfs_write_unlock(inode->i_sb);
	}
	th->t_trans_id = 0;

	/* 
	 * we have to unlock the pages after updating i_size, otherwise
	 * we race with writepage
	 */
	for (i = 0; i < num_pages; i++) {
		struct page *page = prepared_pages[i];
		unlock_page(page);
		mark_page_accessed(page);
		page_cache_release(page);
	}
	return retval;
}

/* Look if passed writing region is going to touch file's tail
   (if it is present). And if it is, convert the tail to unformatted node */
static int reiserfs_check_for_tail_and_convert(struct inode *inode,	/* inode to deal with */
					       loff_t pos,	/* Writing position */
					       int write_bytes	/* amount of bytes to write */
    )
{
	INITIALIZE_PATH(path);	// needed for search_for_position
	struct cpu_key key;	// Key that would represent last touched writing byte.
	struct item_head *ih;	// item header of found block;
	int res;		// Return value of various functions we call.
	int cont_expand_offset;	// We will put offset for generic_cont_expand here
	// This can be int just because tails are created
	// only for small files.

/* this embodies a dependency on a particular tail policy */
	if (inode->i_size >= inode->i_sb->s_blocksize * 4) {
		/* such a big files do not have tails, so we won't bother ourselves
		   to look for tails, simply return */
		return 0;
	}

	reiserfs_write_lock(inode->i_sb);
	/* find the item containing the last byte to be written, or if
	 * writing past the end of the file then the last item of the
	 * file (and then we check its type). */
	make_cpu_key(&key, inode, pos + write_bytes + 1, TYPE_ANY,
		     3 /*key length */ );
	res = search_for_position_by_key(inode->i_sb, &key, &path);
	if (res == IO_ERROR) {
		reiserfs_write_unlock(inode->i_sb);
		return -EIO;
	}
	ih = get_ih(&path);
	res = 0;
	if (is_direct_le_ih(ih)) {
		/* Ok, closest item is file tail (tails are stored in "direct"
		 * items), so we need to unpack it. */
		/* To not overcomplicate matters, we just call generic_cont_expand
		   which will in turn call other stuff and finally will boil down to
		   reiserfs_get_block() that would do necessary conversion. */
		cont_expand_offset =
		    le_key_k_offset(get_inode_item_key_version(inode),
				    &(ih->ih_key));
		pathrelse(&path);
		res = generic_cont_expand(inode, cont_expand_offset);
	} else
		pathrelse(&path);

	reiserfs_write_unlock(inode->i_sb);
	return res;
}

/* This function locks pages starting from @pos for @inode.
   @num_pages pages are locked and stored in
   @prepared_pages array. Also buffers are allocated for these pages.
   First and last page of the region is read if it is overwritten only
   partially. If last page did not exist before write (file hole or file
   append), it is zeroed, then. 
   Returns number of unallocated blocks that should be allocated to cover
   new file data.*/
static int reiserfs_prepare_file_region_for_write(struct inode *inode
						  /* Inode of the file */ ,
						  loff_t pos,	/* position in the file */
						  size_t num_pages,	/* number of pages to
									   prepare */
						  size_t write_bytes,	/* Amount of bytes to be
									   overwritten from
									   @pos */
						  struct page **prepared_pages	/* pointer to array
										   where to store
										   prepared pages */
    )
{
	int res = 0;		// Return values of different functions we call.
	unsigned long index = pos >> PAGE_CACHE_SHIFT;	// Offset in file in pages.
	int from = (pos & (PAGE_CACHE_SIZE - 1));	// Writing offset in first page
	int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;
	/* offset of last modified byte in last
	   page */
	struct address_space *mapping = inode->i_mapping;	// Pages are mapped here.
	int i;			// Simple counter
	int blocks = 0;		/* Return value (blocks that should be allocated) */
	struct buffer_head *bh, *head;	// Current bufferhead and first bufferhead
	// of a page.
	unsigned block_start, block_end;	// Starting and ending offsets of current
	// buffer in the page.
	struct buffer_head *wait[2], **wait_bh = wait;	// Buffers for page, if
	// Page appeared to be not up
	// to date. Note how we have
	// at most 2 buffers, this is
	// because we at most may
	// partially overwrite two
	// buffers for one page. One at                                                 // the beginning of write area
	// and one at the end.
	// Everything inthe middle gets                                                 // overwritten totally.

	struct cpu_key key;	// cpu key of item that we are going to deal with
	struct item_head *ih = NULL;	// pointer to item head that we are going to deal with
	struct buffer_head *itembuf = NULL;	// Buffer head that contains items that we are going to deal with
	INITIALIZE_PATH(path);	// path to item, that we are going to deal with.
	__le32 *item = NULL;	// pointer to item we are going to deal with
	int item_pos = -1;	/* Position in indirect item */

	if (num_pages < 1) {
		reiserfs_warning(inode->i_sb,
				 "green-9001: reiserfs_prepare_file_region_for_write "
				 "called with zero number of pages to process");
		return -EFAULT;
	}

	/* We have 2 loops for pages. In first loop we grab and lock the pages, so
	   that nobody would touch these until we release the pages. Then
	   we'd start to deal with mapping buffers to blocks. */
	for (i = 0; i < num_pages; i++) {
		prepared_pages[i] = grab_cache_page(mapping, index + i);	// locks the page
		if (!prepared_pages[i]) {
			res = -ENOMEM;
			goto failed_page_grabbing;
		}
		if (!page_has_buffers(prepared_pages[i]))
			create_empty_buffers(prepared_pages[i],
					     inode->i_sb->s_blocksize, 0);
	}

	/* Let's count amount of blocks for a case where all the blocks
	   overwritten are new (we will substract already allocated blocks later) */
	if (num_pages > 2)
		/* These are full-overwritten pages so we count all the blocks in
		   these pages are counted as needed to be allocated */
		blocks =
		    (num_pages - 2) << (PAGE_CACHE_SHIFT - inode->i_blkbits);

	/* count blocks needed for first page (possibly partially written) */
	blocks += ((PAGE_CACHE_SIZE - from) >> inode->i_blkbits) + !!(from & (inode->i_sb->s_blocksize - 1));	/* roundup */

	/* Now we account for last page. If last page == first page (we
	   overwrite only one page), we substract all the blocks past the
	   last writing position in a page out of already calculated number
	   of blocks */
	blocks += ((num_pages > 1) << (PAGE_CACHE_SHIFT - inode->i_blkbits)) -
	    ((PAGE_CACHE_SIZE - to) >> inode->i_blkbits);
	/* Note how we do not roundup here since partial blocks still
	   should be allocated */

	/* Now if all the write area lies past the file end, no point in
	   maping blocks, since there is none, so we just zero out remaining
	   parts of first and last pages in write area (if needed) */
	if ((pos & ~((loff_t) PAGE_CACHE_SIZE - 1)) > inode->i_size) {
		if (from != 0) {	/* First page needs to be partially zeroed */
			char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0);
			memset(kaddr, 0, from);
			kunmap_atomic(kaddr, KM_USER0);
		}
		if (to != PAGE_CACHE_SIZE) {	/* Last page needs to be partially zeroed */
			char *kaddr =
			    kmap_atomic(prepared_pages[num_pages - 1],
					KM_USER0);
			memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
			kunmap_atomic(kaddr, KM_USER0);
		}

		/* Since all blocks are new - use already calculated value */
		return blocks;
	}

	/* Well, since we write somewhere into the middle of a file, there is
	   possibility we are writing over some already allocated blocks, so
	   let's map these blocks and substract number of such blocks out of blocks
	   we need to allocate (calculated above) */
	/* Mask write position to start on blocksize, we do it out of the
	   loop for performance reasons */
	pos &= ~((loff_t) inode->i_sb->s_blocksize - 1);
	/* Set cpu key to the starting position in a file (on left block boundary) */
	make_cpu_key(&key, inode,
		     1 + ((pos) & ~((loff_t) inode->i_sb->s_blocksize - 1)),
		     TYPE_ANY, 3 /*key length */ );

	reiserfs_write_lock(inode->i_sb);	// We need that for at least search_by_key()
	for (i = 0; i < num_pages; i++) {

		head = page_buffers(prepared_pages[i]);
		/* For each buffer in the page */
		for (bh = head, block_start = 0; bh != head || !block_start;
		     block_start = block_end, bh = bh->b_this_page) {
			if (!bh)
				reiserfs_panic(inode->i_sb,
					       "green-9002: Allocated but absent buffer for a page?");
			/* Find where this buffer ends */
			block_end = block_start + inode->i_sb->s_blocksize;
			if (i == 0 && block_end <= from)
				/* if this buffer is before requested data to map, skip it */
				continue;

			if (i == num_pages - 1 && block_start >= to) {
				/* If this buffer is after requested data to map, abort
				   processing of current page */
				break;
			}

			if (buffer_mapped(bh) && bh->b_blocknr != 0) {
				/* This is optimisation for a case where buffer is mapped
				   and have blocknumber assigned. In case significant amount
				   of such buffers are present, we may avoid some amount
				   of search_by_key calls.
				   Probably it would be possible to move parts of this code
				   out of BKL, but I afraid that would overcomplicate code
				   without any noticeable benefit.
				 */
				item_pos++;
				/* Update the key */
				set_cpu_key_k_offset(&key,
						     cpu_key_k_offset(&key) +
						     inode->i_sb->s_blocksize);
				blocks--;	// Decrease the amount of blocks that need to be
				// allocated
				continue;	// Go to the next buffer
			}

			if (!itembuf ||	/* if first iteration */
			    item_pos >= ih_item_len(ih) / UNFM_P_SIZE) {	/* or if we progressed past the
										   current unformatted_item */
				/* Try to find next item */
				res =
				    search_for_position_by_key(inode->i_sb,
							       &key, &path);
				/* Abort if no more items */
				if (res != POSITION_FOUND) {
					/* make sure later loops don't use this item */
					itembuf = NULL;
					item = NULL;
					break;
				}

				/* Update information about current indirect item */
				itembuf = get_last_bh(&path);
				ih = get_ih(&path);
				item = get_item(&path);
				item_pos = path.pos_in_item;

				RFALSE(!is_indirect_le_ih(ih),
				       "green-9003: indirect item expected");
			}

			/* See if there is some block associated with the file
			   at that position, map the buffer to this block */
			if (get_block_num(item, item_pos)) {
				map_bh(bh, inode->i_sb,
				       get_block_num(item, item_pos));
				blocks--;	// Decrease the amount of blocks that need to be
				// allocated
			}
			item_pos++;
			/* Update the key */
			set_cpu_key_k_offset(&key,
					     cpu_key_k_offset(&key) +
					     inode->i_sb->s_blocksize);
		}
	}
	pathrelse(&path);	// Free the path
	reiserfs_write_unlock(inode->i_sb);

	/* Now zero out unmappend buffers for the first and last pages of
	   write area or issue read requests if page is mapped. */
	/* First page, see if it is not uptodate */
	if (!PageUptodate(prepared_pages[0])) {
		head = page_buffers(prepared_pages[0]);

		/* For each buffer in page */
		for (bh = head, block_start = 0; bh != head || !block_start;
		     block_start = block_end, bh = bh->b_this_page) {

			if (!bh)
				reiserfs_panic(inode->i_sb,
					       "green-9002: Allocated but absent buffer for a page?");
			/* Find where this buffer ends */
			block_end = block_start + inode->i_sb->s_blocksize;
			if (block_end <= from)
				/* if this buffer is before requested data to map, skip it */
				continue;
			if (block_start < from) {	/* Aha, our partial buffer */
				if (buffer_mapped(bh)) {	/* If it is mapped, we need to
								   issue READ request for it to
								   not loose data */
					ll_rw_block(READ, 1, &bh);
					*wait_bh++ = bh;
				} else {	/* Not mapped, zero it */
					char *kaddr =
					    kmap_atomic(prepared_pages[0],
							KM_USER0);
					memset(kaddr + block_start, 0,
					       from - block_start);
					kunmap_atomic(kaddr, KM_USER0);
					set_buffer_uptodate(bh);
				}
			}
		}
	}

	/* Last page, see if it is not uptodate, or if the last page is past the end of the file. */
	if (!PageUptodate(prepared_pages[num_pages - 1]) ||
	    ((pos + write_bytes) >> PAGE_CACHE_SHIFT) >
	    (inode->i_size >> PAGE_CACHE_SHIFT)) {
		head = page_buffers(prepared_pages[num_pages - 1]);

		/* for each buffer in page */
		for (bh = head, block_start = 0; bh != head || !block_start;
		     block_start = block_end, bh = bh->b_this_page) {

			if (!bh)
				reiserfs_panic(inode->i_sb,
					       "green-9002: Allocated but absent buffer for a page?");
			/* Find where this buffer ends */
			block_end = block_start + inode->i_sb->s_blocksize;
			if (block_start >= to)
				/* if this buffer is after requested data to map, skip it */
				break;
			if (block_end > to) {	/* Aha, our partial buffer */
				if (buffer_mapped(bh)) {	/* If it is mapped, we need to
								   issue READ request for it to
								   not loose data */
					ll_rw_block(READ, 1, &bh);
					*wait_bh++ = bh;
				} else {	/* Not mapped, zero it */
					char *kaddr =
					    kmap_atomic(prepared_pages
							[num_pages - 1],
							KM_USER0);
					memset(kaddr + to, 0, block_end - to);
					kunmap_atomic(kaddr, KM_USER0);
					set_buffer_uptodate(bh);
				}
			}
		}
	}

	/* Wait for read requests we made to happen, if necessary */
	while (wait_bh > wait) {
		wait_on_buffer(*--wait_bh);
		if (!buffer_uptodate(*wait_bh)) {
			res = -EIO;
			goto failed_read;
		}
	}

	return blocks;
      failed_page_grabbing:
	num_pages = i;
      failed_read:
	reiserfs_unprepare_pages(prepared_pages, num_pages);
	return res;
}

/* Write @count bytes at position @ppos in a file indicated by @file
   from the buffer @buf.  

   generic_file_write() is only appropriate for filesystems that are not seeking to optimize performance and want
   something simple that works.  It is not for serious use by general purpose filesystems, excepting the one that it was
   written for (ext2/3).  This is for several reasons:

   * It has no understanding of any filesystem specific optimizations.

   * It enters the filesystem repeatedly for each page that is written.

   * It depends on reiserfs_get_block() function which if implemented by reiserfs performs costly search_by_key
   * operation for each page it is supplied with. By contrast reiserfs_file_write() feeds as much as possible at a time
   * to reiserfs which allows for fewer tree traversals.

   * Each indirect pointer insertion takes a lot of cpu, because it involves memory moves inside of blocks.

   * Asking the block allocation code for blocks one at a time is slightly less efficient.

   All of these reasons for not using only generic file write were understood back when reiserfs was first miscoded to
   use it, but we were in a hurry to make code freeze, and so it couldn't be revised then.  This new code should make
   things right finally.

   Future Features: providing search_by_key with hints.

*/
static ssize_t reiserfs_file_write(struct file *file,	/* the file we are going to write into */
				   const char __user * buf,	/*  pointer to user supplied data
								   (in userspace) */
				   size_t count,	/* amount of bytes to write */
				   loff_t * ppos	/* pointer to position in file that we start writing at. Should be updated to
							 * new current position before returning. */
				   )
{
	size_t already_written = 0;	// Number of bytes already written to the file.
	loff_t pos;		// Current position in the file.
	ssize_t res;		// return value of various functions that we call.
	int err = 0;
	struct inode *inode = file->f_dentry->d_inode;	// Inode of the file that we are writing to.
	/* To simplify coding at this time, we store
	   locked pages in array for now */
	struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
	struct reiserfs_transaction_handle th;
	th.t_trans_id = 0;

	if (file->f_flags & O_DIRECT) {	// Direct IO needs treatment
		ssize_t result, after_file_end = 0;
		if ((*ppos + count >= inode->i_size)
		    || (file->f_flags & O_APPEND)) {
			/* If we are appending a file, we need to put this savelink in here.
			   If we will crash while doing direct io, finish_unfinished will
			   cut the garbage from the file end. */
			reiserfs_write_lock(inode->i_sb);
			err =
			    journal_begin(&th, inode->i_sb,
					  JOURNAL_PER_BALANCE_CNT);
			if (err) {
				reiserfs_write_unlock(inode->i_sb);
				return err;
			}
			reiserfs_update_inode_transaction(inode);
			add_save_link(&th, inode, 1 /* Truncate */ );
			after_file_end = 1;
			err =
			    journal_end(&th, inode->i_sb,
					JOURNAL_PER_BALANCE_CNT);
			reiserfs_write_unlock(inode->i_sb);
			if (err)
				return err;
		}
		result = generic_file_write(file, buf, count, ppos);

		if (after_file_end) {	/* Now update i_size and remove the savelink */
			struct reiserfs_transaction_handle th;
			reiserfs_write_lock(inode->i_sb);
			err = journal_begin(&th, inode->i_sb, 1);
			if (err) {
				reiserfs_write_unlock(inode->i_sb);
				return err;
			}
			reiserfs_update_inode_transaction(inode);
			reiserfs_update_sd(&th, inode);
			err = journal_end(&th, inode->i_sb, 1);
			if (err) {
				reiserfs_write_unlock(inode->i_sb);
				return err;
			}
			err = remove_save_link(inode, 1 /* truncate */ );
			reiserfs_write_unlock(inode->i_sb);
			if (err)
				return err;
		}

		return result;
	}

	if (unlikely((ssize_t) count < 0))
		return -EINVAL;

	if (unlikely(!access_ok(VERIFY_READ, buf, count)))
		return -EFAULT;

	down(&inode->i_sem);	// locks the entire file for just us

	pos = *ppos;

	/* Check if we can write to specified region of file, file
	   is not overly big and this kind of stuff. Adjust pos and
	   count, if needed */
	res = generic_write_checks(file, &pos, &count, 0);
	if (res)
		goto out;

	if (count == 0)
		goto out;

	res = remove_suid(file->f_dentry);
	if (res)
		goto out;

	inode_update_time(inode, 1);	/* Both mtime and ctime */

	// Ok, we are done with all the checks.

	// Now we should start real work

	/* If we are going to write past the file's packed tail or if we are going
	   to overwrite part of the tail, we need that tail to be converted into
	   unformatted node */
	res = reiserfs_check_for_tail_and_convert(inode, pos, count);
	if (res)
		goto out;

	while (count > 0) {
		/* This is the main loop in which we running until some error occures
		   or until we write all of the data. */
		size_t num_pages;	/* amount of pages we are going to write this iteration */
		size_t write_bytes;	/* amount of bytes to write during this iteration */
		size_t blocks_to_allocate;	/* how much blocks we need to allocate for this iteration */

		/*  (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos */
		num_pages = !!((pos + count) & (PAGE_CACHE_SIZE - 1)) +	/* round up partial
									   pages */
		    ((count +
		      (pos & (PAGE_CACHE_SIZE - 1))) >> PAGE_CACHE_SHIFT);
		/* convert size to amount of
		   pages */
		reiserfs_write_lock(inode->i_sb);
		if (num_pages > REISERFS_WRITE_PAGES_AT_A_TIME
		    || num_pages > reiserfs_can_fit_pages(inode->i_sb)) {
			/* If we were asked to write more data than we want to or if there
			   is not that much space, then we shorten amount of data to write
			   for this iteration. */
			num_pages =
			    min_t(size_t, REISERFS_WRITE_PAGES_AT_A_TIME,
				  reiserfs_can_fit_pages(inode->i_sb));
			/* Also we should not forget to set size in bytes accordingly */
			write_bytes = (num_pages << PAGE_CACHE_SHIFT) -
			    (pos & (PAGE_CACHE_SIZE - 1));
			/* If position is not on the
			   start of the page, we need
			   to substract the offset
			   within page */
		} else
			write_bytes = count;

		/* reserve the blocks to be allocated later, so that later on
		   we still have the space to write the blocks to */
		reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
						      num_pages <<
						      (PAGE_CACHE_SHIFT -
						       inode->i_blkbits));
		reiserfs_write_unlock(inode->i_sb);

		if (!num_pages) {	/* If we do not have enough space even for a single page... */
			if (pos >
			    inode->i_size + inode->i_sb->s_blocksize -
			    (pos & (inode->i_sb->s_blocksize - 1))) {
				res = -ENOSPC;
				break;	// In case we are writing past the end of the last file block, break.
			}
			// Otherwise we are possibly overwriting the file, so
			// let's set write size to be equal or less than blocksize.
			// This way we get it correctly for file holes.
			// But overwriting files on absolutelly full volumes would not
			// be very efficient. Well, people are not supposed to fill
			// 100% of disk space anyway.
			write_bytes =
			    min_t(size_t, count,
				  inode->i_sb->s_blocksize -
				  (pos & (inode->i_sb->s_blocksize - 1)));
			num_pages = 1;
			// No blocks were claimed before, so do it now.
			reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
							      1 <<
							      (PAGE_CACHE_SHIFT
							       -
							       inode->
							       i_blkbits));
		}

		/* Prepare for writing into the region, read in all the
		   partially overwritten pages, if needed. And lock the pages,
		   so that nobody else can access these until we are done.
		   We get number of actual blocks needed as a result. */
		blocks_to_allocate =
		    reiserfs_prepare_file_region_for_write(inode, pos,
							   num_pages,
							   write_bytes,
							   prepared_pages);
		if (blocks_to_allocate < 0) {
			res = blocks_to_allocate;
			reiserfs_release_claimed_blocks(inode->i_sb,
							num_pages <<
							(PAGE_CACHE_SHIFT -
							 inode->i_blkbits));
			break;
		}

		/* First we correct our estimate of how many blocks we need */
		reiserfs_release_claimed_blocks(inode->i_sb,
						(num_pages <<
						 (PAGE_CACHE_SHIFT -
						  inode->i_sb->
						  s_blocksize_bits)) -
						blocks_to_allocate);

		if (blocks_to_allocate > 0) {	/*We only allocate blocks if we need to */
			/* Fill in all the possible holes and append the file if needed */
			res =
			    reiserfs_allocate_blocks_for_region(&th, inode, pos,
								num_pages,
								write_bytes,
								prepared_pages,
								blocks_to_allocate);
		}

		/* well, we have allocated the blocks, so it is time to free
		   the reservation we made earlier. */
		reiserfs_release_claimed_blocks(inode->i_sb,
						blocks_to_allocate);
		if (res) {
			reiserfs_unprepare_pages(prepared_pages, num_pages);
			break;
		}

/* NOTE that allocating blocks and filling blocks can be done in reverse order
   and probably we would do that just to get rid of garbage in files after a
   crash */

		/* Copy data from user-supplied buffer to file's pages */
		res =
		    reiserfs_copy_from_user_to_file_region(pos, num_pages,
							   write_bytes,
							   prepared_pages, buf);
		if (res) {
			reiserfs_unprepare_pages(prepared_pages, num_pages);
			break;
		}

		/* Send the pages to disk and unlock them. */
		res =
		    reiserfs_submit_file_region_for_write(&th, inode, pos,
							  num_pages,
							  write_bytes,
							  prepared_pages);
		if (res)
			break;

		already_written += write_bytes;
		buf += write_bytes;
		*ppos = pos += write_bytes;
		count -= write_bytes;
		balance_dirty_pages_ratelimited(inode->i_mapping);
	}

	/* this is only true on error */
	if (th.t_trans_id) {
		reiserfs_write_lock(inode->i_sb);
		err = journal_end(&th, th.t_super, th.t_blocks_allocated);
		reiserfs_write_unlock(inode->i_sb);
		if (err) {
			res = err;
			goto out;
		}
	}

	if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
		res =
		    generic_osync_inode(inode, file->f_mapping,
					OSYNC_METADATA | OSYNC_DATA);

	up(&inode->i_sem);
	reiserfs_async_progress_wait(inode->i_sb);
	return (already_written != 0) ? already_written : res;

      out:
	up(&inode->i_sem);	// unlock the file on exit.
	return res;
}

static ssize_t reiserfs_aio_write(struct kiocb *iocb, const char __user * buf,
				  size_t count, loff_t pos)
{
	return generic_file_aio_write(iocb, buf, count, pos);
}

struct file_operations reiserfs_file_operations = {
	.read = generic_file_read,
	.write = reiserfs_file_write,
	.ioctl = reiserfs_ioctl,
	.mmap = generic_file_mmap,
	.release = reiserfs_file_release,
	.fsync = reiserfs_sync_file,
	.sendfile = generic_file_sendfile,
	.aio_read = generic_file_aio_read,
	.aio_write = reiserfs_aio_write,
};

struct inode_operations reiserfs_file_inode_operations = {
	.truncate = reiserfs_vfs_truncate_file,
	.setattr = reiserfs_setattr,
	.setxattr = reiserfs_setxattr,
	.getxattr = reiserfs_getxattr,
	.listxattr = reiserfs_listxattr,
	.removexattr = reiserfs_removexattr,
	.permission = reiserfs_permission,
};
