+static int reiserfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = page->mapping->host;
+ int ret = 0;
+ int update_sd = 0;
+ struct reiserfs_transaction_handle *th;
+ unsigned start;
+ int lock_depth = 0;
+ bool locked = false;
+
+ if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
+ pos ++;
+
+ reiserfs_wait_on_write_block(inode->i_sb);
+ if (reiserfs_transaction_running(inode->i_sb))
+ th = current->journal_info;
+ else
+ th = NULL;
+
+ start = pos & (PAGE_CACHE_SIZE - 1);
+ if (unlikely(copied < len)) {
+ if (!PageUptodate(page))
+ copied = 0;
+
+ page_zero_new_buffers(page, start + copied, start + len);
+ }
+ flush_dcache_page(page);
+
+ reiserfs_commit_page(inode, page, start, start + copied);
+
+ /* generic_commit_write does this for us, but does not update the
+ ** transaction tracking stuff when the size changes. So, we have
+ ** to do the i_size updates here.
+ */
+ if (pos + copied > inode->i_size) {
+ struct reiserfs_transaction_handle myth;
+ lock_depth = reiserfs_write_lock_once(inode->i_sb);
+ locked = true;
+ /* If the file have grown beyond the border where it
+ can have a tail, unmark it as needing a tail
+ packing */
+ if ((have_large_tails(inode->i_sb)
+ && inode->i_size > i_block_size(inode) * 4)
+ || (have_small_tails(inode->i_sb)
+ && inode->i_size > i_block_size(inode)))
+ REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
+
+ ret = journal_begin(&myth, inode->i_sb, 1);
+ if (ret)
+ goto journal_error;
+
+ reiserfs_update_inode_transaction(inode);
+ inode->i_size = pos + copied;
+ /*
+ * this will just nest into our transaction. It's important
+ * to use mark_inode_dirty so the inode gets pushed around on the
+ * dirty lists, and so that O_SYNC works as expected
+ */
+ mark_inode_dirty(inode);
+ reiserfs_update_sd(&myth, inode);
+ update_sd = 1;
+ ret = journal_end(&myth, inode->i_sb, 1);
+ if (ret)
+ goto journal_error;
+ }
+ if (th) {
+ if (!locked) {
+ lock_depth = reiserfs_write_lock_once(inode->i_sb);
+ locked = true;
+ }
+ if (!update_sd)
+ mark_inode_dirty(inode);
+ ret = reiserfs_end_persistent_transaction(th);
+ if (ret)
+ goto out;
+ }
+
+ out:
+ if (locked)
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+ unlock_page(page);
+ page_cache_release(page);
+
+ if (pos + len > inode->i_size)
+ reiserfs_truncate_failed_write(inode);
+
+ return ret == 0 ? copied : ret;
+
+ journal_error:
+ reiserfs_write_unlock_once(inode->i_sb, lock_depth);
+ locked = false;
+ if (th) {
+ if (!update_sd)
+ reiserfs_update_sd(th, inode);
+ ret = reiserfs_end_persistent_transaction(th);
+ }
+ goto out;
+}
+
+int reiserfs_commit_write(struct file *f, struct page *page,
+ unsigned from, unsigned to)