/*
 * 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
    __u32 * 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); // 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);
        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.
    __u32 * 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 */
	    res = -ENOSPC;  /* single page, return -ENOSPC */
	    if ( pos > (inode->i_size & (inode->i_sb->s_blocksize-1)))
		break; // In case we are writing past the file end, 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,
};


