aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jwhiter@redhat.com>2007-05-16 15:56:13 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-07-09 03:22:29 -0400
commit916297aad5de2363dccd531873eda55d4d6afb57 (patch)
treee8e5eabf529bd4a41d9ee225087e237581ce5ffd
parent2a87ab080607d009b8b2a8706f4e27d70402ca9c (diff)
[DLM] keep dlm from panicing when traversing rsb list in debugfs
This problem was originally reported against GFS6.1, but the same issue exists in upstream DLM. This patch keeps the rsb iterator assigning under the rsbtbl list lock. Each time we process an rsb we grab a reference to it to make sure it is not freed out from underneath us, and then put it when we get the next rsb in the list or move onto another list. Signed-off-by: Josef Bacik <jwhiter@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
-rw-r--r--fs/dlm/debug_fs.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c
index 61ba670b9e02..9e27a1675794 100644
--- a/fs/dlm/debug_fs.c
+++ b/fs/dlm/debug_fs.c
@@ -17,6 +17,7 @@
17#include <linux/debugfs.h> 17#include <linux/debugfs.h>
18 18
19#include "dlm_internal.h" 19#include "dlm_internal.h"
20#include "lock.h"
20 21
21#define DLM_DEBUG_BUF_LEN 4096 22#define DLM_DEBUG_BUF_LEN 4096
22static char debug_buf[DLM_DEBUG_BUF_LEN]; 23static char debug_buf[DLM_DEBUG_BUF_LEN];
@@ -166,6 +167,9 @@ static int rsb_iter_next(struct rsb_iter *ri)
166 read_lock(&ls->ls_rsbtbl[i].lock); 167 read_lock(&ls->ls_rsbtbl[i].lock);
167 if (!list_empty(&ls->ls_rsbtbl[i].list)) { 168 if (!list_empty(&ls->ls_rsbtbl[i].list)) {
168 ri->next = ls->ls_rsbtbl[i].list.next; 169 ri->next = ls->ls_rsbtbl[i].list.next;
170 ri->rsb = list_entry(ri->next, struct dlm_rsb,
171 res_hashchain);
172 dlm_hold_rsb(ri->rsb);
169 read_unlock(&ls->ls_rsbtbl[i].lock); 173 read_unlock(&ls->ls_rsbtbl[i].lock);
170 break; 174 break;
171 } 175 }
@@ -176,6 +180,7 @@ static int rsb_iter_next(struct rsb_iter *ri)
176 if (ri->entry >= ls->ls_rsbtbl_size) 180 if (ri->entry >= ls->ls_rsbtbl_size)
177 return 1; 181 return 1;
178 } else { 182 } else {
183 struct dlm_rsb *old = ri->rsb;
179 i = ri->entry; 184 i = ri->entry;
180 read_lock(&ls->ls_rsbtbl[i].lock); 185 read_lock(&ls->ls_rsbtbl[i].lock);
181 ri->next = ri->next->next; 186 ri->next = ri->next->next;
@@ -184,11 +189,13 @@ static int rsb_iter_next(struct rsb_iter *ri)
184 ri->next = NULL; 189 ri->next = NULL;
185 ri->entry++; 190 ri->entry++;
186 read_unlock(&ls->ls_rsbtbl[i].lock); 191 read_unlock(&ls->ls_rsbtbl[i].lock);
192 dlm_put_rsb(old);
187 goto top; 193 goto top;
188 } 194 }
195 ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
189 read_unlock(&ls->ls_rsbtbl[i].lock); 196 read_unlock(&ls->ls_rsbtbl[i].lock);
197 dlm_put_rsb(old);
190 } 198 }
191 ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
192 199
193 return 0; 200 return 0;
194} 201}