From 6df7881a84013f91405e5e113a4c322dd1804ba6 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 5 Sep 2012 08:08:30 -0600 Subject: [PATCH] Btrfs: move the sb_end_intwrite until after the throttle logic Sage reported the following lockdep backtrace ===================================== [ BUG: bad unlock balance detected! ] 3.6.0-rc2-ceph-00171-gc7ed62d #1 Not tainted ------------------------------------- btrfs-cleaner/7607 is trying to release lock (sb_internal) at: [] btrfs_commit_transaction+0xa6e/0xb20 [btrfs] but there are no more locks to release! other info that might help us debug this: 1 lock held by btrfs-cleaner/7607: #0: (&fs_info->cleaner_mutex){+.+...}, at: [] cleaner_kthread+0x95/0x120 [btrfs] stack backtrace: Pid: 7607, comm: btrfs-cleaner Not tainted 3.6.0-rc2-ceph-00171-gc7ed62d #1 Call Trace: [] ? btrfs_commit_transaction+0xa6e/0xb20 [btrfs] [] print_unlock_inbalance_bug+0xfe/0x110 [] lock_release_non_nested+0x1ee/0x310 [] ? kmem_cache_free+0x7b/0x160 [] ? put_transaction+0x8c/0x130 [btrfs] [] ? btrfs_commit_transaction+0xa6e/0xb20 [btrfs] [] lock_release+0xd5/0x220 [] ? kmem_cache_free+0x151/0x160 [] __sb_end_write+0x7d/0x90 [] btrfs_commit_transaction+0xa6e/0xb20 [btrfs] [] ? __init_waitqueue_head+0x60/0x60 [] ? _raw_spin_unlock+0x2b/0x40 [] __btrfs_end_transaction+0x368/0x3c0 [btrfs] [] btrfs_end_transaction_throttle+0x18/0x20 [btrfs] [] btrfs_drop_snapshot+0x410/0x600 [btrfs] [] ? do_raw_spin_unlock+0x5d/0xb0 [] btrfs_clean_old_snapshots+0xaf/0x150 [btrfs] [] ? cleaner_kthread+0x95/0x120 [btrfs] [] cleaner_kthread+0xa9/0x120 [btrfs] [] ? btrfs_destroy_delayed_refs.isra.102+0x220/0x220 [btrfs] [] kthread+0xae/0xc0 [] ? trace_hardirqs_on+0xd/0x10 [] kernel_thread_helper+0x4/0x10 [] ? retint_restore_args+0x13/0x13 [] ? flush_kthread_work+0x1a0/0x1a0 [] ? gs_change+0x13/0x13 This is because the throttle stuff can commit the transaction, which expects to be the one stopping the intwrite stuff, but we've already done it in the __btrfs_end_transaction. Moving the sb_end_intewrite after this logic makes the lockdep go away. Thanks, Tested-by: Sage Weil Signed-off-by: Josef Bacik --- 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 f8ae448ebec4..0629edf99100 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -564,8 +564,6 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, btrfs_trans_release_metadata(trans, root); trans->block_rsv = NULL; - sb_end_intwrite(root->fs_info->sb); - if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) && should_end_transaction(trans, root)) { trans->transaction->blocked = 1; @@ -586,6 +584,8 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, } } + sb_end_intwrite(root->fs_info->sb); + WARN_ON(cur_trans != info->running_transaction); WARN_ON(atomic_read(&cur_trans->num_writers) < 1); atomic_dec(&cur_trans->num_writers); -- 2.20.1