summaryrefslogtreecommitdiff
path: root/fs/dlm/dir.c
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2012-03-08 12:37:12 -0600
committerDavid Teigland <teigland@redhat.com>2012-03-08 14:46:30 -0600
commit7210cb7a72a22303cdb225bd1aea28697a17bbae (patch)
treeeb303df3d35d52080309d139c1d26edcfab1e670 /fs/dlm/dir.c
parent192cfd58774b4d17b2fe8bdc77d89c2ef4e0591d (diff)
downloadlinux-3.10-7210cb7a72a22303cdb225bd1aea28697a17bbae.tar.gz
linux-3.10-7210cb7a72a22303cdb225bd1aea28697a17bbae.tar.bz2
linux-3.10-7210cb7a72a22303cdb225bd1aea28697a17bbae.zip
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.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c
index 83641574b01..dc5eb598b81 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;
}
}