lkml.org 
[lkml]   [2018]   [Mar]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.15 035/122] direct-io: Fix sleep in atomic due to sync AIO
    Date
    4.15-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Jan Kara <jack@suse.cz>

    commit d9c10e5b8863cfb6886d1640386455075c6e979d upstream.

    Commit e864f39569f4 "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 9830f4be159b "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: Mark Rutland <mark.rutland@arm.com>
    Tested-by: Mark Rutland <mark.rutland@arm.com>
    Fixes: 9830f4be159b29399d107bffb99e0132bc5aedd4
    Signed-off-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/direct-io.c | 3 +--
    1 file changed, 1 insertion(+), 2 deletions(-)

    --- a/fs/direct-io.c
    +++ b/fs/direct-io.c
    @@ -1252,8 +1252,7 @@ do_blockdev_direct_IO(struct kiocb *iocb
    */
    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) {
    /*

    \
     
     \ /
      Last update: 2018-03-07 21:35    [W:9.037 / U:0.260 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site