diff options
author | David Teigland <teigland@redhat.com> | 2012-03-08 22:37:12 +0400 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2012-03-09 00:46:30 +0400 |
commit | 7210cb7a72a22303cdb225bd1aea28697a17bbae (patch) | |
tree | eb303df3d35d52080309d139c1d26edcfab1e670 /fs/dlm/dir.c | |
parent | 192cfd58774b4d17b2fe8bdc77d89c2ef4e0591d (diff) | |
download | linux-7210cb7a72a22303cdb225bd1aea28697a17bbae.tar.xz |
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>
Diffstat (limited to 'fs/dlm/dir.c')
-rw-r--r-- | fs/dlm/dir.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c index 83641574b016..dc5eb598b81f 100644 --- a/fs/dlm/dir.c +++ b/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; } } |