Commit d9c10e5b authored by Jan Kara's avatar Jan Kara Committed by Jens Axboe

direct-io: Fix sleep in atomic due to sync AIO

Commit e864f395 "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 9830f4be "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 <hch@lst.de>
CC: Goldwyn Rodrigues <rgoldwyn@suse.com>
CC: stable@vger.kernel.org
Reported-by: default avatarMark Rutland <mark.rutland@arm.com>
Tested-by: default avatarMark Rutland <mark.rutland@arm.com>
Fixes: 9830f4beSigned-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent ba989a01
...@@ -1274,8 +1274,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, ...@@ -1274,8 +1274,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
*/ */
if (dio->is_async && iov_iter_rw(iter) == WRITE) { if (dio->is_async && iov_iter_rw(iter) == WRITE) {
retval = 0; retval = 0;
if ((iocb->ki_filp->f_flags & O_DSYNC) || if (iocb->ki_flags & IOCB_DSYNC)
IS_SYNC(iocb->ki_filp->f_mapping->host))
retval = dio_set_defer_completion(dio); retval = dio_set_defer_completion(dio);
else if (!dio->inode->i_sb->s_dio_done_wq) { else if (!dio->inode->i_sb->s_dio_done_wq) {
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment