diff options
| author | David Teigland <teigland@redhat.com> | 2012-03-08 13:37:12 -0500 |
|---|---|---|
| committer | David Teigland <teigland@redhat.com> | 2012-03-08 15:46:30 -0500 |
| commit | 7210cb7a72a22303cdb225bd1aea28697a17bbae (patch) | |
| tree | eb303df3d35d52080309d139c1d26edcfab1e670 /fs/dlm | |
| parent | 192cfd58774b4d17b2fe8bdc77d89c2ef4e0591d (diff) | |
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')
| -rw-r--r-- | fs/dlm/dir.c | 17 | ||||
| -rw-r--r-- | fs/dlm/lock.c | 8 | ||||
| -rw-r--r-- | fs/dlm/lock.h | 3 |
3 files changed, 24 insertions, 4 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, | |||
| 351 | static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len) | 351 | static struct dlm_rsb *find_rsb_root(struct dlm_ls *ls, char *name, int len) |
| 352 | { | 352 | { |
| 353 | struct dlm_rsb *r; | 353 | struct dlm_rsb *r; |
| 354 | uint32_t hash, bucket; | ||
| 355 | int rv; | ||
| 356 | |||
| 357 | hash = jhash(name, len, 0); | ||
| 358 | bucket = hash & (ls->ls_rsbtbl_size - 1); | ||
| 359 | |||
| 360 | spin_lock(&ls->ls_rsbtbl[bucket].lock); | ||
| 361 | rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].keep, name, len, 0, &r); | ||
| 362 | if (rv) | ||
| 363 | rv = dlm_search_rsb_tree(&ls->ls_rsbtbl[bucket].toss, | ||
| 364 | name, len, 0, &r); | ||
| 365 | spin_unlock(&ls->ls_rsbtbl[bucket].lock); | ||
| 366 | |||
| 367 | if (!rv) | ||
| 368 | return r; | ||
| 354 | 369 | ||
| 355 | down_read(&ls->ls_root_sem); | 370 | down_read(&ls->ls_root_sem); |
| 356 | list_for_each_entry(r, &ls->ls_root_list, res_root_list) { | 371 | list_for_each_entry(r, &ls->ls_root_list, res_root_list) { |
| 357 | if (len == r->res_length && !memcmp(name, r->res_name, len)) { | 372 | if (len == r->res_length && !memcmp(name, r->res_name, len)) { |
| 358 | up_read(&ls->ls_root_sem); | 373 | up_read(&ls->ls_root_sem); |
| 374 | log_error(ls, "find_rsb_root revert to root_list %s", | ||
| 375 | r->res_name); | ||
| 359 | return r; | 376 | return r; |
| 360 | } | 377 | } |
| 361 | } | 378 | } |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index d47183043c59..fa5c07d51dcc 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
| @@ -411,8 +411,8 @@ static int rsb_cmp(struct dlm_rsb *r, const char *name, int nlen) | |||
| 411 | return memcmp(r->res_name, maxname, DLM_RESNAME_MAXLEN); | 411 | return memcmp(r->res_name, maxname, DLM_RESNAME_MAXLEN); |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | static int search_rsb_tree(struct rb_root *tree, char *name, int len, | 414 | int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len, |
| 415 | unsigned int flags, struct dlm_rsb **r_ret) | 415 | unsigned int flags, struct dlm_rsb **r_ret) |
| 416 | { | 416 | { |
| 417 | struct rb_node *node = tree->rb_node; | 417 | struct rb_node *node = tree->rb_node; |
| 418 | struct dlm_rsb *r; | 418 | struct dlm_rsb *r; |
| @@ -474,12 +474,12 @@ static int _search_rsb(struct dlm_ls *ls, char *name, int len, int b, | |||
| 474 | struct dlm_rsb *r; | 474 | struct dlm_rsb *r; |
| 475 | int error; | 475 | int error; |
| 476 | 476 | ||
| 477 | error = search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, flags, &r); | 477 | error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].keep, name, len, flags, &r); |
| 478 | if (!error) { | 478 | if (!error) { |
| 479 | kref_get(&r->res_ref); | 479 | kref_get(&r->res_ref); |
| 480 | goto out; | 480 | goto out; |
| 481 | } | 481 | } |
| 482 | error = search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, flags, &r); | 482 | error = dlm_search_rsb_tree(&ls->ls_rsbtbl[b].toss, name, len, flags, &r); |
| 483 | if (error) | 483 | if (error) |
| 484 | goto out; | 484 | goto out; |
| 485 | 485 | ||
diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h index 265017a7c3e7..1a255307f6ff 100644 --- a/fs/dlm/lock.h +++ b/fs/dlm/lock.h | |||
| @@ -28,6 +28,9 @@ void dlm_scan_waiters(struct dlm_ls *ls); | |||
| 28 | void dlm_scan_timeout(struct dlm_ls *ls); | 28 | void dlm_scan_timeout(struct dlm_ls *ls); |
| 29 | void dlm_adjust_timeouts(struct dlm_ls *ls); | 29 | void dlm_adjust_timeouts(struct dlm_ls *ls); |
| 30 | 30 | ||
| 31 | int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len, | ||
| 32 | unsigned int flags, struct dlm_rsb **r_ret); | ||
| 33 | |||
| 31 | int dlm_purge_locks(struct dlm_ls *ls); | 34 | int dlm_purge_locks(struct dlm_ls *ls); |
| 32 | void dlm_purge_mstcpy_locks(struct dlm_rsb *r); | 35 | void dlm_purge_mstcpy_locks(struct dlm_rsb *r); |
| 33 | void dlm_grant_after_purge(struct dlm_ls *ls); | 36 | void dlm_grant_after_purge(struct dlm_ls *ls); |
