All of lore.kernel.org
 help / color / mirror / Atom feed
* [Ocfs2-devel] [PATCH 2/5] ocfs2/cluster: implement show & store method for IPv6 attribute
@ 2018-10-25 10:34 piaojun
  0 siblings, 0 replies; only message in thread
From: piaojun @ 2018-10-25 10:34 UTC (permalink / raw)
  To: ocfs2-devel

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 <piaojun@huawei.com>
---
 fs/ocfs2/cluster/nodemanager.c | 108 ++++++++++++++++++++++++++++++++++-------
 fs/ocfs2/cluster/nodemanager.h |   6 +++
 2 files changed, 96 insertions(+), 18 deletions(-)

diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index a3c4e61..292f5dd 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -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.. */
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h
index 55fdb81..1f3cfc5 100644
--- a/fs/ocfs2/cluster/nodemanager.h
+++ b/fs/ocfs2/cluster/nodemanager.h
@@ -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;
-- 

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2018-10-25 10:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-25 10:34 [Ocfs2-devel] [PATCH 2/5] ocfs2/cluster: implement show & store method for IPv6 attribute piaojun

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.