]> git.proxmox.com Git - mirror_ubuntu-kernels.git/blobdiff - block/fops.c
mm: always expand the stack with the mmap write lock held
[mirror_ubuntu-kernels.git] / block / fops.c
index 50d245e8c913a1499d47c9b139fa17b6ddf7df73..d2e6be4e3d1c7da029d0a38bd18cf9b069f901e2 100644 (file)
@@ -221,6 +221,24 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
                        bio_endio(bio);
                        break;
                }
+               if (iocb->ki_flags & IOCB_NOWAIT) {
+                       /*
+                        * This is nonblocking IO, and we need to allocate
+                        * another bio if we have data left to map. As we
+                        * cannot guarantee that one of the sub bios will not
+                        * fail getting issued FOR NOWAIT and as error results
+                        * are coalesced across all of them, be safe and ask for
+                        * a retry of this from blocking context.
+                        */
+                       if (unlikely(iov_iter_count(iter))) {
+                               bio_release_pages(bio, false);
+                               bio_clear_flag(bio, BIO_REFFED);
+                               bio_put(bio);
+                               blk_finish_plug(&plug);
+                               return -EAGAIN;
+                       }
+                       bio->bi_opf |= REQ_NOWAIT;
+               }
 
                if (is_read) {
                        if (dio->flags & DIO_SHOULD_DIRTY)
@@ -228,9 +246,6 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
                } else {
                        task_io_account_write(bio->bi_iter.bi_size);
                }
-               if (iocb->ki_flags & IOCB_NOWAIT)
-                       bio->bi_opf |= REQ_NOWAIT;
-
                dio->size += bio->bi_iter.bi_size;
                pos += bio->bi_iter.bi_size;