Commit 7210cb7a authored by David Teigland's avatar David Teigland

dlm: fix slow rsb search in dir recovery

The function used to find an rsb during directory
recovery was searching the single linear list of
rsb's.  This wasted a lot of time compared to
using the standard hash table to find the rsb.
Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
parent 192cfd58
...@@ -351,11 +351,28 @@ int dlm_dir_lookup(struct dlm_ls *ls, int nodeid, char *name, int namelen, ...@@ -351,11 +351,28 @@ int dlm_dir_lookup(struct dlm_ls *ls, int nodeid, char *name, int namelen,
static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len) static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len)
{ {
struct dlm_rsb *r; struct dlm_rsb *r;
uint32_t hash, bucket;
int rv;
hash = jhash(name, len, 0);
bucket = hash & (ls->ls_rsbtbl_size - 1);
spin_lock(&ls->ls_rsbtbl[bucket].lock);
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].keep, name, len, 0, &r);
if (rv)
rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].toss,
name, len, 0, &r);
spin_unlock(&ls->ls_rsbtbl[bucket].lock);
if (!rv)
return r;
down_read(&ls->ls_root_sem); down_read(&ls->ls_root_sem);
list_for_each_entry(r, &ls->ls_root_list, res_root_list) { list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
if (len == r->res_length && !memcmp(name, r->res_name, len)) { if (len == r->res_length && !memcmp(name, r->res_name, len)) {
up_read(&ls->ls_root_sem); up_read(&ls->ls_root_sem);
log_error(ls, "find_rsb_root revert to root_list %s",
r->res_name);
return r; return r;
} }
} }
......
...@@ -411,7 +411,7 @@ static int rsb_cmp(struct dlm_rsb *r, const char *name, int nlen) ...@@ -411,7 +411,7 @@ static int rsb_cmp(struct dlm_rsb *r, const char *name, int nlen)
return memcmp(r->res_name, maxname, DLM_RESNAME_MAXLEN); return memcmp(r->res_name, maxname, DLM_RESNAME_MAXLEN);
} }
static int search_rsb_tree(struct rb_root *tree, char *name, int len, int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len,
unsigned int flags, struct dlm_rsb **r_ret) unsigned int flags, struct dlm_rsb **r_ret)
{ {
struct rb_node *node = tree->rb_node; struct rb_node *node = tree->rb_node;
...@@ -474,12 +474,12 @@ static int _search_rsb(struct dlm_ls *ls, char *name, int len, int b, ...@@ -474,12 +474,12 @@ static int _search_rsb(struct dlm_ls *ls, char *name, int len, int b,
struct dlm_rsb *r; struct dlm_rsb *r;
int error; int error;
error = search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, flags, &r); error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, flags, &r);
if (!error) { if (!error) {
kref_get(&r->res_ref); kref_get(&r->res_ref);
goto out; goto out;
} }
error = search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, flags, &r); error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, flags, &r);
if (error) if (error)
goto out; goto out;
......
...@@ -28,6 +28,9 @@ void dlm_scan_waiters(struct dlm_ls *ls); ...@@ -28,6 +28,9 @@ void dlm_scan_waiters(struct dlm_ls *ls);
void dlm_scan_timeout(struct dlm_ls *ls); void dlm_scan_timeout(struct dlm_ls *ls);
void dlm_adjust_timeouts(struct dlm_ls *ls); void dlm_adjust_timeouts(struct dlm_ls *ls);
int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len,
unsigned int flags, struct dlm_rsb **r_ret);
int dlm_purge_locks(struct dlm_ls *ls); int dlm_purge_locks(struct dlm_ls *ls);
void dlm_purge_mstcpy_locks(struct dlm_rsb *r); void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
void dlm_grant_after_purge(struct dlm_ls *ls); void dlm_grant_after_purge(struct dlm_ls *ls);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment