From 8ad92bbde3a17ce9aa44e32ae42df5db259fa2ce Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Fri, 5 Jun 2015 10:33:11 +0530 Subject: stack: use list_head for managing frames PROBLEM -------- statedump requests that traverse call frames of all call stacks in execution may race with a STACK_RESET on a stack. This could crash the corresponding glusterfs process. For e.g, recently we observed this in a regression test case tests/basic/afr/sparse-self-heal.t. FIX --- gf_proc_dump_pending_frames takes a (TRY_LOCK) call_pool->lock before iterating through call frames of all call stacks in progress. With this fix, STACK_RESET removes its call frames under the same lock. Additional info ---------------- This fix makes call_stack_t to use struct list_head in place of custom doubly-linked list implementation. This makes call_frame_t manipulation easier to maintain in the context of STACK_WIND et al. BUG: 1234408 Change-Id: I7e43bccd3994cd9184ab982dba3dbc10618f0d94 Signed-off-by: Krishnan Parthasarathi Reviewed-on: http://review.gluster.org/11095 Reviewed-by: Niels de Vos Tested-by: Gluster Build System Reviewed-by: Pranith Kumar Karampuri Tested-by: NetBSD Build System (cherry picked from commit 79e4c7b2fad6db15863efb4e979525b1bd4862ea) Reviewed-on: http://review.gluster.org/11352 --- xlators/meta/src/frames-file.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'xlators/meta/src/frames-file.c') diff --git a/xlators/meta/src/frames-file.c b/xlators/meta/src/frames-file.c index 0e9777c9da2..b81e5c7413b 100644 --- a/xlators/meta/src/frames-file.c +++ b/xlators/meta/src/frames-file.c @@ -44,8 +44,7 @@ frames_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd) strprintf (strfd, "\t\t\"Number\": %d,\n", ++i); strprintf (strfd, "\t\t\"Frame\": [\n"); j = 1; - for (frame = &stack->frames; frame; - frame = frame->next) { + list_for_each_entry (frame, &stack->myframes, frames) { strprintf (strfd, "\t\t {\n"); strprintf (strfd, "\t\t\t\"Number\": %d,\n", j++); @@ -76,7 +75,8 @@ frames_file_fill (xlator_t *this, inode_t *file, strfd_t *strfd) frame->unwind_to); strprintf (strfd, "\t\t\t\"Complete\": %d\n", frame->complete); - if (frame->next == NULL) + if (list_is_last (&frame->frames, + &stack->myframes)) strprintf (strfd, "\t\t }\n"); else strprintf (strfd, "\t\t },\n"); -- cgit