diff options
author | David Teigland <teigland@redhat.com> | 2006-08-24 15:47:20 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-08-25 10:02:53 -0400 |
commit | 5f88f1ea16a2fb5f125505053d1bfb7901a88c64 (patch) | |
tree | e3d9ce0e01a3903556885c784f8db759c26a795e /fs/dlm | |
parent | 5dc39fe621ead2fa2a0439a686be4df185861eae (diff) |
[DLM] add new lockspace to list ealier
When a new lockspace was being created, the recoverd thread was being
started for it before the lockspace was added to the global list of
lockspaces. The new thread was looking up the lockspace in the global
list and sometimes not finding it due to the race with the original thread
adding it to the list. We need to add the lockspace to the global list
before starting the thread instead of after, and if the new thread can't
find the lockspace for some reason, it should return an error.
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/dlm')
-rw-r--r-- | fs/dlm/lockspace.c | 13 | ||||
-rw-r--r-- | fs/dlm/recoverd.c | 4 |
2 files changed, 11 insertions, 6 deletions
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 7adaad53fc38..ff83f80e43eb 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -488,16 +488,17 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
488 | 488 | ||
489 | down_write(&ls->ls_in_recovery); | 489 | down_write(&ls->ls_in_recovery); |
490 | 490 | ||
491 | spin_lock(&lslist_lock); | ||
492 | list_add(&ls->ls_list, &lslist); | ||
493 | spin_unlock(&lslist_lock); | ||
494 | |||
495 | /* needs to find ls in lslist */ | ||
491 | error = dlm_recoverd_start(ls); | 496 | error = dlm_recoverd_start(ls); |
492 | if (error) { | 497 | if (error) { |
493 | log_error(ls, "can't start dlm_recoverd %d", error); | 498 | log_error(ls, "can't start dlm_recoverd %d", error); |
494 | goto out_rcomfree; | 499 | goto out_rcomfree; |
495 | } | 500 | } |
496 | 501 | ||
497 | spin_lock(&lslist_lock); | ||
498 | list_add(&ls->ls_list, &lslist); | ||
499 | spin_unlock(&lslist_lock); | ||
500 | |||
501 | dlm_create_debug_file(ls); | 502 | dlm_create_debug_file(ls); |
502 | 503 | ||
503 | error = kobject_setup(ls); | 504 | error = kobject_setup(ls); |
@@ -519,11 +520,11 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
519 | kobject_unregister(&ls->ls_kobj); | 520 | kobject_unregister(&ls->ls_kobj); |
520 | out_del: | 521 | out_del: |
521 | dlm_delete_debug_file(ls); | 522 | dlm_delete_debug_file(ls); |
523 | dlm_recoverd_stop(ls); | ||
524 | out_rcomfree: | ||
522 | spin_lock(&lslist_lock); | 525 | spin_lock(&lslist_lock); |
523 | list_del(&ls->ls_list); | 526 | list_del(&ls->ls_list); |
524 | spin_unlock(&lslist_lock); | 527 | spin_unlock(&lslist_lock); |
525 | dlm_recoverd_stop(ls); | ||
526 | out_rcomfree: | ||
527 | kfree(ls->ls_recover_buf); | 528 | kfree(ls->ls_recover_buf); |
528 | out_dirfree: | 529 | out_dirfree: |
529 | kfree(ls->ls_dirtbl); | 530 | kfree(ls->ls_dirtbl); |
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index eac8e9fa67f1..362e3eff4dc9 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c | |||
@@ -234,6 +234,10 @@ static int dlm_recoverd(void *arg) | |||
234 | struct dlm_ls *ls; | 234 | struct dlm_ls *ls; |
235 | 235 | ||
236 | ls = dlm_find_lockspace_local(arg); | 236 | ls = dlm_find_lockspace_local(arg); |
237 | if (!ls) { | ||
238 | log_print("dlm_recoverd: no lockspace %p", arg); | ||
239 | return -1; | ||
240 | } | ||
237 | 241 | ||
238 | while (!kthread_should_stop()) { | 242 | while (!kthread_should_stop()) { |
239 | set_current_state(TASK_INTERRUPTIBLE); | 243 | set_current_state(TASK_INTERRUPTIBLE); |