ocfs2/cluster: implement show & store method for IPv6 attribute
PATCH 2/5 ocfs2/cluster: implement show & store method for IPv6 attribute
Implement o2nm_node_ipv6_port_show(), o2nm_node_ipv6_port_store(), o2nm_node_ipv6_address_show and o2nm_node_ipv6_address_store which used for configuring IPv6 node information.
Signed-off-by Jun Piao <[email protected]>
--- fs/ocfs2/cluster/nodemanager.c | 108 ++++++++++++++++++++++++++++++++++------- fs/ocfs2/cluster/nodemanager.h | 6 +++ 2 files changed, 96 insertions(+), 18 deletions(-)
fs/ocfs2/cluster/nodemanager.c +90 -18
@@ -78,7 +78,7 @@ int o2nm_configured_node_map(unsigned long *map, unsigned bytes)EXPORT_SYMBOL_GPL (o2nm_configured_node_map);static struct o2nm_node *o2nm_node_ip_tree_lookup (struct o2nm_cluster *cluster, -__be32 ip_needle, +u8 ip_needle[],struct rb_node ***ret_p,struct rb_node **ret_parent) {
@@ -91,9 +91,12 @@ static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster, parent = *p; node = rb_entry(parent, struct o2nm_node, nd_ip_node); - - cmp =memcmp (&ip_needle, &node->nd_ipv4_address, -sizeof (ip_needle)); +if (node->nd_ipnet_type ==IPV4_TYPE ) + cmp =memcmp (ip_needle, &node->nd_ipv4_address, +sizeof (node->nd_ipv4_address)); +else + cmp =memcmp (ip_needle, node->nd_ipv6_address, +sizeof (node->nd_ipv6_address));if (cmp <0 ) p = &(*p)->rb_left;else if (cmp >0 )
@@ -121,7 +124,7 @@ struct o2nm_node *o2nm_get_node_by_ip(__be32 addr) goto out;read_lock (&cluster->cl_nodes_lock); - node =o2nm_node_ip_tree_lookup (cluster, addr,NULL ,NULL ); + node =o2nm_node_ip_tree_lookup (cluster, (u8 *)&addr,NULL ,NULL );if (node)config_item_get (&node->nd_item);read_unlock (&cluster->cl_nodes_lock);
@@ -218,9 +221,14 @@ static ssize_t o2nm_node_num_store(struct config_item *item, const char *page,* node number and try to use our address and port attributes * to connect to this node.. make sure that they've been set * before writing the node attribute? */ -if (!test_bit (O2NM_NODE_ATTR_IPV4_ADDRESS , &node->nd_set_attributes) || - !test_bit (O2NM_NODE_ATTR_IPV4_PORT , &node->nd_set_attributes)) -return -EINVAL ;/* XXX */ +if ((node->nd_ipnet_type ==IPV4_TYPE ) && + (!test_bit (O2NM_NODE_ATTR_IPV4_ADDRESS , &node->nd_set_attributes) || + !test_bit (O2NM_NODE_ATTR_IPV4_PORT , &node->nd_set_attributes))) +return -EINVAL ; +else if ((node->nd_ipnet_type ==IPV6_TYPE ) && + (!test_bit (O2NM_NODE_ATTR_IPV6_ADDRESS , &node->nd_set_attributes) || + !test_bit (O2NM_NODE_ATTR_IPV6_PORT , &node->nd_set_attributes))) +return -EINVAL ;o2nm_lock_subsystem (); cluster =to_o2nm_cluster_from_node (node);
@@ -312,7 +320,7 @@ static ssize_t o2nm_node_ipv4_address_store(struct config_item *item, ret =0 ;write_lock (&cluster->cl_nodes_lock); -if (o2nm_node_ip_tree_lookup (cluster, ipv4_addr, &p, &parent)) +if (o2nm_node_ip_tree_lookup (cluster, (u8 *)&ipv4_addr, &p, &parent)) ret = -EEXIST ;else if (test_and_set_bit (O2NM_NODE_ATTR_IPV4_ADDRESS , &node->nd_set_attributes))
@@ -328,31 +336,86 @@ static ssize_t o2nm_node_ipv4_address_store(struct config_item *item,return ret;memcpy (&node->nd_ipv4_address, &ipv4_addr,sizeof (ipv4_addr)); + node->nd_ipnet_type =IPV4_TYPE ;return count; }static ssize_t o2nm_node_ipv6_port_show (struct config_item *item,char *page) { -return 0 ; +return sprintf (page,"%u\n" ,ntohs (to_o2nm_node (item)->nd_ipv6_port)); }static ssize_t o2nm_node_ipv6_port_store (struct config_item *item,const char *page,size_t count) { -return 0 ; +struct o2nm_node *node =to_o2nm_node (item); +unsigned long tmp; +char *p = (char *)page; + + tmp =simple_strtoul (p, &p,0 ); +if (!p || (*p && (*p !='\n' ))) +return -EINVAL ; + +if (tmp ==0 ) +return -EINVAL ; +if (tmp >= (u16)-1 ) +return -ERANGE ; + +if (test_and_set_bit (O2NM_NODE_ATTR_IPV6_PORT , &node->nd_set_attributes)) +return -EBUSY ; + node->nd_ipv6_port =htons (tmp); + +return count; }static ssize_t o2nm_node_ipv6_address_show (struct config_item *item,char *page) { -return 0 ; +return sprintf (page,"%pI6\n" ,to_o2nm_node (item)->nd_ipv6_address); }static ssize_t o2nm_node_ipv6_address_store (struct config_item *item,const char *page,size_t count) { -return 0 ; +struct o2nm_node *node =to_o2nm_node (item); +struct o2nm_cluster *cluster; +int ret; +struct rb_node **p, *parent; +u8 ipv6_addr[16 ] = {0 }; + + ret =in6_pton ((const char *)page, count, ipv6_addr,-1 ,NULL ); +if (ret !=1 ) +return -EINVAL ; + +o2nm_lock_subsystem (); + cluster =to_o2nm_cluster_from_node (node); +if (!cluster) { +o2nm_unlock_subsystem (); +return -EINVAL ; + } + + ret =0 ; +write_lock (&cluster->cl_nodes_lock); +if (o2nm_node_ip_tree_lookup (cluster, ipv6_addr, &p, &parent)) + ret = -EEXIST ; +else if (test_and_set_bit (O2NM_NODE_ATTR_IPV6_ADDRESS , + &node->nd_set_attributes)) + ret = -EBUSY ; +else { +rb_link_node (&node->nd_ip_node, parent, p); +rb_insert_color (&node->nd_ip_node, &cluster->cl_node_ip_tree); + } +write_unlock (&cluster->cl_nodes_lock); +o2nm_unlock_subsystem (); + +if (ret) +return ret; + +memcpy (node->nd_ipv6_address, ipv6_addr,sizeof (ipv6_addr)); + node->nd_ipnet_type =IPV6_TYPE ; + +return count; }static ssize_t o2nm_node_local_show (struct config_item *item,char *page)
@@ -377,10 +440,16 @@ static ssize_t o2nm_node_local_store(struct config_item *item, const char *page,/* setting local turns on networking rx for now so we require having * set everything else first */ -if (!test_bit (O2NM_NODE_ATTR_IPV4_ADDRESS , &node->nd_set_attributes) || - !test_bit (O2NM_NODE_ATTR_NUM , &node->nd_set_attributes) || - !test_bit (O2NM_NODE_ATTR_IPV4_PORT , &node->nd_set_attributes)) -return -EINVAL ;/* XXX */ +if (!test_bit (O2NM_NODE_ATTR_NUM , &node->nd_set_attributes)) +return -EINVAL ; +if ((node->nd_ipnet_type ==IPV4_TYPE ) && + (!test_bit (O2NM_NODE_ATTR_IPV4_ADDRESS , &node->nd_set_attributes) || + !test_bit (O2NM_NODE_ATTR_IPV4_PORT , &node->nd_set_attributes))) +return -EINVAL ; +else if ((node->nd_ipnet_type ==IPV6_TYPE ) && + (!test_bit (O2NM_NODE_ATTR_IPV6_ADDRESS , &node->nd_set_attributes) || + !test_bit (O2NM_NODE_ATTR_IPV6_PORT , &node->nd_set_attributes))) +return -EINVAL ;o2nm_lock_subsystem (); cluster =to_o2nm_cluster_from_node (node);
@@ -649,6 +718,7 @@ static void o2nm_node_group_drop_item(struct config_group *group, {struct o2nm_node *node =to_o2nm_node (item);struct o2nm_cluster *cluster =to_o2nm_cluster (group->cg_item.ci_parent); +u8 ipv6_addr[16 ] = {0 };o2net_disconnect_node (node);
@@ -664,7 +734,9 @@ static void o2nm_node_group_drop_item(struct config_group *group,write_lock (&cluster->cl_nodes_lock);/* XXX sloppy */ -if (node->nd_ipv4_address) +if ((node->nd_ipnet_type ==IPV4_TYPE && node->nd_ipv4_address) || + (node->nd_ipnet_type ==IPV6_TYPE && +memcmp (ipv6_addr, node->nd_ipv6_address,sizeof (ipv6_addr))))rb_erase (&node->nd_ip_node, &cluster->cl_node_ip_tree);/* nd_num might be 0 if the node number hasn't been set.. */
fs/ocfs2/cluster/nodemanager.h +6 -0
@@ -39,6 +39,12 @@ enum o2nm_fence_method { O2NM_FENCE_METHODS, /* Number of fence methods */ }; +enum ipnet_type { +IPV4_TYPE =0 , +IPV6_TYPE , +INVALID_IPNET_TYPE , +}; +struct o2nm_node {spinlock_t nd_lock;struct config_item nd_item;