• Sayali Lokhande's avatar
    f2fs: Avoid double lock for cp_rwsem during checkpoint · 34c061ad
    Sayali Lokhande authored
    There could be a scenario where f2fs_sync_node_pages gets
    called during checkpoint, which in turn tries to flush
    inline data and calls iput(). This results in deadlock as
    iput() tries to hold cp_rwsem, which is already held at the
    beginning by checkpoint->block_operations().
    
    Call stack :
    
    Thread A		Thread B
    f2fs_write_checkpoint()
    - block_operations(sbi)
     - f2fs_lock_all(sbi);
      - down_write(&sbi->cp_rwsem);
    
                            - open()
                             - igrab()
                            - write() write inline data
                            - unlink()
    - f2fs_sync_node_pages()
     - if (is_inline_node(page))
      - flush_inline_data()
       - ilookup()
         page = f2fs_pagecache_get_page()
         if (!page)
          goto iput_out;
         iput_out:
    			-close()
    			-iput()
           iput(inode);
           - f2fs_evict_inode()
            - f2fs_truncate_blocks()
             - f2fs_lock_op()
               - down_read(&sbi->cp_rwsem);
    
    Fixes: 2049d4fc ("f2fs: avoid multiple node page writes due to inline_data")
    Signed-off-by: default avatarSayali Lokhande <sayalil@codeaurora.org>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    34c061ad
node.c 77.3 KB