Merge tag 'for-6.0-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[linux-block.git] / fs / btrfs / inode.c
index f0c97d25b4a0e762849ac63c3fa7f40d8bf38f2f..ad250892028d6e0387ff8ad101e0ee2a9b9452f2 100644 (file)
@@ -7693,6 +7693,20 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
        const u64 data_alloc_len = length;
        bool unlock_extents = false;
 
+       /*
+        * We could potentially fault if we have a buffer > PAGE_SIZE, and if
+        * we're NOWAIT we may submit a bio for a partial range and return
+        * EIOCBQUEUED, which would result in an errant short read.
+        *
+        * The best way to handle this would be to allow for partial completions
+        * of iocb's, so we could submit the partial bio, return and fault in
+        * the rest of the pages, and then submit the io for the rest of the
+        * range.  However we don't have that currently, so simply return
+        * -EAGAIN at this point so that the normal path is used.
+        */
+       if (!write && (flags & IOMAP_NOWAIT) && length > PAGE_SIZE)
+               return -EAGAIN;
+
        /*
         * Cap the size of reads to that usually seen in buffered I/O as we need
         * to allocate a contiguous array for the checksums.