On Mon, Feb 08, 2021 at 07:30:08PM -0700, Jens Axboe wrote: > + if (iocb->ki_flags & IOCB_NOWAIT) { > + if (filemap_range_needs_writeback(mapping, pos, end)) { > + ret = -EAGAIN; > + goto out_free_dio; > + } > + flags |= IOMAP_NOWAIT; > + } > if (iter_is_iovec(iter)) > dio->flags |= IOMAP_DIO_DIRTY; > } else { > + if (iocb->ki_flags & IOCB_NOWAIT) { > + if (filemap_range_has_page(mapping, pos, end)) { > + ret = -EAGAIN; > + goto out_free_dio; > + } > + flags |= IOMAP_NOWAIT; > + } > + > flags |= IOMAP_WRITE; > dio->flags |= IOMAP_DIO_WRITE; > > @@ -478,14 +493,6 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, > dio->flags |= IOMAP_DIO_WRITE_FUA; > } > > - if (iocb->ki_flags & IOCB_NOWAIT) { > - if (filemap_range_has_page(mapping, pos, end)) { > - ret = -EAGAIN; > - goto out_free_dio; > - } > - flags |= IOMAP_NOWAIT; > - } looking at this I really hate the scheme with the potential racyness and duplicated page looksups. Why can't we pass a nonblock flag to filemap_write_and_wait_range and invalidate_inode_pages2_range that makes them return -EAGAIN when they would block to clean this whole mess up?