Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -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;
		}
		}
	}
	}
+4 −4
Original line number Original line Diff line number Diff line
@@ -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,
	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;


+3 −0
Original line number Original line Diff line number Diff line
@@ -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);