dlm: fix race between remove and lookup
It was possible for a remove message on an old rsb to be sent after a lookup message on a new rsb, where the rsbs were for the same resource name. This could lead to a missing directory entry for the new rsb. It is fixed by keeping a copy of the resource name being removed until after the remove has been sent. A lookup checks if this in-progress remove matches the name it is looking up. Signed-off-by: David Teigland <teigland@redhat.com>
このコミットが含まれているのは:
@@ -506,6 +506,15 @@ static int new_lockspace(const char *name, const char *cluster,
|
||||
spin_lock_init(&ls->ls_rsbtbl[i].lock);
|
||||
}
|
||||
|
||||
spin_lock_init(&ls->ls_remove_spin);
|
||||
|
||||
for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
|
||||
ls->ls_remove_names[i] = kzalloc(DLM_RESNAME_MAXLEN+1,
|
||||
GFP_KERNEL);
|
||||
if (!ls->ls_remove_names[i])
|
||||
goto out_rsbtbl;
|
||||
}
|
||||
|
||||
idr_init(&ls->ls_lkbidr);
|
||||
spin_lock_init(&ls->ls_lkbidr_spin);
|
||||
|
||||
@@ -556,7 +565,7 @@ static int new_lockspace(const char *name, const char *cluster,
|
||||
|
||||
ls->ls_recover_buf = kmalloc(dlm_config.ci_buffer_size, GFP_NOFS);
|
||||
if (!ls->ls_recover_buf)
|
||||
goto out_lkbfree;
|
||||
goto out_lkbidr;
|
||||
|
||||
ls->ls_slot = 0;
|
||||
ls->ls_num_slots = 0;
|
||||
@@ -640,8 +649,13 @@ static int new_lockspace(const char *name, const char *cluster,
|
||||
spin_unlock(&lslist_lock);
|
||||
idr_destroy(&ls->ls_recover_idr);
|
||||
kfree(ls->ls_recover_buf);
|
||||
out_lkbfree:
|
||||
out_lkbidr:
|
||||
idr_destroy(&ls->ls_lkbidr);
|
||||
for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++) {
|
||||
if (ls->ls_remove_names[i])
|
||||
kfree(ls->ls_remove_names[i]);
|
||||
}
|
||||
out_rsbtbl:
|
||||
vfree(ls->ls_rsbtbl);
|
||||
out_lsfree:
|
||||
if (do_unreg)
|
||||
@@ -796,6 +810,9 @@ static int release_lockspace(struct dlm_ls *ls, int force)
|
||||
|
||||
vfree(ls->ls_rsbtbl);
|
||||
|
||||
for (i = 0; i < DLM_REMOVE_NAMES_MAX; i++)
|
||||
kfree(ls->ls_remove_names[i]);
|
||||
|
||||
while (!list_empty(&ls->ls_new_rsb)) {
|
||||
rsb = list_first_entry(&ls->ls_new_rsb, struct dlm_rsb,
|
||||
res_hashchain);
|
||||
|
新しいイシューから参照
ユーザーをブロックする