]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/reiserfs/file.c
Merge branch 'v28-range-hrtimers-for-linus-v2' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-omap-h63xx.git] / fs / reiserfs / file.c
index 2070aeee2a521f7c106ba3fd68601a99b6807532..33408417038c2c93c576534c8d946deaa66ef4e9 100644 (file)
@@ -153,608 +153,6 @@ static int reiserfs_sync_file(struct file *p_s_filp,
        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);
-       if (!allocated_blocks)
-               return -ENOMEM;
-
-       /* 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 = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
-                               pathrelse(&path);
-                               goto error_exit;
-                       }
-               } else {
-                       res = res == QUOTA_EXCEEDED ? -EDQUOT : -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 = kzalloc(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;
-                       }
-                       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)) {
-                                       inode->i_size = cpu_key_k_offset(&key) +
-                                               (to_paste << inode->i_blkbits);
-                                       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
-               mark_inode_dirty(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)
@@ -824,432 +222,6 @@ int reiserfs_commit_page(struct inode *inode, struct page *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);
-                       // this sets the proper flags for O_SYNC to trigger a commit
-                       mark_inode_dirty(inode);
-                       reiserfs_write_unlock(inode->i_sb);
-               } else {
-                       reiserfs_write_lock(inode->i_sb);
-                       reiserfs_update_inode_transaction(inode);
-                       mark_inode_dirty(inode);
-                       reiserfs_write_unlock(inode->i_sb);
-               }
-
-               sd_update = 1;
-       }
-       if (th->t_trans_id) {
-               reiserfs_write_lock(inode->i_sb);
-               if (!sd_update)
-                       mark_inode_dirty(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 */
-                       zero_user_page(prepared_pages[0], 0, from, KM_USER0);
-
-               if (to != PAGE_CACHE_SIZE)      /* Last page needs to be partially zeroed */
-                       zero_user_page(prepared_pages[num_pages-1], to,
-                                       PAGE_CACHE_SIZE - to, 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 */
-                                       zero_user_page(prepared_pages[0],
-                                                      block_start,
-                                                      from - block_start, 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 */
-                                       zero_user_page(prepared_pages[num_pages-1],
-                                                       to, block_end - to, 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.  
 
@@ -1284,14 +256,9 @@ static ssize_t reiserfs_file_write(struct file *file,     /* the file we are going t
                                                         * 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_path.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;
 
@@ -1311,212 +278,7 @@ static ssize_t reiserfs_file_write(struct file *file,    /* the file we are going t
                        count = MAX_NON_LFS - (unsigned long)*ppos;
        }
 
-       if (file->f_flags & O_DIRECT)
-               return do_sync_write(file, buf, count, ppos);
-
-       if (unlikely((ssize_t) count < 0))
-               return -EINVAL;
-
-       if (unlikely(!access_ok(VERIFY_READ, buf, count)))
-               return -EFAULT;
-
-       mutex_lock(&inode->i_mutex);    // 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_path.dentry);
-       if (res)
-               goto out;
-
-       file_update_time(file);
-
-       // 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. */
-               res = reiserfs_prepare_file_region_for_write(inode, pos,
-                                                            num_pages,
-                                                            write_bytes,
-                                                            prepared_pages);
-               if (res < 0) {
-                       reiserfs_release_claimed_blocks(inode->i_sb,
-                                                       num_pages <<
-                                                       (PAGE_CACHE_SHIFT -
-                                                        inode->i_blkbits));
-                       break;
-               }
-
-               blocks_to_allocate = res;
-
-               /* 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_nr(inode->i_mapping, num_pages);
-       }
-
-       /* 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 (likely(res >= 0) &&
-           (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))))
-               res = generic_osync_inode(inode, file->f_mapping,
-                                         OSYNC_METADATA | OSYNC_DATA);
-
-       mutex_unlock(&inode->i_mutex);
-       reiserfs_async_progress_wait(inode->i_sb);
-       return (already_written != 0) ? already_written : res;
-
-      out:
-       mutex_unlock(&inode->i_mutex);  // unlock the file on exit.
-       return res;
+       return do_sync_write(file, buf, count, ppos);
 }
 
 const struct file_operations reiserfs_file_operations = {
@@ -1534,6 +296,7 @@ const struct file_operations reiserfs_file_operations = {
        .aio_write = generic_file_aio_write,
        .splice_read = generic_file_splice_read,
        .splice_write = generic_file_splice_write,
+       .llseek = generic_file_llseek,
 };
 
 const struct inode_operations reiserfs_file_inode_operations = {