From: David Teigland Use node weights in directory mapping. Allows nodes to be configured to be responsible for more or less of the directory. Signed-off-by: David Teigland Signed-off-by: Andrew Morton --- drivers/dlm/dir.c | 6 +++++- drivers/dlm/dlm_internal.h | 2 ++ drivers/dlm/lowcomms.c | 13 +++++++++++++ drivers/dlm/lowcomms.h | 1 + drivers/dlm/member.c | 39 ++++++++++++++++++++++++++++++++------- 5 files changed, 53 insertions(+), 8 deletions(-) diff -puN drivers/dlm/dir.c~dlm-node-weights drivers/dlm/dir.c --- devel/drivers/dlm/dir.c~dlm-node-weights 2005-07-16 13:35:54.000000000 -0700 +++ devel-akpm/drivers/dlm/dir.c 2005-07-16 13:35:54.000000000 -0700 @@ -89,13 +89,17 @@ int dlm_dir_name2nodeid(struct dlm_ls *l } hash = dlm_hash(name, length); - node = (hash >> 16) % ls->ls_num_nodes; if (ls->ls_node_array) { + node = (hash >> 16) % ls->ls_total_weight; nodeid = ls->ls_node_array[node]; goto out; } + /* make_member_array() failed to kmalloc ls_node_array... */ + + node = (hash >> 16) % ls->ls_num_nodes; + list_for_each(tmp, &ls->ls_nodes) { if (n++ != node) continue; diff -puN drivers/dlm/dlm_internal.h~dlm-node-weights drivers/dlm/dlm_internal.h --- devel/drivers/dlm/dlm_internal.h~dlm-node-weights 2005-07-16 13:35:54.000000000 -0700 +++ devel-akpm/drivers/dlm/dlm_internal.h 2005-07-16 13:35:54.000000000 -0700 @@ -134,6 +134,7 @@ struct dlm_member { struct list_head list; int nodeid; int gone_event; + int weight; }; /* @@ -457,6 +458,7 @@ struct dlm_ls { struct list_head ls_nodes_gone; /* dead node list, recovery */ int ls_num_nodes; /* number of nodes in ls */ int ls_low_nodeid; + int ls_total_weight; int *ls_node_array; int *ls_nodeids_next; int ls_nodeids_next_count; diff -puN drivers/dlm/lowcomms.c~dlm-node-weights drivers/dlm/lowcomms.c --- devel/drivers/dlm/lowcomms.c~dlm-node-weights 2005-07-16 13:35:54.000000000 -0700 +++ devel-akpm/drivers/dlm/lowcomms.c 2005-07-16 13:35:54.000000000 -0700 @@ -254,6 +254,19 @@ static int nodeid_to_addr(int nodeid, st return 0; } +int dlm_node_weight(int nodeid) +{ + struct dlm_node *node; + int weight = -1; + + down(&nodes_sem); + node = search_node(nodeid); + if (node) + weight = node->weight; + up(&nodes_sem); + return weight; +} + int dlm_set_node(int nodeid, int weight, char *addr_buf) { struct dlm_node *node; diff -puN drivers/dlm/lowcomms.h~dlm-node-weights drivers/dlm/lowcomms.h --- devel/drivers/dlm/lowcomms.h~dlm-node-weights 2005-07-16 13:35:54.000000000 -0700 +++ devel-akpm/drivers/dlm/lowcomms.h 2005-07-16 13:35:54.000000000 -0700 @@ -23,6 +23,7 @@ void dlm_lowcomms_commit_buffer(void *mh int dlm_set_node(int nodeid, int weight, char *addr_buf); int dlm_set_local(int nodeid, int weight, char *addr_buf); int dlm_our_nodeid(void); +int dlm_node_weight(int nodeid); #endif /* __LOWCOMMS_DOT_H__ */ diff -puN drivers/dlm/member.c~dlm-node-weights drivers/dlm/member.c --- devel/drivers/dlm/member.c~dlm-node-weights 2005-07-16 13:35:54.000000000 -0700 +++ devel-akpm/drivers/dlm/member.c 2005-07-16 13:35:54.000000000 -0700 @@ -56,6 +56,7 @@ static int dlm_add_member(struct dlm_ls return -ENOMEM; memb->nodeid = nodeid; + memb->weight = dlm_node_weight(nodeid); add_ordered_member(ls, memb); ls->ls_num_nodes++; return 0; @@ -126,19 +127,43 @@ void dlm_clear_members_finish(struct dlm static void make_member_array(struct dlm_ls *ls) { struct dlm_member *memb; - int i = 0, *array; + int i, w, x = 0, total = 0, all_zero = 0, *array; - if (ls->ls_node_array) { - kfree(ls->ls_node_array); - ls->ls_node_array = NULL; + kfree(ls->ls_node_array); + ls->ls_node_array = NULL; + + list_for_each_entry(memb, &ls->ls_nodes, list) { + if (memb->weight) + total += memb->weight; } - array = kmalloc(sizeof(int) * ls->ls_num_nodes, GFP_KERNEL); + /* all nodes revert to weight of 1 if all have weight 0 */ + + if (!total) { + total = ls->ls_num_nodes; + all_zero = 1; + } + + ls->ls_total_weight = total; + + array = kmalloc(sizeof(int) * total, GFP_KERNEL); if (!array) return; - list_for_each_entry(memb, &ls->ls_nodes, list) - array[i++] = memb->nodeid; + list_for_each_entry(memb, &ls->ls_nodes, list) { + if (!all_zero && !memb->weight) + continue; + + if (all_zero) + w = 1; + else + w = memb->weight; + + DLM_ASSERT(x < total, printk("total %d x %d\n", total, x);); + + for (i = 0; i < w; i++) + array[x++] = memb->nodeid; + } ls->ls_node_array = array; } _