}
 
 static int ocfs2_prepare_inode_for_write(struct file *file,
-                                        loff_t *ppos,
+                                        loff_t pos,
                                         size_t count,
                                         int appending,
                                         int *direct_io,
        int ret = 0, meta_level = 0;
        struct dentry *dentry = file->f_path.dentry;
        struct inode *inode = dentry->d_inode;
-       loff_t saved_pos = 0, end;
+       loff_t end;
        struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
        int full_coherency = !(osb->s_mount_opt &
                OCFS2_MOUNT_COHERENCY_BUFFERED);
                        }
                }
 
-               /* work on a copy of ppos until we're sure that we won't have
-                * to recalculate it due to relocking. */
-               if (appending)
-                       saved_pos = i_size_read(inode);
-               else
-                       saved_pos = *ppos;
-
-               end = saved_pos + count;
+               end = pos + count;
 
-               ret = ocfs2_check_range_for_refcount(inode, saved_pos, count);
+               ret = ocfs2_check_range_for_refcount(inode, pos, count);
                if (ret == 1) {
                        ocfs2_inode_unlock(inode, meta_level);
                        meta_level = -1;
 
                        ret = ocfs2_prepare_inode_for_refcount(inode,
                                                               file,
-                                                              saved_pos,
+                                                              pos,
                                                               count,
                                                               &meta_level);
                        if (has_refcount)
                 * caller will have to retake some cluster
                 * locks and initiate the io as buffered.
                 */
-               ret = ocfs2_check_range_for_holes(inode, saved_pos, count);
+               ret = ocfs2_check_range_for_holes(inode, pos, count);
                if (ret == 1) {
                        /*
                         * Fallback to old way if the feature bit is not set.
                break;
        }
 
-       if (appending)
-               *ppos = saved_pos;
-
 out_unlock:
        trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno,
-                                           saved_pos, appending, count,
+                                           pos, appending, count,
                                            direct_io, has_refcount);
 
        if (meta_level >= 0)
        int ret, direct_io, appending, rw_level, have_alloc_sem  = 0;
        int can_do_direct, has_refcount = 0;
        ssize_t written = 0;
-       size_t count = iov_iter_count(from);
+       size_t count = iov_iter_count(from), orig_count;
        loff_t old_size;
        u32 old_clusters;
        struct file *file = iocb->ki_filp;
                ocfs2_inode_unlock(inode, 1);
        }
 
+       orig_count = count;
+       ret = generic_write_checks(file, &iocb->ki_pos, &count);
+       if (ret < 0) {
+               mlog_errno(ret);
+               goto out;
+       }
+       iov_iter_truncate(from, count);
+
        can_do_direct = direct_io;
-       ret = ocfs2_prepare_inode_for_write(file, &iocb->ki_pos, count, appending,
+       ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, appending,
                                            &can_do_direct, &has_refcount);
        if (ret < 0) {
                mlog_errno(ret);
                rw_level = -1;
 
                direct_io = 0;
+               iov_iter_reexpand(from, count = orig_count);
                goto relock;
        }
 
        /* communicate with ocfs2_dio_end_io */
        ocfs2_iocb_set_rw_locked(iocb, rw_level);
 
-       ret = generic_write_checks(file, &iocb->ki_pos, &count);
-       if (ret)
-               goto out_dio;
-
-       iov_iter_truncate(from, count);
        if (direct_io) {
                loff_t endbyte;
                ssize_t written_buffered;