mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
dlm for 6.12
- Remove some unnecesary hold/unhold rsb refcounting in cases where an existing refcount is known to exist. - Remove some unnecessary checking for zero nodeids, which should never exist, and add some warning if they do. - Make the slow freeing of structs in release_lockspace() async, run from a workqueue. - Prior rcu freeing allows some further struct lookups to run without a lock. - Use blocking kernel_connect on sockets to avoid EINPROGRESS. -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEcGkeEvkvjdvlR90nOBtzx/yAaaoFAmbpqCEACgkQOBtzx/yA aap1FBAAk6qmMoGHLl4pmJtDtPNZlsyCE7/SIdGjeMuszX5ENMl3sdoJ7qxX8ism r9v7YqN7K3lLuFb8xnuLw1i5VAp8jkNgTEQ2z4gOKRpHILCsQkJyFHF3CxpqbiOz DbyIgOOqo00kgU/sI3NwbuwSr18DZhY8QylIvqk32K2TjhdfxhffocVsfroDJWAH NdcH71rAVcPVe+Ls1XW6Bqn+QpDbcaki4V524MImBVVRGHxD1FjFjZ1ppohcqDK0 Xdrxeh3iVz0ovoyxkpHEvdW0+t3y4jLo4bR9iQnj7MVA5eNX4uwTdd1deSg/ueY2 6m7WMIZy6hA1Tj6TdAf+dXp+MPm+LhHaXv7wz1yJU6JdTUryvctynLgXBTVhNEcM y5TVuLC4ad1NgFsPeGAG7vH1puXoVCxoKT8pPGQhbBoUbILJALGR8ApF/kc+CZms AUYB2oQoaZXtaubrF3WoUQ4eakypo3z0MVzNzLsO+AYJAOiqQkLJaa6dVLu1qg7n 6UjBypNyJjevoWJIUqI0lYlXD7x3HFz3q6LYjhThITDnNo57KzqgqJ2p9KHtEp8/ WPNm7zPHzH088wk19uEbJP67FySPa34XUqebfOv32je5rHvrF7Ux3TkHI9Dm+by9 PwI3LtmXQyNbH9nwFdqFda7SuDTnlskTCEr3bZx+Dact6Zwk9Lc= =25XB -----END PGP SIGNATURE----- Merge tag 'dlm-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm Pull dlm updates from David Teigland: - Remove some unnecesary hold/unhold rsb refcounting in cases where an existing refcount is known to exist - Remove some unnecessary checking for zero nodeids, which should never exist, and add some warning if they do - Make the slow freeing of structs in release_lockspace() async, run from a workqueue - Prior rcu freeing allows some further struct lookups to run without a lock - Use blocking kernel_connect on sockets to avoid EINPROGRESS * tag 'dlm-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm: dlm: add missing -ENOMEM if alloc_workqueue() fails dlm: do synchronized socket connect call dlm: move lkb xarray lookup out of lock dlm: move dlm_search_rsb_tree() out of lock dlm: use RSB_HASHED to avoid lookup twice dlm: async freeing of lockspace resources dlm: drop kobject release callback handling dlm: warn about invalid nodeid comparsions dlm: never return invalid nodeid by dlm_our_nodeid() dlm: remove unnecessary refcounts dlm: cleanup memory allocation helpers
This commit is contained in:
commit
932d2d1fcb
@ -928,7 +928,7 @@ int dlm_comm_seq(int nodeid, uint32_t *seq)
|
|||||||
|
|
||||||
int dlm_our_nodeid(void)
|
int dlm_our_nodeid(void)
|
||||||
{
|
{
|
||||||
return local_comm ? local_comm->nodeid : 0;
|
return local_comm->nodeid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* num 0 is first addr, num 1 is second addr */
|
/* num 0 is first addr, num 1 is second addr */
|
||||||
|
@ -295,6 +295,7 @@ struct dlm_lkb {
|
|||||||
void *lkb_astparam; /* caller's ast arg */
|
void *lkb_astparam; /* caller's ast arg */
|
||||||
struct dlm_user_args *lkb_ua;
|
struct dlm_user_args *lkb_ua;
|
||||||
};
|
};
|
||||||
|
struct rcu_head rcu;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -660,6 +661,8 @@ struct dlm_ls {
|
|||||||
const struct dlm_lockspace_ops *ls_ops;
|
const struct dlm_lockspace_ops *ls_ops;
|
||||||
void *ls_ops_arg;
|
void *ls_ops_arg;
|
||||||
|
|
||||||
|
struct work_struct ls_free_work;
|
||||||
|
|
||||||
int ls_namelen;
|
int ls_namelen;
|
||||||
char ls_name[DLM_LOCKSPACE_LEN + 1];
|
char ls_name[DLM_LOCKSPACE_LEN + 1];
|
||||||
};
|
};
|
||||||
@ -803,6 +806,8 @@ static inline void dlm_set_sbflags_val(struct dlm_lkb *lkb, uint32_t val)
|
|||||||
__DLM_SBF_MAX_BIT);
|
__DLM_SBF_MAX_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern struct workqueue_struct *dlm_wq;
|
||||||
|
|
||||||
int dlm_plock_init(void);
|
int dlm_plock_init(void);
|
||||||
void dlm_plock_exit(void);
|
void dlm_plock_exit(void);
|
||||||
|
|
||||||
|
134
fs/dlm/lock.c
134
fs/dlm/lock.c
@ -600,7 +600,7 @@ static int get_rsb_struct(struct dlm_ls *ls, const void *name, int len,
|
|||||||
{
|
{
|
||||||
struct dlm_rsb *r;
|
struct dlm_rsb *r;
|
||||||
|
|
||||||
r = dlm_allocate_rsb(ls);
|
r = dlm_allocate_rsb();
|
||||||
if (!r)
|
if (!r)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -733,11 +733,13 @@ static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
||||||
|
if (error)
|
||||||
|
goto do_new;
|
||||||
|
|
||||||
/* check if the rsb is active under read lock - likely path */
|
/* check if the rsb is active under read lock - likely path */
|
||||||
read_lock_bh(&ls->ls_rsbtbl_lock);
|
read_lock_bh(&ls->ls_rsbtbl_lock);
|
||||||
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
if (!rsb_flag(r, RSB_HASHED)) {
|
||||||
if (error) {
|
|
||||||
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
||||||
goto do_new;
|
goto do_new;
|
||||||
}
|
}
|
||||||
@ -918,11 +920,13 @@ static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len,
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
||||||
|
if (error)
|
||||||
|
goto do_new;
|
||||||
|
|
||||||
/* check if the rsb is in active state under read lock - likely path */
|
/* check if the rsb is in active state under read lock - likely path */
|
||||||
read_lock_bh(&ls->ls_rsbtbl_lock);
|
read_lock_bh(&ls->ls_rsbtbl_lock);
|
||||||
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
if (!rsb_flag(r, RSB_HASHED)) {
|
||||||
if (error) {
|
|
||||||
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
||||||
goto do_new;
|
goto do_new;
|
||||||
}
|
}
|
||||||
@ -1151,7 +1155,7 @@ static void __dlm_master_lookup(struct dlm_ls *ls, struct dlm_rsb *r, int our_no
|
|||||||
r->res_dir_nodeid = our_nodeid;
|
r->res_dir_nodeid = our_nodeid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fix_master && dlm_is_removed(ls, r->res_master_nodeid)) {
|
if (fix_master && r->res_master_nodeid && dlm_is_removed(ls, r->res_master_nodeid)) {
|
||||||
/* Recovery uses this function to set a new master when
|
/* Recovery uses this function to set a new master when
|
||||||
* the previous master failed. Setting NEW_MASTER will
|
* the previous master failed. Setting NEW_MASTER will
|
||||||
* force dlm_recover_masters to call recover_master on this
|
* force dlm_recover_masters to call recover_master on this
|
||||||
@ -1276,43 +1280,45 @@ static int _dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *na
|
|||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
||||||
|
if (error)
|
||||||
|
goto not_found;
|
||||||
|
|
||||||
/* check if the rsb is active under read lock - likely path */
|
/* check if the rsb is active under read lock - likely path */
|
||||||
read_lock_bh(&ls->ls_rsbtbl_lock);
|
read_lock_bh(&ls->ls_rsbtbl_lock);
|
||||||
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
if (!rsb_flag(r, RSB_HASHED)) {
|
||||||
if (!error) {
|
|
||||||
if (rsb_flag(r, RSB_INACTIVE)) {
|
|
||||||
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
|
||||||
goto do_inactive;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* because the rsb is active, we need to lock_rsb before
|
|
||||||
* checking/changing re_master_nodeid
|
|
||||||
*/
|
|
||||||
|
|
||||||
hold_rsb(r);
|
|
||||||
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
|
||||||
lock_rsb(r);
|
|
||||||
|
|
||||||
__dlm_master_lookup(ls, r, our_nodeid, from_nodeid, false,
|
|
||||||
flags, r_nodeid, result);
|
|
||||||
|
|
||||||
/* the rsb was active */
|
|
||||||
unlock_rsb(r);
|
|
||||||
put_rsb(r);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
||||||
goto not_found;
|
goto not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rsb_flag(r, RSB_INACTIVE)) {
|
||||||
|
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
||||||
|
goto do_inactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* because the rsb is active, we need to lock_rsb before
|
||||||
|
* checking/changing re_master_nodeid
|
||||||
|
*/
|
||||||
|
|
||||||
|
hold_rsb(r);
|
||||||
|
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
||||||
|
lock_rsb(r);
|
||||||
|
|
||||||
|
__dlm_master_lookup(ls, r, our_nodeid, from_nodeid, false,
|
||||||
|
flags, r_nodeid, result);
|
||||||
|
|
||||||
|
/* the rsb was active */
|
||||||
|
unlock_rsb(r);
|
||||||
|
put_rsb(r);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
do_inactive:
|
do_inactive:
|
||||||
/* unlikely path - relookup under write */
|
/* unlikely path - check if still part of ls_rsbtbl */
|
||||||
write_lock_bh(&ls->ls_rsbtbl_lock);
|
write_lock_bh(&ls->ls_rsbtbl_lock);
|
||||||
|
|
||||||
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
/* see comment in find_rsb_dir */
|
||||||
if (!error) {
|
if (rsb_flag(r, RSB_HASHED)) {
|
||||||
if (!rsb_flag(r, RSB_INACTIVE)) {
|
if (!rsb_flag(r, RSB_INACTIVE)) {
|
||||||
write_unlock_bh(&ls->ls_rsbtbl_lock);
|
write_unlock_bh(&ls->ls_rsbtbl_lock);
|
||||||
/* something as changed, very unlikely but
|
/* something as changed, very unlikely but
|
||||||
@ -1403,14 +1409,14 @@ void dlm_dump_rsb_name(struct dlm_ls *ls, const char *name, int len)
|
|||||||
struct dlm_rsb *r = NULL;
|
struct dlm_rsb *r = NULL;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
read_lock_bh(&ls->ls_rsbtbl_lock);
|
rcu_read_lock();
|
||||||
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
error = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
||||||
if (!error)
|
if (!error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
dlm_dump_rsb(r);
|
dlm_dump_rsb(r);
|
||||||
out:
|
out:
|
||||||
read_unlock_bh(&ls->ls_rsbtbl_lock);
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deactivate_rsb(struct kref *kref)
|
static void deactivate_rsb(struct kref *kref)
|
||||||
@ -1442,18 +1448,6 @@ static void deactivate_rsb(struct kref *kref)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See comment for unhold_lkb */
|
|
||||||
|
|
||||||
static void unhold_rsb(struct dlm_rsb *r)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
/* inactive rsbs are not ref counted */
|
|
||||||
WARN_ON(rsb_flag(r, RSB_INACTIVE));
|
|
||||||
rv = kref_put(&r->res_ref, deactivate_rsb);
|
|
||||||
DLM_ASSERT(!rv, dlm_dump_rsb(r););
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_inactive_rsb(struct dlm_rsb *r)
|
void free_inactive_rsb(struct dlm_rsb *r)
|
||||||
{
|
{
|
||||||
WARN_ON_ONCE(!rsb_flag(r, RSB_INACTIVE));
|
WARN_ON_ONCE(!rsb_flag(r, RSB_INACTIVE));
|
||||||
@ -1497,7 +1491,7 @@ static int _create_lkb(struct dlm_ls *ls, struct dlm_lkb **lkb_ret,
|
|||||||
limit.max = end;
|
limit.max = end;
|
||||||
limit.min = start;
|
limit.min = start;
|
||||||
|
|
||||||
lkb = dlm_allocate_lkb(ls);
|
lkb = dlm_allocate_lkb();
|
||||||
if (!lkb)
|
if (!lkb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -1533,11 +1527,21 @@ static int find_lkb(struct dlm_ls *ls, uint32_t lkid, struct dlm_lkb **lkb_ret)
|
|||||||
{
|
{
|
||||||
struct dlm_lkb *lkb;
|
struct dlm_lkb *lkb;
|
||||||
|
|
||||||
read_lock_bh(&ls->ls_lkbxa_lock);
|
rcu_read_lock();
|
||||||
lkb = xa_load(&ls->ls_lkbxa, lkid);
|
lkb = xa_load(&ls->ls_lkbxa, lkid);
|
||||||
if (lkb)
|
if (lkb) {
|
||||||
kref_get(&lkb->lkb_ref);
|
/* check if lkb is still part of lkbxa under lkbxa_lock as
|
||||||
read_unlock_bh(&ls->ls_lkbxa_lock);
|
* the lkb_ref is tight to the lkbxa data structure, see
|
||||||
|
* __put_lkb().
|
||||||
|
*/
|
||||||
|
read_lock_bh(&ls->ls_lkbxa_lock);
|
||||||
|
if (kref_read(&lkb->lkb_ref))
|
||||||
|
kref_get(&lkb->lkb_ref);
|
||||||
|
else
|
||||||
|
lkb = NULL;
|
||||||
|
read_unlock_bh(&ls->ls_lkbxa_lock);
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
*lkb_ret = lkb;
|
*lkb_ret = lkb;
|
||||||
return lkb ? 0 : -ENOENT;
|
return lkb ? 0 : -ENOENT;
|
||||||
@ -1675,10 +1679,8 @@ static void del_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb)
|
|||||||
|
|
||||||
static void move_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb, int sts)
|
static void move_lkb(struct dlm_rsb *r, struct dlm_lkb *lkb, int sts)
|
||||||
{
|
{
|
||||||
hold_lkb(lkb);
|
|
||||||
del_lkb(r, lkb);
|
del_lkb(r, lkb);
|
||||||
add_lkb(r, lkb, sts);
|
add_lkb(r, lkb, sts);
|
||||||
unhold_lkb(lkb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int msg_reply_type(int mstype)
|
static int msg_reply_type(int mstype)
|
||||||
@ -4323,17 +4325,28 @@ static void receive_remove(struct dlm_ls *ls, const struct dlm_message *ms)
|
|||||||
memset(name, 0, sizeof(name));
|
memset(name, 0, sizeof(name));
|
||||||
memcpy(name, ms->m_extra, len);
|
memcpy(name, ms->m_extra, len);
|
||||||
|
|
||||||
write_lock_bh(&ls->ls_rsbtbl_lock);
|
rcu_read_lock();
|
||||||
|
|
||||||
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl, name, len, &r);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
|
rcu_read_unlock();
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
log_error(ls, "%s from %d not found %s", __func__,
|
log_error(ls, "%s from %d not found %s", __func__,
|
||||||
from_nodeid, name);
|
from_nodeid, name);
|
||||||
write_unlock_bh(&ls->ls_rsbtbl_lock);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write_lock_bh(&ls->ls_rsbtbl_lock);
|
||||||
|
if (!rsb_flag(r, RSB_HASHED)) {
|
||||||
|
rcu_read_unlock();
|
||||||
|
write_unlock_bh(&ls->ls_rsbtbl_lock);
|
||||||
|
/* should not happen */
|
||||||
|
log_error(ls, "%s from %d got removed during removal %s",
|
||||||
|
__func__, from_nodeid, name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* at this stage the rsb can only being freed here */
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (!rsb_flag(r, RSB_INACTIVE)) {
|
if (!rsb_flag(r, RSB_INACTIVE)) {
|
||||||
if (r->res_master_nodeid != from_nodeid) {
|
if (r->res_master_nodeid != from_nodeid) {
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
@ -5297,7 +5310,7 @@ int dlm_recover_waiters_post(struct dlm_ls *ls)
|
|||||||
case DLM_MSG_LOOKUP:
|
case DLM_MSG_LOOKUP:
|
||||||
case DLM_MSG_REQUEST:
|
case DLM_MSG_REQUEST:
|
||||||
_request_lock(r, lkb);
|
_request_lock(r, lkb);
|
||||||
if (is_master(r))
|
if (r->res_nodeid != -1 && is_master(r))
|
||||||
confirm_master(r, 0);
|
confirm_master(r, 0);
|
||||||
break;
|
break;
|
||||||
case DLM_MSG_CONVERT:
|
case DLM_MSG_CONVERT:
|
||||||
@ -5409,9 +5422,8 @@ void dlm_recover_purge(struct dlm_ls *ls, const struct list_head *root_list)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
list_for_each_entry(r, root_list, res_root_list) {
|
list_for_each_entry(r, root_list, res_root_list) {
|
||||||
hold_rsb(r);
|
|
||||||
lock_rsb(r);
|
lock_rsb(r);
|
||||||
if (is_master(r)) {
|
if (r->res_nodeid != -1 && is_master(r)) {
|
||||||
purge_dead_list(ls, r, &r->res_grantqueue,
|
purge_dead_list(ls, r, &r->res_grantqueue,
|
||||||
nodeid_gone, &lkb_count);
|
nodeid_gone, &lkb_count);
|
||||||
purge_dead_list(ls, r, &r->res_convertqueue,
|
purge_dead_list(ls, r, &r->res_convertqueue,
|
||||||
@ -5420,7 +5432,7 @@ void dlm_recover_purge(struct dlm_ls *ls, const struct list_head *root_list)
|
|||||||
nodeid_gone, &lkb_count);
|
nodeid_gone, &lkb_count);
|
||||||
}
|
}
|
||||||
unlock_rsb(r);
|
unlock_rsb(r);
|
||||||
unhold_rsb(r);
|
|
||||||
cond_resched();
|
cond_resched();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,8 @@ int dlm_debug_add_lkb_to_waiters(struct dlm_ls *ls, uint32_t lkb_id,
|
|||||||
|
|
||||||
static inline int is_master(struct dlm_rsb *r)
|
static inline int is_master(struct dlm_rsb *r)
|
||||||
{
|
{
|
||||||
|
WARN_ON_ONCE(r->res_nodeid == -1);
|
||||||
|
|
||||||
return !r->res_nodeid;
|
return !r->res_nodeid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,12 +174,6 @@ static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr,
|
|||||||
return a->store ? a->store(ls, buf, len) : len;
|
return a->store ? a->store(ls, buf, len) : len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lockspace_kobj_release(struct kobject *k)
|
|
||||||
{
|
|
||||||
struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj);
|
|
||||||
kfree(ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct sysfs_ops dlm_attr_ops = {
|
static const struct sysfs_ops dlm_attr_ops = {
|
||||||
.show = dlm_attr_show,
|
.show = dlm_attr_show,
|
||||||
.store = dlm_attr_store,
|
.store = dlm_attr_store,
|
||||||
@ -188,7 +182,6 @@ static const struct sysfs_ops dlm_attr_ops = {
|
|||||||
static struct kobj_type dlm_ktype = {
|
static struct kobj_type dlm_ktype = {
|
||||||
.default_groups = dlm_groups,
|
.default_groups = dlm_groups,
|
||||||
.sysfs_ops = &dlm_attr_ops,
|
.sysfs_ops = &dlm_attr_ops,
|
||||||
.release = lockspace_kobj_release,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct kset *dlm_kset;
|
static struct kset *dlm_kset;
|
||||||
@ -322,13 +315,50 @@ static int threads_start(void)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lkb_idr_free(struct dlm_lkb *lkb)
|
||||||
|
{
|
||||||
|
if (lkb->lkb_lvbptr && test_bit(DLM_IFL_MSTCPY_BIT, &lkb->lkb_iflags))
|
||||||
|
dlm_free_lvb(lkb->lkb_lvbptr);
|
||||||
|
|
||||||
|
dlm_free_lkb(lkb);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rhash_free_rsb(void *ptr, void *arg)
|
||||||
|
{
|
||||||
|
struct dlm_rsb *rsb = ptr;
|
||||||
|
|
||||||
|
dlm_free_rsb(rsb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_lockspace(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct dlm_ls *ls = container_of(work, struct dlm_ls, ls_free_work);
|
||||||
|
struct dlm_lkb *lkb;
|
||||||
|
unsigned long id;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free all lkb's in xa
|
||||||
|
*/
|
||||||
|
xa_for_each(&ls->ls_lkbxa, id, lkb) {
|
||||||
|
lkb_idr_free(lkb);
|
||||||
|
}
|
||||||
|
xa_destroy(&ls->ls_lkbxa);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free all rsb's on rsbtbl
|
||||||
|
*/
|
||||||
|
rhashtable_free_and_destroy(&ls->ls_rsbtbl, rhash_free_rsb, NULL);
|
||||||
|
|
||||||
|
kfree(ls);
|
||||||
|
}
|
||||||
|
|
||||||
static int new_lockspace(const char *name, const char *cluster,
|
static int new_lockspace(const char *name, const char *cluster,
|
||||||
uint32_t flags, int lvblen,
|
uint32_t flags, int lvblen,
|
||||||
const struct dlm_lockspace_ops *ops, void *ops_arg,
|
const struct dlm_lockspace_ops *ops, void *ops_arg,
|
||||||
int *ops_result, dlm_lockspace_t **lockspace)
|
int *ops_result, dlm_lockspace_t **lockspace)
|
||||||
{
|
{
|
||||||
struct dlm_ls *ls;
|
struct dlm_ls *ls;
|
||||||
int do_unreg = 0;
|
|
||||||
int namelen = strlen(name);
|
int namelen = strlen(name);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -453,6 +483,8 @@ static int new_lockspace(const char *name, const char *cluster,
|
|||||||
spin_lock_init(&ls->ls_cb_lock);
|
spin_lock_init(&ls->ls_cb_lock);
|
||||||
INIT_LIST_HEAD(&ls->ls_cb_delay);
|
INIT_LIST_HEAD(&ls->ls_cb_delay);
|
||||||
|
|
||||||
|
INIT_WORK(&ls->ls_free_work, free_lockspace);
|
||||||
|
|
||||||
ls->ls_recoverd_task = NULL;
|
ls->ls_recoverd_task = NULL;
|
||||||
mutex_init(&ls->ls_recoverd_active);
|
mutex_init(&ls->ls_recoverd_active);
|
||||||
spin_lock_init(&ls->ls_recover_lock);
|
spin_lock_init(&ls->ls_recover_lock);
|
||||||
@ -530,9 +562,6 @@ static int new_lockspace(const char *name, const char *cluster,
|
|||||||
wait_event(ls->ls_recover_lock_wait,
|
wait_event(ls->ls_recover_lock_wait,
|
||||||
test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
|
test_bit(LSFL_RECOVER_LOCK, &ls->ls_flags));
|
||||||
|
|
||||||
/* let kobject handle freeing of ls if there's an error */
|
|
||||||
do_unreg = 1;
|
|
||||||
|
|
||||||
ls->ls_kobj.kset = dlm_kset;
|
ls->ls_kobj.kset = dlm_kset;
|
||||||
error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL,
|
error = kobject_init_and_add(&ls->ls_kobj, &dlm_ktype, NULL,
|
||||||
"%s", ls->ls_name);
|
"%s", ls->ls_name);
|
||||||
@ -580,10 +609,8 @@ static int new_lockspace(const char *name, const char *cluster,
|
|||||||
xa_destroy(&ls->ls_lkbxa);
|
xa_destroy(&ls->ls_lkbxa);
|
||||||
rhashtable_destroy(&ls->ls_rsbtbl);
|
rhashtable_destroy(&ls->ls_rsbtbl);
|
||||||
out_lsfree:
|
out_lsfree:
|
||||||
if (do_unreg)
|
kobject_put(&ls->ls_kobj);
|
||||||
kobject_put(&ls->ls_kobj);
|
kfree(ls);
|
||||||
else
|
|
||||||
kfree(ls);
|
|
||||||
out:
|
out:
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
return error;
|
return error;
|
||||||
@ -640,15 +667,6 @@ int dlm_new_user_lockspace(const char *name, const char *cluster,
|
|||||||
ops_arg, ops_result, lockspace);
|
ops_arg, ops_result, lockspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lkb_idr_free(struct dlm_lkb *lkb)
|
|
||||||
{
|
|
||||||
if (lkb->lkb_lvbptr && test_bit(DLM_IFL_MSTCPY_BIT, &lkb->lkb_iflags))
|
|
||||||
dlm_free_lvb(lkb->lkb_lvbptr);
|
|
||||||
|
|
||||||
dlm_free_lkb(lkb);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE: We check the lkbxa here rather than the resource table.
|
/* NOTE: We check the lkbxa here rather than the resource table.
|
||||||
This is because there may be LKBs queued as ASTs that have been unlinked
|
This is because there may be LKBs queued as ASTs that have been unlinked
|
||||||
from their RSBs and are pending deletion once the AST has been delivered */
|
from their RSBs and are pending deletion once the AST has been delivered */
|
||||||
@ -680,17 +698,8 @@ static int lockspace_busy(struct dlm_ls *ls, int force)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rhash_free_rsb(void *ptr, void *arg)
|
|
||||||
{
|
|
||||||
struct dlm_rsb *rsb = ptr;
|
|
||||||
|
|
||||||
dlm_free_rsb(rsb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int release_lockspace(struct dlm_ls *ls, int force)
|
static int release_lockspace(struct dlm_ls *ls, int force)
|
||||||
{
|
{
|
||||||
struct dlm_lkb *lkb;
|
|
||||||
unsigned long id;
|
|
||||||
int busy, rv;
|
int busy, rv;
|
||||||
|
|
||||||
busy = lockspace_busy(ls, force);
|
busy = lockspace_busy(ls, force);
|
||||||
@ -743,22 +752,11 @@ static int release_lockspace(struct dlm_ls *ls, int force)
|
|||||||
|
|
||||||
dlm_delete_debug_file(ls);
|
dlm_delete_debug_file(ls);
|
||||||
|
|
||||||
|
kobject_put(&ls->ls_kobj);
|
||||||
|
|
||||||
xa_destroy(&ls->ls_recover_xa);
|
xa_destroy(&ls->ls_recover_xa);
|
||||||
kfree(ls->ls_recover_buf);
|
kfree(ls->ls_recover_buf);
|
||||||
|
|
||||||
/*
|
|
||||||
* Free all lkb's in xa
|
|
||||||
*/
|
|
||||||
xa_for_each(&ls->ls_lkbxa, id, lkb) {
|
|
||||||
lkb_idr_free(lkb);
|
|
||||||
}
|
|
||||||
xa_destroy(&ls->ls_lkbxa);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Free all rsb's on rsbtbl
|
|
||||||
*/
|
|
||||||
rhashtable_free_and_destroy(&ls->ls_rsbtbl, rhash_free_rsb, NULL);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free structures on any other lists
|
* Free structures on any other lists
|
||||||
*/
|
*/
|
||||||
@ -768,10 +766,11 @@ static int release_lockspace(struct dlm_ls *ls, int force)
|
|||||||
dlm_clear_members(ls);
|
dlm_clear_members(ls);
|
||||||
dlm_clear_members_gone(ls);
|
dlm_clear_members_gone(ls);
|
||||||
kfree(ls->ls_node_array);
|
kfree(ls->ls_node_array);
|
||||||
log_rinfo(ls, "release_lockspace final free");
|
|
||||||
kobject_put(&ls->ls_kobj);
|
|
||||||
/* The ls structure will be freed when the kobject is done with */
|
|
||||||
|
|
||||||
|
log_rinfo(ls, "%s final free", __func__);
|
||||||
|
|
||||||
|
/* delayed free of data structures see free_lockspace() */
|
||||||
|
queue_work(dlm_wq, &ls->ls_free_work);
|
||||||
module_put(THIS_MODULE);
|
module_put(THIS_MODULE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -161,8 +161,6 @@ struct dlm_proto_ops {
|
|||||||
const char *name;
|
const char *name;
|
||||||
int proto;
|
int proto;
|
||||||
|
|
||||||
int (*connect)(struct connection *con, struct socket *sock,
|
|
||||||
struct sockaddr *addr, int addr_len);
|
|
||||||
void (*sockopts)(struct socket *sock);
|
void (*sockopts)(struct socket *sock);
|
||||||
int (*bind)(struct socket *sock);
|
int (*bind)(struct socket *sock);
|
||||||
int (*listen_validate)(void);
|
int (*listen_validate)(void);
|
||||||
@ -1599,8 +1597,7 @@ static int dlm_connect(struct connection *con)
|
|||||||
|
|
||||||
log_print_ratelimited("connecting to %d", con->nodeid);
|
log_print_ratelimited("connecting to %d", con->nodeid);
|
||||||
make_sockaddr(&addr, dlm_config.ci_tcp_port, &addr_len);
|
make_sockaddr(&addr, dlm_config.ci_tcp_port, &addr_len);
|
||||||
result = dlm_proto_ops->connect(con, sock, (struct sockaddr *)&addr,
|
result = kernel_connect(sock, (struct sockaddr *)&addr, addr_len, 0);
|
||||||
addr_len);
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case -EINPROGRESS:
|
case -EINPROGRESS:
|
||||||
/* not an error */
|
/* not an error */
|
||||||
@ -1634,13 +1631,6 @@ static void process_send_sockets(struct work_struct *work)
|
|||||||
switch (ret) {
|
switch (ret) {
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case -EINPROGRESS:
|
|
||||||
/* avoid spamming resched on connection
|
|
||||||
* we might can switch to a state_change
|
|
||||||
* event based mechanism if established
|
|
||||||
*/
|
|
||||||
msleep(100);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* CF_SEND_PENDING not cleared */
|
/* CF_SEND_PENDING not cleared */
|
||||||
up_write(&con->sock_lock);
|
up_write(&con->sock_lock);
|
||||||
@ -1831,12 +1821,6 @@ static int dlm_tcp_bind(struct socket *sock)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dlm_tcp_connect(struct connection *con, struct socket *sock,
|
|
||||||
struct sockaddr *addr, int addr_len)
|
|
||||||
{
|
|
||||||
return kernel_connect(sock, addr, addr_len, O_NONBLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dlm_tcp_listen_validate(void)
|
static int dlm_tcp_listen_validate(void)
|
||||||
{
|
{
|
||||||
/* We don't support multi-homed hosts */
|
/* We don't support multi-homed hosts */
|
||||||
@ -1873,7 +1857,6 @@ static int dlm_tcp_listen_bind(struct socket *sock)
|
|||||||
static const struct dlm_proto_ops dlm_tcp_ops = {
|
static const struct dlm_proto_ops dlm_tcp_ops = {
|
||||||
.name = "TCP",
|
.name = "TCP",
|
||||||
.proto = IPPROTO_TCP,
|
.proto = IPPROTO_TCP,
|
||||||
.connect = dlm_tcp_connect,
|
|
||||||
.sockopts = dlm_tcp_sockopts,
|
.sockopts = dlm_tcp_sockopts,
|
||||||
.bind = dlm_tcp_bind,
|
.bind = dlm_tcp_bind,
|
||||||
.listen_validate = dlm_tcp_listen_validate,
|
.listen_validate = dlm_tcp_listen_validate,
|
||||||
@ -1886,22 +1869,6 @@ static int dlm_sctp_bind(struct socket *sock)
|
|||||||
return sctp_bind_addrs(sock, 0);
|
return sctp_bind_addrs(sock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dlm_sctp_connect(struct connection *con, struct socket *sock,
|
|
||||||
struct sockaddr *addr, int addr_len)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Make kernel_connect() function return in specified time,
|
|
||||||
* since O_NONBLOCK argument in connect() function does not work here,
|
|
||||||
* then, we should restore the default value of this attribute.
|
|
||||||
*/
|
|
||||||
sock_set_sndtimeo(sock->sk, 5);
|
|
||||||
ret = kernel_connect(sock, addr, addr_len, 0);
|
|
||||||
sock_set_sndtimeo(sock->sk, 0);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dlm_sctp_listen_validate(void)
|
static int dlm_sctp_listen_validate(void)
|
||||||
{
|
{
|
||||||
if (!IS_ENABLED(CONFIG_IP_SCTP)) {
|
if (!IS_ENABLED(CONFIG_IP_SCTP)) {
|
||||||
@ -1929,7 +1896,6 @@ static const struct dlm_proto_ops dlm_sctp_ops = {
|
|||||||
.name = "SCTP",
|
.name = "SCTP",
|
||||||
.proto = IPPROTO_SCTP,
|
.proto = IPPROTO_SCTP,
|
||||||
.try_new_addr = true,
|
.try_new_addr = true,
|
||||||
.connect = dlm_sctp_connect,
|
|
||||||
.sockopts = dlm_sctp_sockopts,
|
.sockopts = dlm_sctp_sockopts,
|
||||||
.bind = dlm_sctp_bind,
|
.bind = dlm_sctp_bind,
|
||||||
.listen_validate = dlm_sctp_listen_validate,
|
.listen_validate = dlm_sctp_listen_validate,
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
#include <trace/events/dlm.h>
|
#include <trace/events/dlm.h>
|
||||||
|
|
||||||
|
struct workqueue_struct *dlm_wq;
|
||||||
|
|
||||||
static int __init init_dlm(void)
|
static int __init init_dlm(void)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
@ -50,10 +52,18 @@ static int __init init_dlm(void)
|
|||||||
if (error)
|
if (error)
|
||||||
goto out_user;
|
goto out_user;
|
||||||
|
|
||||||
|
dlm_wq = alloc_workqueue("dlm_wq", 0, 0);
|
||||||
|
if (!dlm_wq) {
|
||||||
|
error = -ENOMEM;
|
||||||
|
goto out_plock;
|
||||||
|
}
|
||||||
|
|
||||||
printk("DLM installed\n");
|
printk("DLM installed\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_plock:
|
||||||
|
dlm_plock_exit();
|
||||||
out_user:
|
out_user:
|
||||||
dlm_user_exit();
|
dlm_user_exit();
|
||||||
out_debug:
|
out_debug:
|
||||||
@ -70,6 +80,8 @@ static int __init init_dlm(void)
|
|||||||
|
|
||||||
static void __exit exit_dlm(void)
|
static void __exit exit_dlm(void)
|
||||||
{
|
{
|
||||||
|
/* be sure every pending work e.g. freeing is done */
|
||||||
|
destroy_workqueue(dlm_wq);
|
||||||
dlm_plock_exit();
|
dlm_plock_exit();
|
||||||
dlm_user_exit();
|
dlm_user_exit();
|
||||||
dlm_config_exit();
|
dlm_config_exit();
|
||||||
|
@ -366,6 +366,8 @@ int dlm_is_member(struct dlm_ls *ls, int nodeid)
|
|||||||
|
|
||||||
int dlm_is_removed(struct dlm_ls *ls, int nodeid)
|
int dlm_is_removed(struct dlm_ls *ls, int nodeid)
|
||||||
{
|
{
|
||||||
|
WARN_ON_ONCE(!nodeid || nodeid == -1);
|
||||||
|
|
||||||
if (find_memb(&ls->ls_nodes_gone, nodeid))
|
if (find_memb(&ls->ls_nodes_gone, nodeid))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -84,10 +84,7 @@ void dlm_memory_exit(void)
|
|||||||
|
|
||||||
char *dlm_allocate_lvb(struct dlm_ls *ls)
|
char *dlm_allocate_lvb(struct dlm_ls *ls)
|
||||||
{
|
{
|
||||||
char *p;
|
return kzalloc(ls->ls_lvblen, GFP_ATOMIC);
|
||||||
|
|
||||||
p = kzalloc(ls->ls_lvblen, GFP_ATOMIC);
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlm_free_lvb(char *p)
|
void dlm_free_lvb(char *p)
|
||||||
@ -95,12 +92,9 @@ void dlm_free_lvb(char *p)
|
|||||||
kfree(p);
|
kfree(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls)
|
struct dlm_rsb *dlm_allocate_rsb(void)
|
||||||
{
|
{
|
||||||
struct dlm_rsb *r;
|
return kmem_cache_zalloc(rsb_cache, GFP_ATOMIC);
|
||||||
|
|
||||||
r = kmem_cache_zalloc(rsb_cache, GFP_ATOMIC);
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __free_rsb_rcu(struct rcu_head *rcu)
|
static void __free_rsb_rcu(struct rcu_head *rcu)
|
||||||
@ -116,16 +110,15 @@ void dlm_free_rsb(struct dlm_rsb *r)
|
|||||||
call_rcu(&r->rcu, __free_rsb_rcu);
|
call_rcu(&r->rcu, __free_rsb_rcu);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls)
|
struct dlm_lkb *dlm_allocate_lkb(void)
|
||||||
{
|
{
|
||||||
struct dlm_lkb *lkb;
|
return kmem_cache_zalloc(lkb_cache, GFP_ATOMIC);
|
||||||
|
|
||||||
lkb = kmem_cache_zalloc(lkb_cache, GFP_ATOMIC);
|
|
||||||
return lkb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlm_free_lkb(struct dlm_lkb *lkb)
|
static void __free_lkb_rcu(struct rcu_head *rcu)
|
||||||
{
|
{
|
||||||
|
struct dlm_lkb *lkb = container_of(rcu, struct dlm_lkb, rcu);
|
||||||
|
|
||||||
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
|
if (test_bit(DLM_DFL_USER_BIT, &lkb->lkb_dflags)) {
|
||||||
struct dlm_user_args *ua;
|
struct dlm_user_args *ua;
|
||||||
ua = lkb->lkb_ua;
|
ua = lkb->lkb_ua;
|
||||||
@ -138,6 +131,11 @@ void dlm_free_lkb(struct dlm_lkb *lkb)
|
|||||||
kmem_cache_free(lkb_cache, lkb);
|
kmem_cache_free(lkb_cache, lkb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dlm_free_lkb(struct dlm_lkb *lkb)
|
||||||
|
{
|
||||||
|
call_rcu(&lkb->rcu, __free_lkb_rcu);
|
||||||
|
}
|
||||||
|
|
||||||
struct dlm_mhandle *dlm_allocate_mhandle(void)
|
struct dlm_mhandle *dlm_allocate_mhandle(void)
|
||||||
{
|
{
|
||||||
return kmem_cache_alloc(mhandle_cache, GFP_ATOMIC);
|
return kmem_cache_alloc(mhandle_cache, GFP_ATOMIC);
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
int dlm_memory_init(void);
|
int dlm_memory_init(void);
|
||||||
void dlm_memory_exit(void);
|
void dlm_memory_exit(void);
|
||||||
struct dlm_rsb *dlm_allocate_rsb(struct dlm_ls *ls);
|
struct dlm_rsb *dlm_allocate_rsb(void);
|
||||||
void dlm_free_rsb(struct dlm_rsb *r);
|
void dlm_free_rsb(struct dlm_rsb *r);
|
||||||
struct dlm_lkb *dlm_allocate_lkb(struct dlm_ls *ls);
|
struct dlm_lkb *dlm_allocate_lkb(void);
|
||||||
void dlm_free_lkb(struct dlm_lkb *l);
|
void dlm_free_lkb(struct dlm_lkb *l);
|
||||||
char *dlm_allocate_lvb(struct dlm_ls *ls);
|
char *dlm_allocate_lvb(struct dlm_ls *ls);
|
||||||
void dlm_free_lvb(char *l);
|
void dlm_free_lvb(char *l);
|
||||||
|
@ -452,10 +452,11 @@ static int recover_master(struct dlm_rsb *r, unsigned int *count, uint64_t seq)
|
|||||||
int is_removed = 0;
|
int is_removed = 0;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
if (is_master(r))
|
if (r->res_nodeid != -1 && is_master(r))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
is_removed = dlm_is_removed(ls, r->res_nodeid);
|
if (r->res_nodeid != -1)
|
||||||
|
is_removed = dlm_is_removed(ls, r->res_nodeid);
|
||||||
|
|
||||||
if (!is_removed && !rsb_flag(r, RSB_NEW_MASTER))
|
if (!is_removed && !rsb_flag(r, RSB_NEW_MASTER))
|
||||||
return 0;
|
return 0;
|
||||||
@ -664,7 +665,7 @@ int dlm_recover_locks(struct dlm_ls *ls, uint64_t seq,
|
|||||||
int error, count = 0;
|
int error, count = 0;
|
||||||
|
|
||||||
list_for_each_entry(r, root_list, res_root_list) {
|
list_for_each_entry(r, root_list, res_root_list) {
|
||||||
if (is_master(r)) {
|
if (r->res_nodeid != -1 && is_master(r)) {
|
||||||
rsb_clear_flag(r, RSB_NEW_MASTER);
|
rsb_clear_flag(r, RSB_NEW_MASTER);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -858,7 +859,7 @@ void dlm_recover_rsbs(struct dlm_ls *ls, const struct list_head *root_list)
|
|||||||
|
|
||||||
list_for_each_entry(r, root_list, res_root_list) {
|
list_for_each_entry(r, root_list, res_root_list) {
|
||||||
lock_rsb(r);
|
lock_rsb(r);
|
||||||
if (is_master(r)) {
|
if (r->res_nodeid != -1 && is_master(r)) {
|
||||||
if (rsb_flag(r, RSB_RECOVER_CONVERT))
|
if (rsb_flag(r, RSB_RECOVER_CONVERT))
|
||||||
recover_conversion(r);
|
recover_conversion(r);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user