From: Greg Kroah-Hartman Date: Fri, 15 May 2015 01:42:01 +0000 (-0700) Subject: 3.14-stable patches X-Git-Tag: v3.10.79~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba471a37642059e06351703803bda76233356a5f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: ocfs2-dlm-fix-race-between-purge-and-get-lock-resource.patch --- diff --git a/queue-3.14/ocfs2-dlm-fix-race-between-purge-and-get-lock-resource.patch b/queue-3.14/ocfs2-dlm-fix-race-between-purge-and-get-lock-resource.patch new file mode 100644 index 00000000000..521489f4a98 --- /dev/null +++ b/queue-3.14/ocfs2-dlm-fix-race-between-purge-and-get-lock-resource.patch @@ -0,0 +1,62 @@ +From b1432a2a35565f538586774a03bf277c27fc267d Mon Sep 17 00:00:00 2001 +From: Junxiao Bi +Date: Tue, 5 May 2015 16:24:02 -0700 +Subject: ocfs2: dlm: fix race between purge and get lock resource + +From: Junxiao Bi + +commit b1432a2a35565f538586774a03bf277c27fc267d upstream. + +There is a race window in dlm_get_lock_resource(), which may return a +lock resource which has been purged. This will cause the process to +hang forever in dlmlock() as the ast msg can't be handled due to its +lock resource not existing. + + dlm_get_lock_resource { + ... + spin_lock(&dlm->spinlock); + tmpres = __dlm_lookup_lockres_full(dlm, lockid, namelen, hash); + if (tmpres) { + spin_unlock(&dlm->spinlock); + >>>>>>>> race window, dlm_run_purge_list() may run and purge + the lock resource + spin_lock(&tmpres->spinlock); + ... + spin_unlock(&tmpres->spinlock); + } + } + +Signed-off-by: Junxiao Bi +Cc: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ocfs2/dlm/dlmmaster.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/fs/ocfs2/dlm/dlmmaster.c ++++ b/fs/ocfs2/dlm/dlmmaster.c +@@ -726,6 +726,19 @@ lookup: + if (tmpres) { + spin_unlock(&dlm->spinlock); + spin_lock(&tmpres->spinlock); ++ ++ /* ++ * Right after dlm spinlock was released, dlm_thread could have ++ * purged the lockres. Check if lockres got unhashed. If so ++ * start over. ++ */ ++ if (hlist_unhashed(&tmpres->hash_node)) { ++ spin_unlock(&tmpres->spinlock); ++ dlm_lockres_put(tmpres); ++ tmpres = NULL; ++ goto lookup; ++ } ++ + /* Wait on the thread that is mastering the resource */ + if (tmpres->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { + __dlm_wait_on_lockres(tmpres);