mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 06:34:12 +08:00
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: David Teigland <teigland@redhat.com>
This commit is contained in:
parent
192cfd5877
commit
7210cb7a72
17
fs/dlm/dir.c
17
fs/dlm/dir.c
@ -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)
|
||||
{
|
||||
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);
|
||||
list_for_each_entry(r, &ls->ls_root_list, res_root_list) {
|
||||
if (len == r->res_length && !memcmp(name, r->res_name, len)) {
|
||||
up_read(&ls->ls_root_sem);
|
||||
log_error(ls, "find_rsb_root revert to root_list %s",
|
||||
r->res_name);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
@ -411,8 +411,8 @@ static int rsb_cmp(struct dlm_rsb *r, const char *name, int nlen)
|
||||
return memcmp(r->res_name, maxname, DLM_RESNAME_MAXLEN);
|
||||
}
|
||||
|
||||
static int search_rsb_tree(struct rb_root *tree, char *name, int len,
|
||||
unsigned int flags, struct dlm_rsb **r_ret)
|
||||
int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len,
|
||||
unsigned int flags, struct dlm_rsb **r_ret)
|
||||
{
|
||||
struct rb_node *node = tree->rb_node;
|
||||
struct dlm_rsb *r;
|
||||
@ -474,12 +474,12 @@ static int _search_rsb(struct dlm_ls *ls, char *name, int len, int b,
|
||||
struct dlm_rsb *r;
|
||||
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) {
|
||||
kref_get(&r->res_ref);
|
||||
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)
|
||||
goto out;
|
||||
|
||||
|
@ -28,6 +28,9 @@ void dlm_scan_waiters(struct dlm_ls *ls);
|
||||
void dlm_scan_timeout(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);
|
||||
void dlm_purge_mstcpy_locks(struct dlm_rsb *r);
|
||||
void dlm_grant_after_purge(struct dlm_ls *ls);
|
||||
|
Loading…
Reference in New Issue
Block a user