diff options
author | David Teigland <teigland@redhat.com> | 2008-08-18 15:03:25 -0400 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2008-08-28 12:50:07 -0400 |
commit | c1dcf65ffc5796bf4ff75c13f448e63b3a416fd6 (patch) | |
tree | 0283dcd832fb54758e80f7fb53f8efb331b6321c /fs/dlm | |
parent | dc68c7ed362a00a48290252573a8eb9f74463c3a (diff) |
dlm: fix locking of lockspace list in dlm_scand
The dlm_scand thread needs to lock the list of lockspaces
when going through it.
Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/dlm_internal.h | 1 | ||||
-rw-r--r-- | fs/dlm/lockspace.c | 27 |
2 files changed, 26 insertions, 2 deletions
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 9e0622aff496..868e4c9ef127 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -445,6 +445,7 @@ struct dlm_ls { | |||
445 | the dlm using this ls */ | 445 | the dlm using this ls */ |
446 | int ls_create_count; /* create/release refcount */ | 446 | int ls_create_count; /* create/release refcount */ |
447 | unsigned long ls_flags; /* LSFL_ */ | 447 | unsigned long ls_flags; /* LSFL_ */ |
448 | unsigned long ls_scan_time; | ||
448 | struct kobject ls_kobj; | 449 | struct kobject ls_kobj; |
449 | 450 | ||
450 | struct dlm_rsbtable *ls_rsbtbl; | 451 | struct dlm_rsbtable *ls_rsbtbl; |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index ba672fe0a601..d910501de6d2 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -212,19 +212,41 @@ void dlm_lockspace_exit(void) | |||
212 | kset_unregister(dlm_kset); | 212 | kset_unregister(dlm_kset); |
213 | } | 213 | } |
214 | 214 | ||
215 | static struct dlm_ls *find_ls_to_scan(void) | ||
216 | { | ||
217 | struct dlm_ls *ls; | ||
218 | |||
219 | spin_lock(&lslist_lock); | ||
220 | list_for_each_entry(ls, &lslist, ls_list) { | ||
221 | if (time_after_eq(jiffies, ls->ls_scan_time + | ||
222 | dlm_config.ci_scan_secs * HZ)) { | ||
223 | spin_unlock(&lslist_lock); | ||
224 | return ls; | ||
225 | } | ||
226 | } | ||
227 | spin_unlock(&lslist_lock); | ||
228 | return NULL; | ||
229 | } | ||
230 | |||
215 | static int dlm_scand(void *data) | 231 | static int dlm_scand(void *data) |
216 | { | 232 | { |
217 | struct dlm_ls *ls; | 233 | struct dlm_ls *ls; |
234 | int timeout_jiffies = dlm_config.ci_scan_secs * HZ; | ||
218 | 235 | ||
219 | while (!kthread_should_stop()) { | 236 | while (!kthread_should_stop()) { |
220 | list_for_each_entry(ls, &lslist, ls_list) { | 237 | ls = find_ls_to_scan(); |
238 | if (ls) { | ||
221 | if (dlm_lock_recovery_try(ls)) { | 239 | if (dlm_lock_recovery_try(ls)) { |
240 | ls->ls_scan_time = jiffies; | ||
222 | dlm_scan_rsbs(ls); | 241 | dlm_scan_rsbs(ls); |
223 | dlm_scan_timeout(ls); | 242 | dlm_scan_timeout(ls); |
224 | dlm_unlock_recovery(ls); | 243 | dlm_unlock_recovery(ls); |
244 | } else { | ||
245 | ls->ls_scan_time += HZ; | ||
225 | } | 246 | } |
247 | } else { | ||
248 | schedule_timeout_interruptible(timeout_jiffies); | ||
226 | } | 249 | } |
227 | schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ); | ||
228 | } | 250 | } |
229 | return 0; | 251 | return 0; |
230 | } | 252 | } |
@@ -418,6 +440,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
418 | ls->ls_lvblen = lvblen; | 440 | ls->ls_lvblen = lvblen; |
419 | ls->ls_count = 0; | 441 | ls->ls_count = 0; |
420 | ls->ls_flags = 0; | 442 | ls->ls_flags = 0; |
443 | ls->ls_scan_time = jiffies; | ||
421 | 444 | ||
422 | if (flags & DLM_LSFL_TIMEWARN) | 445 | if (flags & DLM_LSFL_TIMEWARN) |
423 | set_bit(LSFL_TIMEWARN, &ls->ls_flags); | 446 | set_bit(LSFL_TIMEWARN, &ls->ls_flags); |