diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 53cd33293042..6c5c3f049b33 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -64,11 +64,37 @@ static void release_node(struct config_item *); static struct configfs_attribute *comm_attrs[]; static struct configfs_attribute *node_attrs[]; +static u32 rsb_hashfn(const void *data, u32 len, u32 seed) +{ + const struct dlm_rsb_key *key = data; + + return jhash(key->name, key->len, 0); +} + +static u32 rsb_obj_hashfn(const void *data, u32 len, u32 seed) +{ + const struct dlm_rsb *r = data; + + return r->res_hash; +} + +static int rsb_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *obj) +{ + const struct dlm_rsb_key *key = arg->key; + const struct dlm_rsb *r = obj; + + if (key->len != r->res_length) + return -1; + + return memcmp(&r->res_name, key->name, key->len); +} + const struct rhashtable_params dlm_rhash_rsb_params = { .nelem_hint = 3, /* start small */ - .key_len = DLM_RESNAME_MAXLEN, - .key_offset = offsetof(struct dlm_rsb, res_name), .head_offset = offsetof(struct dlm_rsb, res_node), + .hashfn = rsb_hashfn, + .obj_hashfn = rsb_obj_hashfn, + .obj_cmpfn = rsb_obj_cmpfn, .automatic_shrinking = true, }; diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 9df842421ae0..74c2e77d1b55 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h @@ -340,6 +340,11 @@ struct dlm_rsb { char res_name[DLM_RESNAME_MAXLEN+1]; }; +struct dlm_rsb_key { + char name[DLM_RESNAME_MAXLEN]; + size_t len; +}; + /* dlm_master_lookup() flags */ #define DLM_LU_RECOVER_DIR 1 diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index d73c4aed1f8a..2609e4fdeba8 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -625,12 +625,14 @@ static int get_rsb_struct(struct dlm_ls *ls, const void *name, int len, int dlm_search_rsb_tree(struct rhashtable *rhash, const void *name, unsigned int len, struct dlm_rsb **r_ret) { - char key[DLM_RESNAME_MAXLEN] = {}; + struct dlm_rsb_key key = { + .len = len, + }; if (len > DLM_RESNAME_MAXLEN) return -EINVAL; - memcpy(key, name, len); + memcpy(key.name, name, len); *r_ret = rhashtable_lookup_fast(rhash, &key, dlm_rhash_rsb_params); if (*r_ret) return 0;