Btrfs: fix lockdep error in async commit

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Fri Nov 22 17:59:04 EST 2013


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=b1a06a4b574996692b72b742bf6e6aa0c711a948
Commit:     b1a06a4b574996692b72b742bf6e6aa0c711a948
Parent:     d52c1bcc647ca41ee563bc38d8231e5f3816112c
Author:     Liu Bo <bo.li.liu at oracle.com>
AuthorDate: Wed Nov 6 16:57:55 2013 +0800
Committer:  Chris Mason <chris.mason at fusionio.com>
CommitDate: Wed Nov 20 20:44:44 2013 -0500

    Btrfs: fix lockdep error in async commit
    
    Lockdep complains about btrfs's async commit:
    
    [ 2372.462171] [ BUG: bad unlock balance detected! ]
    [ 2372.462191] 3.12.0+ #32 Tainted: G        W
    [ 2372.462209] -------------------------------------
    [ 2372.462228] ceph-osd/14048 is trying to release lock (sb_internal) at:
    [ 2372.462275] [<ffffffffa022cb10>] btrfs_commit_transaction_async+0x1b0/0x2a0 [btrfs]
    [ 2372.462305] but there are no more locks to release!
    [ 2372.462324]
    [ 2372.462324] other info that might help us debug this:
    [ 2372.462349] no locks held by ceph-osd/14048.
    [ 2372.462367]
    [ 2372.462367] stack backtrace:
    [ 2372.462386] CPU: 2 PID: 14048 Comm: ceph-osd Tainted: G        W    3.12.0+ #32
    [ 2372.462414] Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M., BIOS 080015  11/09/2011
    [ 2372.462455]  ffffffffa022cb10 ffff88007490fd28 ffffffff816f094a ffff8800378aa320
    [ 2372.462491]  ffff88007490fd50 ffffffff810adf4c ffff8800378aa320 ffff88009af97650
    [ 2372.462526]  ffffffffa022cb10 ffff88007490fd88 ffffffff810b01ee ffff8800898c0000
    [ 2372.462562] Call Trace:
    [ 2372.462584]  [<ffffffffa022cb10>] ? btrfs_commit_transaction_async+0x1b0/0x2a0 [btrfs]
    [ 2372.462619]  [<ffffffff816f094a>] dump_stack+0x45/0x56
    [ 2372.462642]  [<ffffffff810adf4c>] print_unlock_imbalance_bug+0xec/0x100
    [ 2372.462677]  [<ffffffffa022cb10>] ? btrfs_commit_transaction_async+0x1b0/0x2a0 [btrfs]
    [ 2372.462710]  [<ffffffff810b01ee>] lock_release+0x18e/0x210
    [ 2372.462742]  [<ffffffffa022cb36>] btrfs_commit_transaction_async+0x1d6/0x2a0 [btrfs]
    [ 2372.462783]  [<ffffffffa025a7ce>] btrfs_ioctl_start_sync+0x3e/0xc0 [btrfs]
    [ 2372.462822]  [<ffffffffa025f1d3>] btrfs_ioctl+0x4c3/0x1f70 [btrfs]
    [ 2372.462849]  [<ffffffff812c0321>] ? avc_has_perm+0x121/0x1b0
    [ 2372.462873]  [<ffffffff812c0224>] ? avc_has_perm+0x24/0x1b0
    [ 2372.462897]  [<ffffffff8107ecc8>] ? sched_clock_cpu+0xa8/0x100
    [ 2372.462922]  [<ffffffff8117b145>] do_vfs_ioctl+0x2e5/0x4e0
    [ 2372.462946]  [<ffffffff812c19e6>] ? file_has_perm+0x86/0xa0
    [ 2372.462969]  [<ffffffff8117b3c1>] SyS_ioctl+0x81/0xa0
    [ 2372.462991]  [<ffffffff817045a4>] tracesys+0xdd/0xe2
    
    ====================================================
    
    It's because that we don't do the right thing when checking if it's ok to
    tell lockdep that we're trying to release the rwsem.
    
    If the trans handle's type is TRANS_ATTACH, we won't acquire the freeze rwsem, but
    as TRANS_ATTACH fits the check (trans < TRANS_JOIN_NOLOCK), we'll release the freeze
    rwsem, which makes lockdep complains a lot.
    
    Reported-by: Ma Jianpeng <majianpeng at gmail.com>
    Signed-off-by: Liu Bo <bo.li.liu at oracle.com>
    Signed-off-by: Miao Xie <miaox at cn.fujitsu.com>
    Signed-off-by: Josef Bacik <jbacik at fusionio.com>
    Signed-off-by: Chris Mason <chris.mason at fusionio.com>
---
 fs/btrfs/transaction.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 57c16b4..c6a872a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1480,7 +1480,7 @@ static void do_async_commit(struct work_struct *work)
 	 * We've got freeze protection passed with the transaction.
 	 * Tell lockdep about it.
 	 */
-	if (ac->newtrans->type < TRANS_JOIN_NOLOCK)
+	if (ac->newtrans->type & __TRANS_FREEZABLE)
 		rwsem_acquire_read(
 		     &ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
 		     0, 1, _THIS_IP_);
@@ -1521,7 +1521,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
 	 * Tell lockdep we've released the freeze rwsem, since the
 	 * async commit thread will be the one to unlock it.
 	 */
-	if (trans->type < TRANS_JOIN_NOLOCK)
+	if (ac->newtrans->type & __TRANS_FREEZABLE)
 		rwsem_release(
 			&root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
 			1, _THIS_IP_);



More information about the linux-mtd-cvs mailing list