From 1b44959b80384aabad406af4028f090d862a5377 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 26 Feb 2018 12:51:43 +0100 Subject: [PATCH] direct-io: Fix sleep in atomic due to sync AIO Commit 27f3873604e4 "fs: add RWF_DSYNC aand RWF_SYNC" added additional way for direct IO to become synchronous and thus trigger fsync from the IO completion handler. Then commit 2a2d7bcc1d67 "fs: Use RWF_* flags for AIO operations" allowed these flags to be set for AIO as well. However that commit forgot to update the condition checking whether the IO completion handling should be defered to a workqueue and thus AIO DIO with RWF_[D]SYNC set will call fsync() from IRQ context resulting in sleep in atomic. Fix the problem by checking directly iocb flags (the same way as it is done in dio_complete()) instead of checking all conditions that could lead to IO being synchronous. CC: Christoph Hellwig CC: Goldwyn Rodrigues CC: stable@vger.kernel.org Reported-by: Mark Rutland Tested-by: Mark Rutland Fixes: 2a2d7bcc1d670073fbd732202e2e5c6f5b756ff7 Signed-off-by: Jan Kara Signed-off-by: Jens Axboe --- fs/direct-io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index a0ca9e48e9937..1357ef563893a 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1274,8 +1274,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, */ if (dio->is_async && iov_iter_rw(iter) == WRITE) { retval = 0; - if ((iocb->ki_filp->f_flags & O_DSYNC) || - IS_SYNC(iocb->ki_filp->f_mapping->host)) + if (iocb->ki_flags & IOCB_DSYNC) retval = dio_set_defer_completion(dio); else if (!dio->inode->i_sb->s_dio_done_wq) { /* -- 2.39.5