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


