lkml.org 
[lkml]   [2017]   [Nov]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 22/25] ocfs2: should wait dio before inode lock in ocfs2_setattr()
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

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

    From: alex chen <alex.chen@huawei.com>

    commit 28f5a8a7c033cbf3e32277f4cc9c6afd74f05300 upstream.

    we should wait dio requests to finish before inode lock in
    ocfs2_setattr(), otherwise the following deadlock will happen:

    process 1 process 2 process 3
    truncate file 'A' end_io of writing file 'A' receiving the bast messages
    ocfs2_setattr
    ocfs2_inode_lock_tracker
    ocfs2_inode_lock_full
    inode_dio_wait
    __inode_dio_wait
    -->waiting for all dio
    requests finish
    dlm_proxy_ast_handler
    dlm_do_local_bast
    ocfs2_blocking_ast
    ocfs2_generic_handle_bast
    set OCFS2_LOCK_BLOCKED flag
    dio_end_io
    dio_bio_end_aio
    dio_complete
    ocfs2_dio_end_io
    ocfs2_dio_end_io_write
    ocfs2_inode_lock
    __ocfs2_cluster_lock
    ocfs2_wait_for_mask
    -->waiting for OCFS2_LOCK_BLOCKED
    flag to be cleared, that is waiting
    for 'process 1' unlocking the inode lock
    inode_dio_end
    -->here dec the i_dio_count, but will never
    be called, so a deadlock happened.

    Link: http://lkml.kernel.org/r/59F81636.70508@huawei.com
    Signed-off-by: Alex Chen <alex.chen@huawei.com>
    Reviewed-by: Jun Piao <piaojun@huawei.com>
    Reviewed-by: Joseph Qi <jiangqi903@gmail.com>
    Acked-by: Changwei Ge <ge.changwei@h3c.com>
    Cc: Mark Fasheh <mfasheh@versity.com>
    Cc: Joel Becker <jlbec@evilplan.org>
    Cc: Junxiao Bi <junxiao.bi@oracle.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/ocfs2/file.c | 9 +++++++--
    1 file changed, 7 insertions(+), 2 deletions(-)

    --- a/fs/ocfs2/file.c
    +++ b/fs/ocfs2/file.c
    @@ -1166,6 +1166,13 @@ int ocfs2_setattr(struct dentry *dentry,
    }
    size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE;
    if (size_change) {
    + /*
    + * Here we should wait dio to finish before inode lock
    + * to avoid a deadlock between ocfs2_setattr() and
    + * ocfs2_dio_end_io_write()
    + */
    + inode_dio_wait(inode);
    +
    status = ocfs2_rw_lock(inode, 1);
    if (status < 0) {
    mlog_errno(status);
    @@ -1186,8 +1193,6 @@ int ocfs2_setattr(struct dentry *dentry,
    if (status)
    goto bail_unlock;

    - inode_dio_wait(inode);
    -
    if (i_size_read(inode) >= attr->ia_size) {
    if (ocfs2_should_order_data(inode)) {
    status = ocfs2_begin_ordered_truncate(inode,

    \
     
     \ /
      Last update: 2017-11-22 11:28    [W:5.245 / U:0.112 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site