On Tue, Mar 04, 2025 at 12:18:07PM +0000, Pavel Begunkov wrote: > ((dio->flags & IOMAP_DIO_NEED_SYNC) && !use_fua) || > - ((dio->flags & IOMAP_DIO_WRITE) && pos >= i_size_read(inode))) > + ((dio->flags & IOMAP_DIO_WRITE) && pos >= i_size_read(inode))) { > dio->flags &= ~IOMAP_DIO_CALLER_COMP; > > + if (!is_sync_kiocb(dio->iocb) && > + (dio->iocb->ki_flags & IOCB_NOWAIT)) > + return -EAGAIN; Black magic without comments explaining it. > + if (!is_sync_kiocb(dio->iocb) && (dio->iocb->ki_flags & IOCB_NOWAIT)) { > + /* > + * This is nonblocking IO, and we might need to allocate > + * multiple bios. In this case, 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, ask > + * for a retry of this from blocking context. > + */ > + if (bio_iov_vecs_to_alloc(dio->submit.iter, BIO_MAX_VECS + 1) > > + BIO_MAX_VECS) This is not very accurate in times of multi-page bvecs and large order folios all over. I think you really need to byte the bullet and support for early returns from the non-blocking bio submission path.