• Ashish Samant's avatar
    ocfs2: fix double put of recount tree in ocfs2_lock_refcount_tree() · 4131d538
    Ashish Samant authored
    In ocfs2_lock_refcount_tree, if ocfs2_read_refcount_block() returns an
    error, we do ocfs2_refcount_tree_put twice (once in
    ocfs2_unlock_refcount_tree and once outside it), thereby reducing the
    refcount of the refcount tree twice, but we dont delete the tree in this
    case.  This will make refcnt of the tree = 0 and the
    ocfs2_refcount_tree_put will eventually call ocfs2_mark_lockres_freeing,
    setting OCFS2_LOCK_FREEING for the refcount_tree->rf_lockres.
    
    The error returned by ocfs2_read_refcount_block is propagated all the
    way back and for next iteration of write, ocfs2_lock_refcount_tree gets
    the same tree back from ocfs2_get_refcount_tree because we havent
    deleted the tree.  Now we have the same tree, but OCFS2_LOCK_FREEING is
    set for rf_lockres and eventually, when _ocfs2_lock_refcount_tree is
    called in this iteration, BUG_ON( __ocfs2_cluster_lock:1395 ERROR:
    Cluster lock called on freeing lockres T00000000000000000386019775b08d!
    flags 0x81) is triggerred.
    
    Call stack:
    
      (loop16,11155,0):ocfs2_lock_refcount_tree:482 ERROR: status = -5
      (loop16,11155,0):ocfs2_refcount_cow_hunk:3497 ERROR: status = -5
      (loop16,11155,0):ocfs2_refcount_cow:3560 ERROR: status = -5
      (loop16,11155,0):ocfs2_prepare_inode_for_refcount:2111 ERROR: status = -5
      (loop16,11155,0):ocfs2_prepare_inode_for_write:2190 ERROR: status = -5
      (loop16,11155,0):ocfs2_file_write_iter:2331 ERROR: status = -5
      (loop16,11155,0):__ocfs2_cluster_lock:1395 ERROR: bug expression:
      lockres->l_flags & OCFS2_LOCK_FREEING
    
      (loop16,11155,0):__ocfs2_cluster_lock:1395 ERROR: Cluster lock called on
      freeing lockres T00000000000000000386019775b08d! flags 0x81
    
      kernel BUG at fs/ocfs2/dlmglue.c:1395!
    
      invalid opcode: 0000 [#1] SMP  CPU 0
      Modules linked in: tun ocfs2 jbd2 xen_blkback xen_netback xen_gntdev .. sd_mod crc_t10dif ext3 jbd mbcache
      RIP: __ocfs2_cluster_lock+0x31c/0x740 [ocfs2]
      RSP: e02b:ffff88017c0138a0  EFLAGS: 00010086
      Process loop16 (pid: 11155, threadinfo ffff88017c010000, task ffff8801b5374300)
      Call Trace:
         ocfs2_refcount_lock+0xae/0x130 [ocfs2]
         __ocfs2_lock_refcount_tree+0x29/0xe0 [ocfs2]
         ocfs2_lock_refcount_tree+0xdd/0x320 [ocfs2]
         ocfs2_refcount_cow_hunk+0x1cb/0x440 [ocfs2]
         ocfs2_refcount_cow+0xa9/0x1d0 [ocfs2]
         ocfs2_prepare_inode_for_refcount+0x115/0x200 [ocfs2]
         ocfs2_prepare_inode_for_write+0x33b/0x470 [ocfs2]
         ocfs2_file_write_iter+0x220/0x8c0 [ocfs2]
         aio_write_iter+0x2e/0x30
    
    Fix this by avoiding the second call to ocfs2_refcount_tree_put()
    
    Link: http://lkml.kernel.org/r/1473984404-32011-1-git-send-email-ashish.samant@oracle.comSigned-off-by: default avatarAshish Samant <ashish.samant@oracle.com>
    Reviewed-by: default avatarEric Ren <zren@suse.com>
    Cc: Mark Fasheh <mfasheh@versity.com>
    Cc: Joel Becker <jlbec@evilplan.org>
    Cc: Junxiao Bi <junxiao.bi@oracle.com>
    Cc: Joseph Qi <jiangqi903@gmail.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    4131d538
refcounttree.c 112 KB