Commit c1dcf65ffc5796bf4ff75c13f448e63b3a416fd6

Authored by David Teigland
1 parent dc68c7ed36

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>

Showing 2 changed files with 26 additions and 2 deletions Side-by-side Diff

fs/dlm/dlm_internal.h
... ... @@ -445,6 +445,7 @@
445 445 the dlm using this ls */
446 446 int ls_create_count; /* create/release refcount */
447 447 unsigned long ls_flags; /* LSFL_ */
  448 + unsigned long ls_scan_time;
448 449 struct kobject ls_kobj;
449 450  
450 451 struct dlm_rsbtable *ls_rsbtbl;
... ... @@ -212,19 +212,41 @@
212 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 231 static int dlm_scand(void *data)
216 232 {
217 233 struct dlm_ls *ls;
  234 + int timeout_jiffies = dlm_config.ci_scan_secs * HZ;
218 235  
219 236 while (!kthread_should_stop()) {
220   - list_for_each_entry(ls, &lslist, ls_list) {
  237 + ls = find_ls_to_scan();
  238 + if (ls) {
221 239 if (dlm_lock_recovery_try(ls)) {
  240 + ls->ls_scan_time = jiffies;
222 241 dlm_scan_rsbs(ls);
223 242 dlm_scan_timeout(ls);
224 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 251 return 0;
230 252 }
... ... @@ -418,6 +440,7 @@
418 440 ls->ls_lvblen = lvblen;
419 441 ls->ls_count = 0;
420 442 ls->ls_flags = 0;
  443 + ls->ls_scan_time = jiffies;
421 444  
422 445 if (flags & DLM_LSFL_TIMEWARN)
423 446 set_bit(LSFL_TIMEWARN, &ls->ls_flags);