Skip to content

Commit a43a67a

Browse files
goldwynrkdave
authored andcommitted
btrfs: switch to iomap_dio_rw() for dio
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 so 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. Signed-off-by: Goldwyn Rodrigues <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 3ad99be commit a43a67a

File tree

4 files changed

+166
-169
lines changed

4 files changed

+166
-169
lines changed

fs/btrfs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ config BTRFS_FS
1414
select LZO_DECOMPRESS
1515
select ZSTD_COMPRESS
1616
select ZSTD_DECOMPRESS
17+
select FS_IOMAP
1718
select RAID6_PQ
1819
select XOR_BLOCKS
1920
select SRCU

fs/btrfs/ctree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2933,6 +2933,7 @@ int btrfs_writepage_cow_fixup(struct page *page, u64 start, u64 end);
29332933
void btrfs_writepage_endio_finish_ordered(struct page *page, u64 start,
29342934
u64 end, int uptodate);
29352935
extern const struct dentry_operations btrfs_dentry_operations;
2936+
ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter);
29362937

29372938
/* ioctl.c */
29382939
long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);

fs/btrfs/file.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,7 +1819,7 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
18191819
loff_t endbyte;
18201820
int err;
18211821

1822-
written = generic_file_direct_write(iocb, from);
1822+
written = btrfs_direct_IO(iocb, from);
18231823

18241824
if (written < 0 || !iov_iter_count(from))
18251825
return written;
@@ -3476,9 +3476,26 @@ static int btrfs_file_open(struct inode *inode, struct file *filp)
34763476
return generic_file_open(inode, filp);
34773477
}
34783478

3479+
static ssize_t btrfs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
3480+
{
3481+
ssize_t ret = 0;
3482+
3483+
if (iocb->ki_flags & IOCB_DIRECT) {
3484+
struct inode *inode = file_inode(iocb->ki_filp);
3485+
3486+
inode_lock_shared(inode);
3487+
ret = btrfs_direct_IO(iocb, to);
3488+
inode_unlock_shared(inode);
3489+
if (ret < 0)
3490+
return ret;
3491+
}
3492+
3493+
return generic_file_buffered_read(iocb, to, ret);
3494+
}
3495+
34793496
const struct file_operations btrfs_file_operations = {
34803497
.llseek = btrfs_file_llseek,
3481-
.read_iter = generic_file_read_iter,
3498+
.read_iter = btrfs_file_read_iter,
34823499
.splice_read = generic_file_splice_read,
34833500
.write_iter = btrfs_file_write_iter,
34843501
.mmap = btrfs_file_mmap,

0 commit comments

Comments
 (0)