aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoseph Qi <joseph.qi@huawei.com>2014-09-25 19:05:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-09-26 11:10:34 -0400
commit5760a97c7143c208fa3a8f8cad0ed7dd672ebd28 (patch)
tree5fa9d3345390c8d86f7768ee6d04d2520d4c28f5 /fs
parent56d7acc792c0d98f38f22058671ee715ff197023 (diff)
ocfs2/dlm: do not get resource spinlock if lockres is new
There is a deadlock case which reported by Guozhonghua: https://oss.oracle.com/pipermail/ocfs2-devel/2014-September/010079.html This case is caused by &res->spinlock and &dlm->master_lock misordering in different threads. It was introduced by commit 8d400b81cc83 ("ocfs2/dlm: Clean up refmap helpers"). Since lockres is new, it doesn't not require the &res->spinlock. So remove it. Fixes: 8d400b81cc83 ("ocfs2/dlm: Clean up refmap helpers") Signed-off-by: Joseph Qi <joseph.qi@huawei.com> Reviewed-by: joyce.xue <xuejiufei@huawei.com> Reported-by: Guozhonghua <guozhonghua@h3c.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Mark Fasheh <mfasheh@suse.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 3ec906ef5d9a..e3cfa0227026 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -655,12 +655,9 @@ void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
655 clear_bit(bit, res->refmap); 655 clear_bit(bit, res->refmap);
656} 656}
657 657
658 658static void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
659void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
660 struct dlm_lock_resource *res) 659 struct dlm_lock_resource *res)
661{ 660{
662 assert_spin_locked(&res->spinlock);
663
664 res->inflight_locks++; 661 res->inflight_locks++;
665 662
666 mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name, 663 mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name,
@@ -668,6 +665,13 @@ void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
668 __builtin_return_address(0)); 665 __builtin_return_address(0));
669} 666}
670 667
668void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
669 struct dlm_lock_resource *res)
670{
671 assert_spin_locked(&res->spinlock);
672 __dlm_lockres_grab_inflight_ref(dlm, res);
673}
674
671void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm, 675void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
672 struct dlm_lock_resource *res) 676 struct dlm_lock_resource *res)
673{ 677{
@@ -894,10 +898,8 @@ lookup:
894 /* finally add the lockres to its hash bucket */ 898 /* finally add the lockres to its hash bucket */
895 __dlm_insert_lockres(dlm, res); 899 __dlm_insert_lockres(dlm, res);
896 900
897 /* Grab inflight ref to pin the resource */ 901 /* since this lockres is new it doesn't not require the spinlock */
898 spin_lock(&res->spinlock); 902 __dlm_lockres_grab_inflight_ref(dlm, res);
899 dlm_lockres_grab_inflight_ref(dlm, res);
900 spin_unlock(&res->spinlock);
901 903
902 /* get an extra ref on the mle in case this is a BLOCK 904 /* get an extra ref on the mle in case this is a BLOCK
903 * if so, the creator of the BLOCK may try to put the last 905 * if so, the creator of the BLOCK may try to put the last