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 | |
| 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>
| -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); |
