btrfs: switch to iomap for direct IO
We're using direct io implementation based on buffer heads. This patch switches to the new iomap infrastructure. Switch from __blockdev_direct_IO() to iomap_dio_rw(). Rename btrfs_get_blocks_direct() to btrfs_dio_iomap_begin() and use it as iomap_begin() for iomap direct I/O functions. This function allocates and locks all the blocks required for the I/O. btrfs_submit_direct() is used as the submit_io() hook for direct I/O ops. Since we need direct I/O reads to go through iomap_dio_rw(), we change file_operations.read_iter() to a btrfs_file_read_iter() which calls btrfs_direct_IO() for direct reads and falls back to generic_file_buffered_read() for incomplete reads and buffered reads. We don't need address_space.direct_IO() anymore: set it to noop. Similarly, we don't need flags used in __blockdev_direct_IO(). iomap is capable of direct I/O reads from a hole, so we don't need to return -ENOENT. Btrfs direct I/O is now done under i_rwsem, shared in case of reads and exclusive in case of writes. This guards against simultaneous truncates. Use iomap->iomap_end() to check for failed or incomplete direct I/O: - for writes, call __endio_write_update_ordered() - for reads, unlock extents btrfs_dio_data is now hooked in iomap->private and not current->journal_info. It carries the reservation variable and the amount of data submitted, so we can calculate the amount of data to call __endio_write_update_ordered in case of an error. This patch removes last use of struct buffer_head from btrfs. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:

committed by
David Sterba

parent
154f7cb868
commit
f85781fb50
@@ -1870,7 +1870,7 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
|
||||
loff_t endbyte;
|
||||
int err;
|
||||
|
||||
written = generic_file_direct_write(iocb, from);
|
||||
written = btrfs_direct_IO(iocb, from);
|
||||
|
||||
if (written < 0 || !iov_iter_count(from))
|
||||
return written;
|
||||
@@ -3568,9 +3568,26 @@ static int btrfs_file_open(struct inode *inode, struct file *filp)
|
||||
return generic_file_open(inode, filp);
|
||||
}
|
||||
|
||||
static ssize_t btrfs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
if (iocb->ki_flags & IOCB_DIRECT) {
|
||||
struct inode *inode = file_inode(iocb->ki_filp);
|
||||
|
||||
inode_lock_shared(inode);
|
||||
ret = btrfs_direct_IO(iocb, to);
|
||||
inode_unlock_shared(inode);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return generic_file_buffered_read(iocb, to, ret);
|
||||
}
|
||||
|
||||
const struct file_operations btrfs_file_operations = {
|
||||
.llseek = btrfs_file_llseek,
|
||||
.read_iter = generic_file_read_iter,
|
||||
.read_iter = btrfs_file_read_iter,
|
||||
.splice_read = generic_file_splice_read,
|
||||
.write_iter = btrfs_file_write_iter,
|
||||
.splice_write = iter_file_splice_write,
|
||||
|
Reference in New Issue
Block a user