iomap: pass a flags argument to iomap_dio_rw
Pass a set of flags to iomap_dio_rw instead of the boolean wait_for_completion argument. The IOMAP_DIO_FORCE_WAIT flag replaces the wait_for_completion, but only needs to be passed when the iocb isn't synchronous to start with to simplify the callers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> [djwong: rework xfs_file.c so that we can push iomap changes separately] Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
5724be5de8
commit
2f63296578
|
@ -1949,8 +1949,8 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
|
||||||
goto buffered;
|
goto buffered;
|
||||||
}
|
}
|
||||||
|
|
||||||
dio = __iomap_dio_rw(iocb, from, &btrfs_dio_iomap_ops,
|
dio = __iomap_dio_rw(iocb, from, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
|
||||||
&btrfs_dio_ops, is_sync_kiocb(iocb));
|
0);
|
||||||
|
|
||||||
btrfs_inode_unlock(inode, ilock_flags);
|
btrfs_inode_unlock(inode, ilock_flags);
|
||||||
|
|
||||||
|
@ -3622,8 +3622,7 @@ static ssize_t btrfs_direct_read(struct kiocb *iocb, struct iov_iter *to)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
btrfs_inode_lock(inode, BTRFS_ILOCK_SHARED);
|
btrfs_inode_lock(inode, BTRFS_ILOCK_SHARED);
|
||||||
ret = iomap_dio_rw(iocb, to, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
|
ret = iomap_dio_rw(iocb, to, &btrfs_dio_iomap_ops, &btrfs_dio_ops, 0);
|
||||||
is_sync_kiocb(iocb));
|
|
||||||
btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
|
btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,7 @@ static ssize_t ext4_dio_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||||
return generic_file_read_iter(iocb, to);
|
return generic_file_read_iter(iocb, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iomap_dio_rw(iocb, to, &ext4_iomap_ops, NULL,
|
ret = iomap_dio_rw(iocb, to, &ext4_iomap_ops, NULL, 0);
|
||||||
is_sync_kiocb(iocb));
|
|
||||||
inode_unlock_shared(inode);
|
inode_unlock_shared(inode);
|
||||||
|
|
||||||
file_accessed(iocb->ki_filp);
|
file_accessed(iocb->ki_filp);
|
||||||
|
@ -550,7 +549,7 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||||
if (ilock_shared)
|
if (ilock_shared)
|
||||||
iomap_ops = &ext4_iomap_overwrite_ops;
|
iomap_ops = &ext4_iomap_overwrite_ops;
|
||||||
ret = iomap_dio_rw(iocb, from, iomap_ops, &ext4_dio_write_ops,
|
ret = iomap_dio_rw(iocb, from, iomap_ops, &ext4_dio_write_ops,
|
||||||
is_sync_kiocb(iocb) || unaligned_io || extend);
|
(unaligned_io || extend) ? IOMAP_DIO_FORCE_WAIT : 0);
|
||||||
if (ret == -ENOTBLK)
|
if (ret == -ENOTBLK)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
|
|
|
@ -797,9 +797,7 @@ static ssize_t gfs2_file_direct_read(struct kiocb *iocb, struct iov_iter *to,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_uninit;
|
goto out_uninit;
|
||||||
|
|
||||||
ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL,
|
ret = iomap_dio_rw(iocb, to, &gfs2_iomap_ops, NULL, 0);
|
||||||
is_sync_kiocb(iocb));
|
|
||||||
|
|
||||||
gfs2_glock_dq(gh);
|
gfs2_glock_dq(gh);
|
||||||
out_uninit:
|
out_uninit:
|
||||||
gfs2_holder_uninit(gh);
|
gfs2_holder_uninit(gh);
|
||||||
|
@ -833,8 +831,7 @@ static ssize_t gfs2_file_direct_write(struct kiocb *iocb, struct iov_iter *from,
|
||||||
if (offset + len > i_size_read(&ip->i_inode))
|
if (offset + len > i_size_read(&ip->i_inode))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL,
|
ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL, 0);
|
||||||
is_sync_kiocb(iocb));
|
|
||||||
if (ret == -ENOTBLK)
|
if (ret == -ENOTBLK)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -420,13 +420,15 @@ iomap_dio_actor(struct inode *inode, loff_t pos, loff_t length,
|
||||||
struct iomap_dio *
|
struct iomap_dio *
|
||||||
__iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
__iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
||||||
bool wait_for_completion)
|
unsigned int dio_flags)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = iocb->ki_filp->f_mapping;
|
struct address_space *mapping = iocb->ki_filp->f_mapping;
|
||||||
struct inode *inode = file_inode(iocb->ki_filp);
|
struct inode *inode = file_inode(iocb->ki_filp);
|
||||||
size_t count = iov_iter_count(iter);
|
size_t count = iov_iter_count(iter);
|
||||||
loff_t pos = iocb->ki_pos;
|
loff_t pos = iocb->ki_pos;
|
||||||
loff_t end = iocb->ki_pos + count - 1, ret = 0;
|
loff_t end = iocb->ki_pos + count - 1, ret = 0;
|
||||||
|
bool wait_for_completion =
|
||||||
|
is_sync_kiocb(iocb) || (dio_flags & IOMAP_DIO_FORCE_WAIT);
|
||||||
unsigned int iomap_flags = IOMAP_DIRECT;
|
unsigned int iomap_flags = IOMAP_DIRECT;
|
||||||
struct blk_plug plug;
|
struct blk_plug plug;
|
||||||
struct iomap_dio *dio;
|
struct iomap_dio *dio;
|
||||||
|
@ -434,9 +436,6 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
if (!count)
|
if (!count)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (WARN_ON(is_sync_kiocb(iocb) && !wait_for_completion))
|
|
||||||
return ERR_PTR(-EIO);
|
|
||||||
|
|
||||||
dio = kmalloc(sizeof(*dio), GFP_KERNEL);
|
dio = kmalloc(sizeof(*dio), GFP_KERNEL);
|
||||||
if (!dio)
|
if (!dio)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
@ -598,11 +597,11 @@ EXPORT_SYMBOL_GPL(__iomap_dio_rw);
|
||||||
ssize_t
|
ssize_t
|
||||||
iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
||||||
bool wait_for_completion)
|
unsigned int dio_flags)
|
||||||
{
|
{
|
||||||
struct iomap_dio *dio;
|
struct iomap_dio *dio;
|
||||||
|
|
||||||
dio = __iomap_dio_rw(iocb, iter, ops, dops, wait_for_completion);
|
dio = __iomap_dio_rw(iocb, iter, ops, dops, dio_flags);
|
||||||
if (IS_ERR_OR_NULL(dio))
|
if (IS_ERR_OR_NULL(dio))
|
||||||
return PTR_ERR_OR_ZERO(dio);
|
return PTR_ERR_OR_ZERO(dio);
|
||||||
return iomap_dio_complete(dio);
|
return iomap_dio_complete(dio);
|
||||||
|
|
|
@ -219,8 +219,7 @@ xfs_file_dio_aio_read(
|
||||||
} else {
|
} else {
|
||||||
xfs_ilock(ip, XFS_IOLOCK_SHARED);
|
xfs_ilock(ip, XFS_IOLOCK_SHARED);
|
||||||
}
|
}
|
||||||
ret = iomap_dio_rw(iocb, to, &xfs_read_iomap_ops, NULL,
|
ret = iomap_dio_rw(iocb, to, &xfs_read_iomap_ops, NULL, 0);
|
||||||
is_sync_kiocb(iocb));
|
|
||||||
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
|
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -584,7 +583,7 @@ xfs_file_dio_aio_write(
|
||||||
*/
|
*/
|
||||||
ret = iomap_dio_rw(iocb, from, &xfs_direct_write_iomap_ops,
|
ret = iomap_dio_rw(iocb, from, &xfs_direct_write_iomap_ops,
|
||||||
&xfs_dio_write_ops,
|
&xfs_dio_write_ops,
|
||||||
is_sync_kiocb(iocb) || unaligned_io);
|
unaligned_io ? IOMAP_DIO_FORCE_WAIT : 0);
|
||||||
out:
|
out:
|
||||||
xfs_iunlock(ip, iolock);
|
xfs_iunlock(ip, iolock);
|
||||||
|
|
||||||
|
|
|
@ -780,7 +780,7 @@ static ssize_t zonefs_file_dio_write(struct kiocb *iocb, struct iov_iter *from)
|
||||||
ret = zonefs_file_dio_append(iocb, from);
|
ret = zonefs_file_dio_append(iocb, from);
|
||||||
else
|
else
|
||||||
ret = iomap_dio_rw(iocb, from, &zonefs_iomap_ops,
|
ret = iomap_dio_rw(iocb, from, &zonefs_iomap_ops,
|
||||||
&zonefs_write_dio_ops, sync);
|
&zonefs_write_dio_ops, 0);
|
||||||
if (zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
|
if (zi->i_ztype == ZONEFS_ZTYPE_SEQ &&
|
||||||
(ret > 0 || ret == -EIOCBQUEUED)) {
|
(ret > 0 || ret == -EIOCBQUEUED)) {
|
||||||
if (ret > 0)
|
if (ret > 0)
|
||||||
|
@ -917,7 +917,7 @@ static ssize_t zonefs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||||
}
|
}
|
||||||
file_accessed(iocb->ki_filp);
|
file_accessed(iocb->ki_filp);
|
||||||
ret = iomap_dio_rw(iocb, to, &zonefs_iomap_ops,
|
ret = iomap_dio_rw(iocb, to, &zonefs_iomap_ops,
|
||||||
&zonefs_read_dio_ops, is_sync_kiocb(iocb));
|
&zonefs_read_dio_ops, 0);
|
||||||
} else {
|
} else {
|
||||||
ret = generic_file_read_iter(iocb, to);
|
ret = generic_file_read_iter(iocb, to);
|
||||||
if (ret == -EIO)
|
if (ret == -EIO)
|
||||||
|
|
|
@ -256,12 +256,18 @@ struct iomap_dio_ops {
|
||||||
struct bio *bio, loff_t file_offset);
|
struct bio *bio, loff_t file_offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait for the I/O to complete in iomap_dio_rw even if the kiocb is not
|
||||||
|
* synchronous.
|
||||||
|
*/
|
||||||
|
#define IOMAP_DIO_FORCE_WAIT (1 << 0)
|
||||||
|
|
||||||
ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
ssize_t iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
||||||
bool wait_for_completion);
|
unsigned int dio_flags);
|
||||||
struct iomap_dio *__iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
struct iomap_dio *__iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
|
||||||
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
const struct iomap_ops *ops, const struct iomap_dio_ops *dops,
|
||||||
bool wait_for_completion);
|
unsigned int dio_flags);
|
||||||
ssize_t iomap_dio_complete(struct iomap_dio *dio);
|
ssize_t iomap_dio_complete(struct iomap_dio *dio);
|
||||||
int iomap_dio_iopoll(struct kiocb *kiocb, bool spin);
|
int iomap_dio_iopoll(struct kiocb *kiocb, bool spin);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue