Don't let dlm_scand run during recovery since it may try to do a resource
directory removal while the directory nodes are changing.
Signed-off-by: David Teigland <teigland@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
/* Threads cannot use the lockspace while it's being recovered */
/* Threads cannot use the lockspace while it's being recovered */
-static inline void lock_recovery(struct dlm_ls *ls)
+static inline void dlm_lock_recovery(struct dlm_ls *ls)
{
down_read(&ls->ls_in_recovery);
}
{
down_read(&ls->ls_in_recovery);
}
-static inline void unlock_recovery(struct dlm_ls *ls)
+void dlm_unlock_recovery(struct dlm_ls *ls)
{
up_read(&ls->ls_in_recovery);
}
{
up_read(&ls->ls_in_recovery);
}
-static inline int lock_recovery_try(struct dlm_ls *ls)
+int dlm_lock_recovery_try(struct dlm_ls *ls)
{
return down_read_trylock(&ls->ls_in_recovery);
}
{
return down_read_trylock(&ls->ls_in_recovery);
}
- if (dlm_locking_stopped(ls))
- return;
-
for (i = 0; i < ls->ls_rsbtbl_size; i++) {
shrink_bucket(ls, i);
for (i = 0; i < ls->ls_rsbtbl_size; i++) {
shrink_bucket(ls, i);
+ if (dlm_locking_stopped(ls))
+ break;
if (convert)
error = find_lkb(ls, lksb->sb_lkid, &lkb);
if (convert)
error = find_lkb(ls, lksb->sb_lkid, &lkb);
if (error == -EAGAIN)
error = 0;
out:
if (error == -EAGAIN)
error = 0;
out:
+ dlm_unlock_recovery(ls);
dlm_put_lockspace(ls);
return error;
}
dlm_put_lockspace(ls);
return error;
}
error = find_lkb(ls, lkid, &lkb);
if (error)
error = find_lkb(ls, lkid, &lkb);
if (error)
out_put:
dlm_put_lkb(lkb);
out:
out_put:
dlm_put_lkb(lkb);
out:
+ dlm_unlock_recovery(ls);
dlm_put_lockspace(ls);
return error;
}
dlm_put_lockspace(ls);
return error;
}
- if (lock_recovery_try(ls))
+ if (dlm_lock_recovery_try(ls))
log_error(ls, "unknown message type %d", ms->m_type);
}
log_error(ls, "unknown message type %d", ms->m_type);
}
+ dlm_unlock_recovery(ls);
out:
dlm_put_lockspace(ls);
dlm_astd_wake();
out:
dlm_put_lockspace(ls);
dlm_astd_wake();
struct dlm_args args;
int error;
struct dlm_args args;
int error;
error = create_lkb(ls, &lkb);
if (error) {
error = create_lkb(ls, &lkb);
if (error) {
list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
spin_unlock(&ua->proc->locks_spin);
out:
list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks);
spin_unlock(&ua->proc->locks_spin);
out:
+ dlm_unlock_recovery(ls);
struct dlm_user_args *ua;
int error;
struct dlm_user_args *ua;
int error;
error = find_lkb(ls, lkid, &lkb);
if (error)
error = find_lkb(ls, lkid, &lkb);
if (error)
out_put:
dlm_put_lkb(lkb);
out:
out_put:
dlm_put_lkb(lkb);
out:
+ dlm_unlock_recovery(ls);
kfree(ua_tmp);
return error;
}
kfree(ua_tmp);
return error;
}
struct dlm_user_args *ua;
int error;
struct dlm_user_args *ua;
int error;
error = find_lkb(ls, lkid, &lkb);
if (error)
error = find_lkb(ls, lkid, &lkb);
if (error)
out_put:
dlm_put_lkb(lkb);
out:
out_put:
dlm_put_lkb(lkb);
out:
+ dlm_unlock_recovery(ls);
kfree(ua_tmp);
return error;
}
kfree(ua_tmp);
return error;
}
struct dlm_user_args *ua;
int error;
struct dlm_user_args *ua;
int error;
error = find_lkb(ls, lkid, &lkb);
if (error)
error = find_lkb(ls, lkid, &lkb);
if (error)
out_put:
dlm_put_lkb(lkb);
out:
out_put:
dlm_put_lkb(lkb);
out:
+ dlm_unlock_recovery(ls);
kfree(ua_tmp);
return error;
}
kfree(ua_tmp);
return error;
}
{
struct dlm_lkb *lkb, *safe;
{
struct dlm_lkb *lkb, *safe;
while (1) {
lkb = del_proc_lock(ls, proc);
while (1) {
lkb = del_proc_lock(ls, proc);
}
mutex_unlock(&ls->ls_clear_proc_locks);
}
mutex_unlock(&ls->ls_clear_proc_locks);
+ dlm_unlock_recovery(ls);
}
static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
}
static void purge_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
if (nodeid != dlm_our_nodeid()) {
error = send_purge(ls, nodeid, pid);
} else {
if (nodeid != dlm_our_nodeid()) {
error = send_purge(ls, nodeid, pid);
} else {
if (pid == current->pid)
purge_proc_locks(ls, proc);
else
do_purge(ls, nodeid, pid);
if (pid == current->pid)
purge_proc_locks(ls, proc);
else
do_purge(ls, nodeid, pid);
+ dlm_unlock_recovery(ls);
void dlm_hold_rsb(struct dlm_rsb *r);
int dlm_put_lkb(struct dlm_lkb *lkb);
void dlm_scan_rsbs(struct dlm_ls *ls);
void dlm_hold_rsb(struct dlm_rsb *r);
int dlm_put_lkb(struct dlm_lkb *lkb);
void dlm_scan_rsbs(struct dlm_ls *ls);
+int dlm_lock_recovery_try(struct dlm_ls *ls);
+void dlm_unlock_recovery(struct dlm_ls *ls);
int dlm_purge_locks(struct dlm_ls *ls);
void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
int dlm_purge_locks(struct dlm_ls *ls);
void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
struct dlm_ls *ls;
while (!kthread_should_stop()) {
struct dlm_ls *ls;
while (!kthread_should_stop()) {
- list_for_each_entry(ls, &lslist, ls_list)
- dlm_scan_rsbs(ls);
+ list_for_each_entry(ls, &lslist, ls_list) {
+ if (dlm_lock_recovery_try(ls)) {
+ dlm_scan_rsbs(ls);
+ dlm_unlock_recovery(ls);
+ }
+ }
schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
}
return 0;
schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);
}
return 0;