]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
btrfs: enable direct IO for bs > ps cases
authorQu Wenruo <wqu@suse.com>
Sun, 7 Dec 2025 21:13:58 +0000 (07:43 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 3 Feb 2026 05:38:32 +0000 (06:38 +0100)
Previously direct IO was disabled if the fs block size was larger than
the page size, the reasons are:

- Iomap direct IO can split the range ignoring the fs block alignment
  Which could trigger the bio size check from btrfs_submit_bio().

- The buffer is only ensured to be contiguous in user space memory
  The underlying physical memory is not ensured to be contiguous, and
  that can cause problems for the checksum generation/verification and
  RAID56 handling.

However the above problems are solved by the following upstream commits:

001397f5ef49 ("iomap: add IOMAP_DIO_FSBLOCK_ALIGNED flag")
  Which added an extra flag that can be utilized by the fs to ensure
  the bio submitted by iomap is always aligned to fs block size.

ec20799064c8 ("btrfs: enable encoded read/write/send for bs > ps cases")
8870dbeedcf9 ("btrfs: raid56: enable bs > ps support")
  Which makes btrfs to handle bios that are not backed by large folios
  but still are aligned to fs block size.

As the commits have been merged we can enable direct IO support for
bs > ps cases.

Reviewed-by: Neal Gompa <neal@gompa.dev>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/direct-io.c

index 07e19e88ba4b3f83d6d36dcc02115b6727982140..bc7cc2d81f8fef6d54ff4d4b0c9f8ea291e6307e 100644 (file)
@@ -763,7 +763,7 @@ static ssize_t btrfs_dio_read(struct kiocb *iocb, struct iov_iter *iter,
        struct btrfs_dio_data data = { 0 };
 
        return iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
-                           IOMAP_DIO_PARTIAL, &data, done_before);
+                           IOMAP_DIO_PARTIAL | IOMAP_DIO_FSBLOCK_ALIGNED, &data, done_before);
 }
 
 static struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *iter,
@@ -772,7 +772,7 @@ static struct iomap_dio *btrfs_dio_write(struct kiocb *iocb, struct iov_iter *it
        struct btrfs_dio_data data = { 0 };
 
        return __iomap_dio_rw(iocb, iter, &btrfs_dio_iomap_ops, &btrfs_dio_ops,
-                           IOMAP_DIO_PARTIAL, &data, done_before);
+                           IOMAP_DIO_PARTIAL | IOMAP_DIO_FSBLOCK_ALIGNED, &data, done_before);
 }
 
 static ssize_t check_direct_IO(struct btrfs_fs_info *fs_info,
@@ -785,19 +785,6 @@ static ssize_t check_direct_IO(struct btrfs_fs_info *fs_info,
 
        if (iov_iter_alignment(iter) & blocksize_mask)
                return -EINVAL;
-
-       /*
-        * For bs > ps support, we heavily rely on large folios to make sure no
-        * block will cross large folio boundaries.
-        *
-        * But memory provided by direct IO is only virtually contiguous, not
-        * physically contiguous, and will break the btrfs' large folio requirement.
-        *
-        * So for bs > ps support, all direct IOs should fallback to buffered ones.
-        */
-       if (fs_info->sectorsize > PAGE_SIZE)
-               return -EINVAL;
-
        return 0;
 }