@@ -382,6 +382,7 @@ const struct address_space_operations def_blk_aops = {
.write_end = blkdev_write_end,
.writepages = blkdev_writepages,
.direct_IO = blkdev_direct_IO,
+ .swap_rw = blkdev_direct_IO,
.migratepage = buffer_migrate_page_norefs,
.is_dirty_writeback = buffer_check_dirty_writeback,
.supports = AS_SUPPORTS_DIRECT_IO,
@@ -10852,15 +10852,10 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
sis->highest_bit = bsi.nr_pages - 1;
return bsi.nr_extents;
}
-#else
-static void btrfs_swap_deactivate(struct file *file)
-{
-}
-static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
- sector_t *span)
+static ssize_t btrfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
{
- return -EOPNOTSUPP;
+ return iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, NULL, 0);
}
#endif
@@ -10944,8 +10939,11 @@ static const struct address_space_operations btrfs_aops = {
#endif
.set_page_dirty = btrfs_set_page_dirty,
.error_remove_page = generic_error_remove_page,
+#ifdef CONFIG_SWAP
.swap_activate = btrfs_swap_activate,
.swap_deactivate = btrfs_swap_deactivate,
+ .swap_rw = btrfs_swap_rw,
+#endif
.supports = AS_SUPPORTS_DIRECT_IO,
};
@@ -3651,6 +3651,11 @@ static int ext4_iomap_swap_activate(struct swap_info_struct *sis,
&ext4_iomap_report_ops);
}
+static ssize_t ext4_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
+{
+ return iomap_dio_rw(iocb, iter, &ext4_iomap_ops, NULL, 0);
+}
+
static const struct address_space_operations ext4_aops = {
.readpage = ext4_readpage,
.readahead = ext4_readahead,
@@ -3666,6 +3671,7 @@ static const struct address_space_operations ext4_aops = {
.is_partially_uptodate = block_is_partially_uptodate,
.error_remove_page = generic_error_remove_page,
.swap_activate = ext4_iomap_swap_activate,
+ .swap_rw = ext4_swap_rw,
.supports = AS_SUPPORTS_DIRECT_IO,
};
@@ -3683,6 +3689,7 @@ static const struct address_space_operations ext4_journalled_aops = {
.is_partially_uptodate = block_is_partially_uptodate,
.error_remove_page = generic_error_remove_page,
.swap_activate = ext4_iomap_swap_activate,
+ .swap_rw = ext4_swap_rw,
.supports = AS_SUPPORTS_DIRECT_IO,
};
@@ -3701,6 +3708,7 @@ static const struct address_space_operations ext4_da_aops = {
.is_partially_uptodate = block_is_partially_uptodate,
.error_remove_page = generic_error_remove_page,
.swap_activate = ext4_iomap_swap_activate,
+ .swap_rw = ext4_swap_rw,
.supports = AS_SUPPORTS_DIRECT_IO,
};
@@ -3710,6 +3718,7 @@ static const struct address_space_operations ext4_dax_aops = {
.bmap = ext4_bmap,
.invalidatepage = noop_invalidatepage,
.swap_activate = ext4_iomap_swap_activate,
+ .swap_rw = ext4_swap_rw,
.supports = AS_SUPPORTS_DIRECT_IO,
};
@@ -540,6 +540,13 @@ xfs_iomap_swapfile_activate(
&xfs_read_iomap_ops);
}
+static ssize_t xfs_swap_rw(struct kiocb *iocb, struct iov_iter *iter)
+{
+ if (iocb->ki_flags & IOCB_WRITE)
+ return iomap_dio_rw(iocb, iter, &xfs_direct_write_iomap_ops, NULL, 0);
+ return iomap_dio_rw(iocb, iter, &xfs_read_iomap_ops, NULL, 0);
+}
+
const struct address_space_operations xfs_address_space_operations = {
.readpage = xfs_vm_readpage,
.readahead = xfs_vm_readahead,
@@ -552,6 +559,7 @@ const struct address_space_operations xfs_address_space_operations = {
.is_partially_uptodate = iomap_is_partially_uptodate,
.error_remove_page = generic_error_remove_page,
.swap_activate = xfs_iomap_swapfile_activate,
+ .swap_rw = xfs_swap_rw,
.supports = AS_SUPPORTS_DIRECT_IO,
};
@@ -560,5 +568,6 @@ const struct address_space_operations xfs_dax_aops = {
.set_page_dirty = __set_page_dirty_no_writeback,
.invalidatepage = noop_invalidatepage,
.swap_activate = xfs_iomap_swapfile_activate,
+ .swap_rw = xfs_swap_rw,
.supports = AS_SUPPORTS_DIRECT_IO,
};
Implement swap_rw for block devices, btrfs, ext4 and xfs. This allows the the page swapping code to use direct-IO rather than direct bio submission, whilst skipping the checks going via read/write_iter would entail. Signed-off-by: David Howells <dhowells@redhat.com> cc: Matthew Wilcox <willy@infradead.org> cc: Christoph Hellwig <hch@lst.de> cc: Jens Axboe <axboe@kernel.dk> cc: Chris Mason <clm@fb.com> cc: Josef Bacik <josef@toxicpanda.com> cc: David Sterba <dsterba@suse.com> cc: "Theodore Ts'o" <tytso@mit.edu> cc: Andreas Dilger <adilger.kernel@dilger.ca> cc: Darrick J. Wong <djwong@kernel.org> cc: linux-block@vger.kernel.org cc: linux-btrfs@vger.kernel.org cc: linux-ext4@vger.kernel.org cc: linux-xfs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org --- block/fops.c | 1 + fs/btrfs/inode.c | 12 +++++------- fs/ext4/inode.c | 9 +++++++++ fs/xfs/xfs_aops.c | 9 +++++++++ 4 files changed, 24 insertions(+), 7 deletions(-)