Commit 90320251 authored by Al Viro's avatar Al Viro

ocfs2: move generic_write_checks() before the alignment checks

	Alignment checks for dio depend upon the range truncation done by
generic_write_checks().  They can be done as soon as we got ocfs2_rw_lock()
and that actually makes ocfs2_prepare_inode_for_write() simpler.

	The only thing to watch out for is restoring the original count
in "unlock and redo without dio" case.  Position doesn't need to be
restored, since we change it only in O_APPEND case and in that case it
will be reassigned anyway.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 5dc3161c
......@@ -2106,7 +2106,7 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
}
static int ocfs2_prepare_inode_for_write(struct file *file,
loff_t *ppos,
loff_t pos,
size_t count,
int appending,
int *direct_io,
......@@ -2115,7 +2115,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
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);
......@@ -2155,23 +2155,16 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
}
}
/* 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)
......@@ -2227,7 +2220,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
* 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.
......@@ -2242,12 +2235,9 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
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)
......@@ -2263,7 +2253,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
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;
......@@ -2329,8 +2319,16 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
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);
......@@ -2351,6 +2349,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
rw_level = -1;
direct_io = 0;
iov_iter_reexpand(from, count = orig_count);
goto relock;
}
......@@ -2374,11 +2373,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
/* 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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment