Commit f1f973ff authored by Ryan Ding's avatar Ryan Ding Committed by Linus Torvalds

ocfs2: code clean up for direct io

Clean up ocfs2_file_write_iter & ocfs2_prepare_inode_for_write:
 * remove append dio check: it will be checked in ocfs2_direct_IO()
 * remove file hole check: file hole is supported for now
 * remove inline data check: it will be checked in ocfs2_direct_IO()
 * remove the full_coherence check when append dio: we will get the
   inode_lock in ocfs2_dio_get_block, there is no need to fall back to
   buffer io to ensure the coherence semantics.

Now the drop dio procedure is gone.  :)

[akpm@linux-foundation.org: remove unused label]
Signed-off-by: default avatarRyan Ding <ryan.ding@oracle.com>
Reviewed-by: default avatarJunxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <joseph.qi@huawei.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c15471f7
...@@ -1381,44 +1381,6 @@ static int __ocfs2_write_remove_suid(struct inode *inode, ...@@ -1381,44 +1381,6 @@ static int __ocfs2_write_remove_suid(struct inode *inode,
return ret; return ret;
} }
/*
* Will look for holes and unwritten extents in the range starting at
* pos for count bytes (inclusive).
*/
static int ocfs2_check_range_for_holes(struct inode *inode, loff_t pos,
size_t count)
{
int ret = 0;
unsigned int extent_flags;
u32 cpos, clusters, extent_len, phys_cpos;
struct super_block *sb = inode->i_sb;
cpos = pos >> OCFS2_SB(sb)->s_clustersize_bits;
clusters = ocfs2_clusters_for_bytes(sb, pos + count) - cpos;
while (clusters) {
ret = ocfs2_get_clusters(inode, cpos, &phys_cpos, &extent_len,
&extent_flags);
if (ret < 0) {
mlog_errno(ret);
goto out;
}
if (phys_cpos == 0 || (extent_flags & OCFS2_EXT_UNWRITTEN)) {
ret = 1;
break;
}
if (extent_len > clusters)
extent_len = clusters;
clusters -= extent_len;
cpos += extent_len;
}
out:
return ret;
}
static int ocfs2_write_remove_suid(struct inode *inode) static int ocfs2_write_remove_suid(struct inode *inode)
{ {
int ret; int ret;
...@@ -2129,18 +2091,12 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode, ...@@ -2129,18 +2091,12 @@ static int ocfs2_prepare_inode_for_refcount(struct inode *inode,
static int ocfs2_prepare_inode_for_write(struct file *file, static int ocfs2_prepare_inode_for_write(struct file *file,
loff_t pos, loff_t pos,
size_t count, size_t count)
int appending,
int *direct_io,
int *has_refcount)
{ {
int ret = 0, meta_level = 0; int ret = 0, meta_level = 0;
struct dentry *dentry = file->f_path.dentry; struct dentry *dentry = file->f_path.dentry;
struct inode *inode = d_inode(dentry); struct inode *inode = d_inode(dentry);
loff_t end; loff_t end;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
int full_coherency = !(osb->s_mount_opt &
OCFS2_MOUNT_COHERENCY_BUFFERED);
/* /*
* We start with a read level meta lock and only jump to an ex * We start with a read level meta lock and only jump to an ex
...@@ -2189,10 +2145,6 @@ static int ocfs2_prepare_inode_for_write(struct file *file, ...@@ -2189,10 +2145,6 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
pos, pos,
count, count,
&meta_level); &meta_level);
if (has_refcount)
*has_refcount = 1;
if (direct_io)
*direct_io = 0;
} }
if (ret < 0) { if (ret < 0) {
...@@ -2200,67 +2152,12 @@ static int ocfs2_prepare_inode_for_write(struct file *file, ...@@ -2200,67 +2152,12 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
goto out_unlock; goto out_unlock;
} }
/*
* Skip the O_DIRECT checks if we don't need
* them.
*/
if (!direct_io || !(*direct_io))
break;
/*
* There's no sane way to do direct writes to an inode
* with inline data.
*/
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
*direct_io = 0;
break;
}
/*
* Allowing concurrent direct writes means
* i_size changes wouldn't be synchronized, so
* one node could wind up truncating another
* nodes writes.
*/
if (end > i_size_read(inode) && !full_coherency) {
*direct_io = 0;
break;
}
/*
* Fallback to old way if the feature bit is not set.
*/
if (end > i_size_read(inode) &&
!ocfs2_supports_append_dio(osb)) {
*direct_io = 0;
break;
}
/*
* We don't fill holes during direct io, so
* check for them here. If any are found, the
* caller will have to retake some cluster
* locks and initiate the io as buffered.
*/
ret = ocfs2_check_range_for_holes(inode, pos, count);
if (ret == 1) {
/*
* Fallback to old way if the feature bit is not set.
* Otherwise try dio first and then complete the rest
* request through buffer io.
*/
if (!ocfs2_supports_append_dio(osb))
*direct_io = 0;
ret = 0;
} else if (ret < 0)
mlog_errno(ret);
break; break;
} }
out_unlock: out_unlock:
trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno, trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno,
pos, appending, count, pos, count);
direct_io, has_refcount);
if (meta_level >= 0) if (meta_level >= 0)
ocfs2_inode_unlock(inode, meta_level); ocfs2_inode_unlock(inode, meta_level);
...@@ -2272,18 +2169,16 @@ static int ocfs2_prepare_inode_for_write(struct file *file, ...@@ -2272,18 +2169,16 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
struct iov_iter *from) struct iov_iter *from)
{ {
int direct_io, appending, rw_level; int direct_io, rw_level;
int can_do_direct, has_refcount = 0;
ssize_t written = 0; ssize_t written = 0;
ssize_t ret; ssize_t ret;
size_t count = iov_iter_count(from), orig_count; size_t count = iov_iter_count(from);
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
int full_coherency = !(osb->s_mount_opt & int full_coherency = !(osb->s_mount_opt &
OCFS2_MOUNT_COHERENCY_BUFFERED); OCFS2_MOUNT_COHERENCY_BUFFERED);
int unaligned_dio = 0; int unaligned_dio = 0;
int dropped_dio = 0;
int append_write = ((iocb->ki_pos + count) >= int append_write = ((iocb->ki_pos + count) >=
i_size_read(inode) ? 1 : 0); i_size_read(inode) ? 1 : 0);
...@@ -2296,12 +2191,10 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, ...@@ -2296,12 +2191,10 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
if (count == 0) if (count == 0)
return 0; return 0;
appending = iocb->ki_flags & IOCB_APPEND ? 1 : 0;
direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0; direct_io = iocb->ki_flags & IOCB_DIRECT ? 1 : 0;
inode_lock(inode); inode_lock(inode);
relock:
/* /*
* Concurrent O_DIRECT writes are allowed with * Concurrent O_DIRECT writes are allowed with
* mount_option "coherency=buffered". * mount_option "coherency=buffered".
...@@ -2334,7 +2227,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, ...@@ -2334,7 +2227,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
ocfs2_inode_unlock(inode, 1); ocfs2_inode_unlock(inode, 1);
} }
orig_count = iov_iter_count(from);
ret = generic_write_checks(iocb, from); ret = generic_write_checks(iocb, from);
if (ret <= 0) { if (ret <= 0) {
if (ret) if (ret)
...@@ -2343,9 +2235,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, ...@@ -2343,9 +2235,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
} }
count = ret; count = ret;
can_do_direct = direct_io; ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count);
ret = ocfs2_prepare_inode_for_write(file, iocb->ki_pos, count, appending,
&can_do_direct, &has_refcount);
if (ret < 0) { if (ret < 0) {
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
...@@ -2354,22 +2244,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, ...@@ -2354,22 +2244,6 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
if (direct_io && !is_sync_kiocb(iocb)) if (direct_io && !is_sync_kiocb(iocb))
unaligned_dio = ocfs2_is_io_unaligned(inode, count, iocb->ki_pos); unaligned_dio = ocfs2_is_io_unaligned(inode, count, iocb->ki_pos);
/*
* We can't complete the direct I/O as requested, fall back to
* buffered I/O.
*/
if (direct_io && !can_do_direct) {
ocfs2_rw_unlock(inode, rw_level);
rw_level = -1;
direct_io = 0;
iocb->ki_flags &= ~IOCB_DIRECT;
iov_iter_reexpand(from, orig_count);
dropped_dio = 1;
goto relock;
}
if (unaligned_dio) { if (unaligned_dio) {
/* /*
* Wait on previous unaligned aio to complete before * Wait on previous unaligned aio to complete before
...@@ -2405,7 +2279,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb, ...@@ -2405,7 +2279,7 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
goto no_sync; goto no_sync;
if (((file->f_flags & O_DSYNC) && !direct_io) || if (((file->f_flags & O_DSYNC) && !direct_io) ||
IS_SYNC(inode) || dropped_dio) { IS_SYNC(inode)) {
ret = filemap_fdatawrite_range(file->f_mapping, ret = filemap_fdatawrite_range(file->f_mapping,
iocb->ki_pos - written, iocb->ki_pos - written,
iocb->ki_pos - 1); iocb->ki_pos - 1);
......
...@@ -1450,28 +1450,20 @@ DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_remove_inode_range); ...@@ -1450,28 +1450,20 @@ DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_remove_inode_range);
TRACE_EVENT(ocfs2_prepare_inode_for_write, TRACE_EVENT(ocfs2_prepare_inode_for_write,
TP_PROTO(unsigned long long ino, unsigned long long saved_pos, TP_PROTO(unsigned long long ino, unsigned long long saved_pos,
int appending, unsigned long count, unsigned long count),
int *direct_io, int *has_refcount), TP_ARGS(ino, saved_pos, count),
TP_ARGS(ino, saved_pos, appending, count, direct_io, has_refcount),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(unsigned long long, ino) __field(unsigned long long, ino)
__field(unsigned long long, saved_pos) __field(unsigned long long, saved_pos)
__field(int, appending)
__field(unsigned long, count) __field(unsigned long, count)
__field(int, direct_io)
__field(int, has_refcount)
), ),
TP_fast_assign( TP_fast_assign(
__entry->ino = ino; __entry->ino = ino;
__entry->saved_pos = saved_pos; __entry->saved_pos = saved_pos;
__entry->appending = appending;
__entry->count = count; __entry->count = count;
__entry->direct_io = direct_io ? *direct_io : -1;
__entry->has_refcount = has_refcount ? *has_refcount : -1;
), ),
TP_printk("%llu %llu %d %lu %d %d", __entry->ino, TP_printk("%llu %llu %lu", __entry->ino,
__entry->saved_pos, __entry->appending, __entry->count, __entry->saved_pos, __entry->count)
__entry->direct_io, __entry->has_refcount)
); );
DEFINE_OCFS2_INT_EVENT(generic_file_aio_read_ret); DEFINE_OCFS2_INT_EVENT(generic_file_aio_read_ret);
......
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