Skip to content
  • Wu Fengguang's avatar
    vfs: skip I_CLEAR state inodes · b6fac63c
    Wu Fengguang authored
    
    
    clear_inode() will switch inode state from I_FREEING to I_CLEAR, and do so
    _outside_ of inode_lock.  So any I_FREEING testing is incomplete without a
    coupled testing of I_CLEAR.
    
    So add I_CLEAR tests to drop_pagecache_sb(), generic_sync_sb_inodes() and
    add_dquot_ref().
    
    Masayoshi MIZUMA discovered the bug in drop_pagecache_sb() and Jan Kara
    reminds fixing the other two cases.
    
    Masayoshi MIZUMA has a nice panic flow:
    
    =====================================================================
                [process A]               |        [process B]
     |                                    |
     |    prune_icache()                  | drop_pagecache()
     |      spin_lock(&inode_lock)        |   drop_pagecache_sb()
     |      inode->i_state |= I_FREEING;  |       |
     |      spin_unlock(&inode_lock)      |       V
     |          |                         |     spin_lock(&inode_lock)
     |          V                         |         |
     |      dispose_list()                |         |
     |        list_del()                  |         |
     |        clear_inode()               |         |
     |          inode->i_state = I_CLEAR  |         |
     |            |                       |         V
     |            |                       |      if (inode->i_state & (I_FREEING|I_WILL_FREE))
     |            |                       |              continue;           <==== NOT MATCH
     |            |                       |
     |            |                       | (DANGER from here on! Accessing disposing inode!)
     |            |                       |
     |            |                       |      __iget()
     |            |                       |        list_move() <===== PANIC on poisoned list !!
     V            V                       |
    (time)
    =====================================================================
    
    Reported-by: default avatarMasayoshi MIZUMA <m.mizuma@jp.fujitsu.com>
    Reviewed-by: default avatarJan Kara <jack@suse.cz>
    Signed-off-by: default avatarWu Fengguang <fengguang.wu@intel.com>
    Cc: <stable@kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b6fac63c