xref: /linux/fs/dlm/config.c (revision 7f662eb1807ed732ac7d5e119753c8185f241bb8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /******************************************************************************
3 *******************************************************************************
4 **
5 **  Copyright (C) Sistina Software, Inc.  1997-2003  All rights reserved.
6 **  Copyright (C) 2004-2011 Red Hat, Inc.  All rights reserved.
7 **
8 **
9 *******************************************************************************
10 ******************************************************************************/
11 
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/configfs.h>
15 #include <linux/slab.h>
16 #include <linux/in.h>
17 #include <linux/in6.h>
18 #include <linux/dlmconstants.h>
19 #include <net/ipv6.h>
20 #include <net/sock.h>
21 
22 #include "config.h"
23 #include "midcomms.h"
24 #include "lowcomms.h"
25 
26 /*
27  * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/nodeid (refers to <node>)
28  * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/weight
29  * /config/dlm/<cluster>/spaces/<space>/nodes/<node>/release_recover
30  * /config/dlm/<cluster>/comms/<comm>/nodeid (refers to <comm>)
31  * /config/dlm/<cluster>/comms/<comm>/local
32  * /config/dlm/<cluster>/comms/<comm>/addr      (write only)
33  * /config/dlm/<cluster>/comms/<comm>/addr_list (read only)
34  * The <cluster> level is useless, but I haven't figured out how to avoid it.
35  */
36 
37 static struct config_group *space_list;
38 static struct config_group *comm_list;
39 static struct dlm_comm *local_comm;
40 static uint32_t dlm_comm_count;
41 
42 struct dlm_clusters;
43 struct dlm_cluster;
44 struct dlm_spaces;
45 struct dlm_space;
46 struct dlm_comms;
47 struct dlm_comm;
48 struct dlm_nodes;
49 struct dlm_node;
50 
51 static struct config_group *make_cluster(struct config_group *, const char *);
52 static void drop_cluster(struct config_group *, struct config_item *);
53 static void release_cluster(struct config_item *);
54 static struct config_group *make_space(struct config_group *, const char *);
55 static void drop_space(struct config_group *, struct config_item *);
56 static void release_space(struct config_item *);
57 static struct config_item *make_comm(struct config_group *, const char *);
58 static void drop_comm(struct config_group *, struct config_item *);
59 static void release_comm(struct config_item *);
60 static struct config_item *make_node(struct config_group *, const char *);
61 static void drop_node(struct config_group *, struct config_item *);
62 static void release_node(struct config_item *);
63 
64 static struct configfs_attribute *comm_attrs[];
65 static struct configfs_attribute *node_attrs[];
66 
67 static u32 rsb_hashfn(const void *data, u32 len, u32 seed)
68 {
69 	const struct dlm_rsb_key *key = data;
70 
71 	return jhash(key->name, key->len, 0);
72 }
73 
74 static u32 rsb_obj_hashfn(const void *data, u32 len, u32 seed)
75 {
76 	const struct dlm_rsb *r = data;
77 
78 	return r->res_hash;
79 }
80 
81 static int rsb_obj_cmpfn(struct rhashtable_compare_arg *arg, const void *obj)
82 {
83 	const struct dlm_rsb_key *key = arg->key;
84 	const struct dlm_rsb *r = obj;
85 
86 	if (key->len != r->res_length)
87 		return -1;
88 
89 	return memcmp(&r->res_name, key->name, key->len);
90 }
91 
92 const struct rhashtable_params dlm_rhash_rsb_params = {
93 	.nelem_hint = 3, /* start small */
94 	.head_offset = offsetof(struct dlm_rsb, res_node),
95 	.hashfn = rsb_hashfn,
96 	.obj_hashfn = rsb_obj_hashfn,
97 	.obj_cmpfn = rsb_obj_cmpfn,
98 	.automatic_shrinking = true,
99 };
100 
101 struct dlm_cluster {
102 	struct config_group group;
103 	struct dlm_spaces *sps;
104 	struct dlm_comms *cms;
105 };
106 
107 static struct dlm_cluster *config_item_to_cluster(struct config_item *i)
108 {
109 	return i ? container_of(to_config_group(i), struct dlm_cluster, group) :
110 		   NULL;
111 }
112 
113 enum {
114 	CLUSTER_ATTR_TCP_PORT = 0,
115 	CLUSTER_ATTR_BUFFER_SIZE,
116 	CLUSTER_ATTR_RSBTBL_SIZE,
117 	CLUSTER_ATTR_RECOVER_TIMER,
118 	CLUSTER_ATTR_TOSS_SECS,
119 	CLUSTER_ATTR_SCAN_SECS,
120 	CLUSTER_ATTR_LOG_DEBUG,
121 	CLUSTER_ATTR_LOG_INFO,
122 	CLUSTER_ATTR_PROTOCOL,
123 	CLUSTER_ATTR_MARK,
124 	CLUSTER_ATTR_NEW_RSB_COUNT,
125 	CLUSTER_ATTR_RECOVER_CALLBACKS,
126 	CLUSTER_ATTR_CLUSTER_NAME,
127 };
128 
129 static ssize_t cluster_cluster_name_show(struct config_item *item, char *buf)
130 {
131 	return sprintf(buf, "%s\n", dlm_config.ci_cluster_name);
132 }
133 
134 static ssize_t cluster_cluster_name_store(struct config_item *item,
135 					  const char *buf, size_t len)
136 {
137 	strscpy(dlm_config.ci_cluster_name, buf,
138 		sizeof(dlm_config.ci_cluster_name));
139 	return len;
140 }
141 
142 CONFIGFS_ATTR(cluster_, cluster_name);
143 
144 static ssize_t cluster_tcp_port_show(struct config_item *item, char *buf)
145 {
146 	return sprintf(buf, "%u\n", be16_to_cpu(dlm_config.ci_tcp_port));
147 }
148 
149 static int dlm_check_zero_and_dlm_running(unsigned int x)
150 {
151 	if (!x)
152 		return -EINVAL;
153 
154 	if (dlm_lowcomms_is_running())
155 		return -EBUSY;
156 
157 	return 0;
158 }
159 
160 static ssize_t cluster_tcp_port_store(struct config_item *item,
161 				      const char *buf, size_t len)
162 {
163 	int rc;
164 	u16 x;
165 
166 	if (!capable(CAP_SYS_ADMIN))
167 		return -EPERM;
168 
169 	rc = kstrtou16(buf, 0, &x);
170 	if (rc)
171 		return rc;
172 
173 	rc = dlm_check_zero_and_dlm_running(x);
174 	if (rc)
175 		return rc;
176 
177 	dlm_config.ci_tcp_port = cpu_to_be16(x);
178 	return len;
179 }
180 
181 CONFIGFS_ATTR(cluster_, tcp_port);
182 
183 static ssize_t cluster_set(unsigned int *info_field,
184 			   int (*check_cb)(unsigned int x),
185 			   const char *buf, size_t len)
186 {
187 	unsigned int x;
188 	int rc;
189 
190 	if (!capable(CAP_SYS_ADMIN))
191 		return -EPERM;
192 	rc = kstrtouint(buf, 0, &x);
193 	if (rc)
194 		return rc;
195 
196 	if (check_cb) {
197 		rc = check_cb(x);
198 		if (rc)
199 			return rc;
200 	}
201 
202 	*info_field = x;
203 
204 	return len;
205 }
206 
207 #define CLUSTER_ATTR(name, check_cb)                                          \
208 static ssize_t cluster_##name##_store(struct config_item *item, \
209 		const char *buf, size_t len) \
210 {                                                                             \
211 	return cluster_set(&dlm_config.ci_##name, check_cb, buf, len);        \
212 }                                                                             \
213 static ssize_t cluster_##name##_show(struct config_item *item, char *buf)     \
214 {                                                                             \
215 	return snprintf(buf, PAGE_SIZE, "%u\n", dlm_config.ci_##name);        \
216 }                                                                             \
217 CONFIGFS_ATTR(cluster_, name);
218 
219 static int dlm_check_protocol_and_dlm_running(unsigned int x)
220 {
221 	switch (x) {
222 	case 0:
223 		/* TCP */
224 		break;
225 	case 1:
226 		/* SCTP */
227 		if (!IS_ENABLED(CONFIG_IP_SCTP))
228 			return -EOPNOTSUPP;
229 
230 		break;
231 	default:
232 		return -EINVAL;
233 	}
234 
235 	if (dlm_lowcomms_is_running())
236 		return -EBUSY;
237 
238 	return 0;
239 }
240 
241 static int dlm_check_zero(unsigned int x)
242 {
243 	if (!x)
244 		return -EINVAL;
245 
246 	return 0;
247 }
248 
249 static int dlm_check_buffer_size(unsigned int x)
250 {
251 	if (x < DLM_MAX_SOCKET_BUFSIZE)
252 		return -EINVAL;
253 
254 	return 0;
255 }
256 
257 CLUSTER_ATTR(buffer_size, dlm_check_buffer_size);
258 CLUSTER_ATTR(rsbtbl_size, dlm_check_zero);
259 CLUSTER_ATTR(recover_timer, dlm_check_zero);
260 CLUSTER_ATTR(toss_secs, dlm_check_zero);
261 CLUSTER_ATTR(scan_secs, dlm_check_zero);
262 CLUSTER_ATTR(log_debug, NULL);
263 CLUSTER_ATTR(log_info, NULL);
264 CLUSTER_ATTR(protocol, dlm_check_protocol_and_dlm_running);
265 CLUSTER_ATTR(mark, NULL);
266 CLUSTER_ATTR(new_rsb_count, NULL);
267 CLUSTER_ATTR(recover_callbacks, NULL);
268 
269 static struct configfs_attribute *cluster_attrs[] = {
270 	[CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port,
271 	[CLUSTER_ATTR_BUFFER_SIZE] = &cluster_attr_buffer_size,
272 	[CLUSTER_ATTR_RSBTBL_SIZE] = &cluster_attr_rsbtbl_size,
273 	[CLUSTER_ATTR_RECOVER_TIMER] = &cluster_attr_recover_timer,
274 	[CLUSTER_ATTR_TOSS_SECS] = &cluster_attr_toss_secs,
275 	[CLUSTER_ATTR_SCAN_SECS] = &cluster_attr_scan_secs,
276 	[CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug,
277 	[CLUSTER_ATTR_LOG_INFO] = &cluster_attr_log_info,
278 	[CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol,
279 	[CLUSTER_ATTR_MARK] = &cluster_attr_mark,
280 	[CLUSTER_ATTR_NEW_RSB_COUNT] = &cluster_attr_new_rsb_count,
281 	[CLUSTER_ATTR_RECOVER_CALLBACKS] = &cluster_attr_recover_callbacks,
282 	[CLUSTER_ATTR_CLUSTER_NAME] = &cluster_attr_cluster_name,
283 	NULL,
284 };
285 
286 enum {
287 	COMM_ATTR_NODEID = 0,
288 	COMM_ATTR_LOCAL,
289 	COMM_ATTR_ADDR,
290 	COMM_ATTR_ADDR_LIST,
291 	COMM_ATTR_MARK,
292 };
293 
294 enum {
295 	NODE_ATTR_NODEID = 0,
296 	NODE_ATTR_WEIGHT,
297 	NODE_ATTR_RELEASE_RECOVER,
298 };
299 
300 struct dlm_clusters {
301 	struct configfs_subsystem subsys;
302 };
303 
304 struct dlm_spaces {
305 	struct config_group ss_group;
306 };
307 
308 struct dlm_space {
309 	struct config_group group;
310 	struct list_head members;
311 	struct list_head members_gone;
312 	int members_gone_count;
313 	struct mutex members_lock;
314 	int members_count;
315 	struct dlm_nodes *nds;
316 };
317 
318 struct dlm_comms {
319 	struct config_group cs_group;
320 };
321 
322 struct dlm_comm {
323 	struct config_item item;
324 	int seq;
325 	int nodeid;
326 	int local;
327 	int addr_count;
328 	unsigned int mark;
329 	struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT];
330 };
331 
332 struct dlm_nodes {
333 	struct config_group ns_group;
334 };
335 
336 struct dlm_node {
337 	struct config_item item;
338 	struct list_head list; /* space->members */
339 	int nodeid;
340 	int weight;
341 	int new;
342 	int comm_seq; /* copy of cm->seq when nd->nodeid is set */
343 	unsigned int release_recover;
344 };
345 
346 struct dlm_member_gone {
347 	int nodeid;
348 	unsigned int release_recover;
349 
350 	struct list_head list; /* space->members_gone */
351 };
352 
353 static const struct configfs_group_operations clusters_ops = {
354 	.make_group = make_cluster,
355 	.drop_item = drop_cluster,
356 };
357 
358 static const struct configfs_item_operations cluster_ops = {
359 	.release = release_cluster,
360 };
361 
362 static const struct configfs_group_operations spaces_ops = {
363 	.make_group = make_space,
364 	.drop_item = drop_space,
365 };
366 
367 static const struct configfs_item_operations space_ops = {
368 	.release = release_space,
369 };
370 
371 static const struct configfs_group_operations comms_ops = {
372 	.make_item = make_comm,
373 	.drop_item = drop_comm,
374 };
375 
376 static const struct configfs_item_operations comm_ops = {
377 	.release = release_comm,
378 };
379 
380 static const struct configfs_group_operations nodes_ops = {
381 	.make_item = make_node,
382 	.drop_item = drop_node,
383 };
384 
385 static const struct configfs_item_operations node_ops = {
386 	.release = release_node,
387 };
388 
389 static const struct config_item_type clusters_type = {
390 	.ct_group_ops = &clusters_ops,
391 	.ct_owner = THIS_MODULE,
392 };
393 
394 static const struct config_item_type cluster_type = {
395 	.ct_item_ops = &cluster_ops,
396 	.ct_attrs = cluster_attrs,
397 	.ct_owner = THIS_MODULE,
398 };
399 
400 static const struct config_item_type spaces_type = {
401 	.ct_group_ops = &spaces_ops,
402 	.ct_owner = THIS_MODULE,
403 };
404 
405 static const struct config_item_type space_type = {
406 	.ct_item_ops = &space_ops,
407 	.ct_owner = THIS_MODULE,
408 };
409 
410 static const struct config_item_type comms_type = {
411 	.ct_group_ops = &comms_ops,
412 	.ct_owner = THIS_MODULE,
413 };
414 
415 static const struct config_item_type comm_type = {
416 	.ct_item_ops = &comm_ops,
417 	.ct_attrs = comm_attrs,
418 	.ct_owner = THIS_MODULE,
419 };
420 
421 static const struct config_item_type nodes_type = {
422 	.ct_group_ops = &nodes_ops,
423 	.ct_owner = THIS_MODULE,
424 };
425 
426 static const struct config_item_type node_type = {
427 	.ct_item_ops = &node_ops,
428 	.ct_attrs = node_attrs,
429 	.ct_owner = THIS_MODULE,
430 };
431 
432 static struct dlm_space *config_item_to_space(struct config_item *i)
433 {
434 	return i ? container_of(to_config_group(i), struct dlm_space, group) :
435 		   NULL;
436 }
437 
438 static struct dlm_comm *config_item_to_comm(struct config_item *i)
439 {
440 	return i ? container_of(i, struct dlm_comm, item) : NULL;
441 }
442 
443 static struct dlm_node *config_item_to_node(struct config_item *i)
444 {
445 	return i ? container_of(i, struct dlm_node, item) : NULL;
446 }
447 
448 static struct config_group *make_cluster(struct config_group *g,
449 					 const char *name)
450 {
451 	struct dlm_cluster *cl = NULL;
452 	struct dlm_spaces *sps = NULL;
453 	struct dlm_comms *cms = NULL;
454 
455 	cl = kzalloc_obj(struct dlm_cluster, GFP_NOFS);
456 	sps = kzalloc_obj(struct dlm_spaces, GFP_NOFS);
457 	cms = kzalloc_obj(struct dlm_comms, GFP_NOFS);
458 
459 	if (!cl || !sps || !cms)
460 		goto fail;
461 
462 	cl->sps = sps;
463 	cl->cms = cms;
464 
465 	config_group_init_type_name(&cl->group, name, &cluster_type);
466 	config_group_init_type_name(&sps->ss_group, "spaces", &spaces_type);
467 	config_group_init_type_name(&cms->cs_group, "comms", &comms_type);
468 
469 	configfs_add_default_group(&sps->ss_group, &cl->group);
470 	configfs_add_default_group(&cms->cs_group, &cl->group);
471 
472 	space_list = &sps->ss_group;
473 	comm_list = &cms->cs_group;
474 	return &cl->group;
475 
476  fail:
477 	kfree(cl);
478 	kfree(sps);
479 	kfree(cms);
480 	return ERR_PTR(-ENOMEM);
481 }
482 
483 static void drop_cluster(struct config_group *g, struct config_item *i)
484 {
485 	struct dlm_cluster *cl = config_item_to_cluster(i);
486 
487 	configfs_remove_default_groups(&cl->group);
488 
489 	space_list = NULL;
490 	comm_list = NULL;
491 
492 	config_item_put(i);
493 }
494 
495 static void release_cluster(struct config_item *i)
496 {
497 	struct dlm_cluster *cl = config_item_to_cluster(i);
498 
499 	kfree(cl->sps);
500 	kfree(cl->cms);
501 	kfree(cl);
502 }
503 
504 static struct config_group *make_space(struct config_group *g, const char *name)
505 {
506 	struct dlm_space *sp = NULL;
507 	struct dlm_nodes *nds = NULL;
508 
509 	sp = kzalloc_obj(struct dlm_space, GFP_NOFS);
510 	nds = kzalloc_obj(struct dlm_nodes, GFP_NOFS);
511 
512 	if (!sp || !nds)
513 		goto fail;
514 
515 	config_group_init_type_name(&sp->group, name, &space_type);
516 
517 	config_group_init_type_name(&nds->ns_group, "nodes", &nodes_type);
518 	configfs_add_default_group(&nds->ns_group, &sp->group);
519 
520 	INIT_LIST_HEAD(&sp->members);
521 	INIT_LIST_HEAD(&sp->members_gone);
522 	mutex_init(&sp->members_lock);
523 	sp->members_count = 0;
524 	sp->nds = nds;
525 	return &sp->group;
526 
527  fail:
528 	kfree(sp);
529 	kfree(nds);
530 	return ERR_PTR(-ENOMEM);
531 }
532 
533 static void drop_space(struct config_group *g, struct config_item *i)
534 {
535 	struct dlm_space *sp = config_item_to_space(i);
536 
537 	/* assert list_empty(&sp->members) */
538 
539 	configfs_remove_default_groups(&sp->group);
540 	config_item_put(i);
541 }
542 
543 static void release_space(struct config_item *i)
544 {
545 	struct dlm_space *sp = config_item_to_space(i);
546 	kfree(sp->nds);
547 	kfree(sp);
548 }
549 
550 static struct config_item *make_comm(struct config_group *g, const char *name)
551 {
552 	struct dlm_comm *cm;
553 	unsigned int nodeid;
554 	int rv;
555 
556 	rv = kstrtouint(name, 0, &nodeid);
557 	if (rv)
558 		return ERR_PTR(rv);
559 
560 	cm = kzalloc_obj(struct dlm_comm, GFP_NOFS);
561 	if (!cm)
562 		return ERR_PTR(-ENOMEM);
563 
564 	config_item_init_type_name(&cm->item, name, &comm_type);
565 
566 	cm->seq = dlm_comm_count++;
567 	if (!cm->seq)
568 		cm->seq = dlm_comm_count++;
569 
570 	cm->nodeid = nodeid;
571 	cm->local = 0;
572 	cm->addr_count = 0;
573 	cm->mark = 0;
574 	return &cm->item;
575 }
576 
577 static void drop_comm(struct config_group *g, struct config_item *i)
578 {
579 	struct dlm_comm *cm = config_item_to_comm(i);
580 	if (local_comm == cm)
581 		local_comm = NULL;
582 	dlm_midcomms_close(cm->nodeid);
583 	while (cm->addr_count--)
584 		kfree(cm->addr[cm->addr_count]);
585 	config_item_put(i);
586 }
587 
588 static void release_comm(struct config_item *i)
589 {
590 	struct dlm_comm *cm = config_item_to_comm(i);
591 	kfree(cm);
592 }
593 
594 static struct config_item *make_node(struct config_group *g, const char *name)
595 {
596 	struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
597 	unsigned int nodeid;
598 	struct dlm_node *nd;
599 	uint32_t seq = 0;
600 	int rv;
601 
602 	rv = kstrtouint(name, 0, &nodeid);
603 	if (rv)
604 		return ERR_PTR(rv);
605 
606 	nd = kzalloc_obj(struct dlm_node, GFP_NOFS);
607 	if (!nd)
608 		return ERR_PTR(-ENOMEM);
609 
610 	config_item_init_type_name(&nd->item, name, &node_type);
611 	nd->nodeid = nodeid;
612 	nd->weight = 1;  /* default weight of 1 if none is set */
613 	nd->new = 1;     /* set to 0 once it's been read by dlm_nodeid_list() */
614 	dlm_comm_seq(nodeid, &seq, true);
615 	nd->comm_seq = seq;
616 
617 	mutex_lock(&sp->members_lock);
618 	list_add(&nd->list, &sp->members);
619 	sp->members_count++;
620 	mutex_unlock(&sp->members_lock);
621 
622 	return &nd->item;
623 }
624 
625 static void drop_node(struct config_group *g, struct config_item *i)
626 {
627 	struct dlm_space *sp = config_item_to_space(g->cg_item.ci_parent);
628 	struct dlm_node *nd = config_item_to_node(i);
629 	struct dlm_member_gone *mb_gone;
630 
631 	mb_gone = kzalloc_obj(*mb_gone);
632 	if (!mb_gone)
633 		return;
634 
635 	mutex_lock(&sp->members_lock);
636 	list_del(&nd->list);
637 	sp->members_count--;
638 
639 	mb_gone->nodeid = nd->nodeid;
640 	mb_gone->release_recover = nd->release_recover;
641 	list_add(&mb_gone->list, &sp->members_gone);
642 	sp->members_gone_count++;
643 	mutex_unlock(&sp->members_lock);
644 
645 	config_item_put(i);
646 }
647 
648 static void release_node(struct config_item *i)
649 {
650 	struct dlm_node *nd = config_item_to_node(i);
651 	kfree(nd);
652 }
653 
654 static struct dlm_clusters clusters_root = {
655 	.subsys = {
656 		.su_group = {
657 			.cg_item = {
658 				.ci_namebuf = "dlm",
659 				.ci_type = &clusters_type,
660 			},
661 		},
662 	},
663 };
664 
665 int __init dlm_config_init(void)
666 {
667 	config_group_init(&clusters_root.subsys.su_group);
668 	mutex_init(&clusters_root.subsys.su_mutex);
669 	return configfs_register_subsystem(&clusters_root.subsys);
670 }
671 
672 void dlm_config_exit(void)
673 {
674 	configfs_unregister_subsystem(&clusters_root.subsys);
675 }
676 
677 /*
678  * Functions for user space to read/write attributes
679  */
680 
681 static ssize_t comm_nodeid_show(struct config_item *item, char *buf)
682 {
683 	unsigned int nodeid;
684 	int rv;
685 
686 	rv = kstrtouint(config_item_name(item), 0, &nodeid);
687 	if (WARN_ON(rv))
688 		return rv;
689 
690 	return sprintf(buf, "%u\n", nodeid);
691 }
692 
693 static ssize_t comm_nodeid_store(struct config_item *item, const char *buf,
694 				 size_t len)
695 {
696 	return len;
697 }
698 
699 static ssize_t comm_local_show(struct config_item *item, char *buf)
700 {
701 	return sprintf(buf, "%d\n", config_item_to_comm(item)->local);
702 }
703 
704 static ssize_t comm_local_store(struct config_item *item, const char *buf,
705 				size_t len)
706 {
707 	struct dlm_comm *cm = config_item_to_comm(item);
708 	int rc = kstrtoint(buf, 0, &cm->local);
709 
710 	if (rc)
711 		return rc;
712 	if (cm->local && !local_comm)
713 		local_comm = cm;
714 	return len;
715 }
716 
717 static ssize_t comm_addr_store(struct config_item *item, const char *buf,
718 		size_t len)
719 {
720 	struct dlm_comm *cm = config_item_to_comm(item);
721 	struct sockaddr_storage *addr;
722 	int rv;
723 
724 	if (len != sizeof(struct sockaddr_storage))
725 		return -EINVAL;
726 
727 	if (cm->addr_count >= DLM_MAX_ADDR_COUNT)
728 		return -ENOSPC;
729 
730 	addr = kzalloc_obj(*addr, GFP_NOFS);
731 	if (!addr)
732 		return -ENOMEM;
733 
734 	memcpy(addr, buf, len);
735 
736 	rv = dlm_midcomms_addr(cm->nodeid, addr);
737 	if (rv) {
738 		kfree(addr);
739 		return rv;
740 	}
741 
742 	cm->addr[cm->addr_count++] = addr;
743 	return len;
744 }
745 
746 static ssize_t comm_addr_list_show(struct config_item *item, char *buf)
747 {
748 	struct dlm_comm *cm = config_item_to_comm(item);
749 	ssize_t s;
750 	ssize_t allowance;
751 	int i;
752 	struct sockaddr_storage *addr;
753 	struct sockaddr_in *addr_in;
754 	struct sockaddr_in6 *addr_in6;
755 
756 	/* Taken from ip6_addr_string() defined in lib/vsprintf.c */
757 	char buf0[sizeof("AF_INET6	xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255\n")];
758 
759 
760 	/* Derived from SIMPLE_ATTR_SIZE of fs/configfs/file.c */
761 	allowance = 4096;
762 	buf[0] = '\0';
763 
764 	for (i = 0; i < cm->addr_count; i++) {
765 		addr = cm->addr[i];
766 
767 		switch(addr->ss_family) {
768 		case AF_INET:
769 			addr_in = (struct sockaddr_in *)addr;
770 			s = sprintf(buf0, "AF_INET	%pI4\n", &addr_in->sin_addr.s_addr);
771 			break;
772 		case AF_INET6:
773 			addr_in6 = (struct sockaddr_in6 *)addr;
774 			s = sprintf(buf0, "AF_INET6	%pI6\n", &addr_in6->sin6_addr);
775 			break;
776 		default:
777 			s = sprintf(buf0, "%s\n", "<UNKNOWN>");
778 			break;
779 		}
780 		allowance -= s;
781 		if (allowance >= 0)
782 			strcat(buf, buf0);
783 		else {
784 			allowance += s;
785 			break;
786 		}
787 	}
788 	return 4096 - allowance;
789 }
790 
791 static ssize_t comm_mark_show(struct config_item *item, char *buf)
792 {
793 	return sprintf(buf, "%u\n", config_item_to_comm(item)->mark);
794 }
795 
796 static ssize_t comm_mark_store(struct config_item *item, const char *buf,
797 			       size_t len)
798 {
799 	struct dlm_comm *comm;
800 	unsigned int mark;
801 	int rc;
802 
803 	rc = kstrtouint(buf, 0, &mark);
804 	if (rc)
805 		return rc;
806 
807 	if (mark == 0)
808 		mark = dlm_config.ci_mark;
809 
810 	comm = config_item_to_comm(item);
811 	rc = dlm_lowcomms_nodes_set_mark(comm->nodeid, mark);
812 	if (rc)
813 		return rc;
814 
815 	comm->mark = mark;
816 	return len;
817 }
818 
819 CONFIGFS_ATTR(comm_, nodeid);
820 CONFIGFS_ATTR(comm_, local);
821 CONFIGFS_ATTR(comm_, mark);
822 CONFIGFS_ATTR_WO(comm_, addr);
823 CONFIGFS_ATTR_RO(comm_, addr_list);
824 
825 static struct configfs_attribute *comm_attrs[] = {
826 	[COMM_ATTR_NODEID] = &comm_attr_nodeid,
827 	[COMM_ATTR_LOCAL] = &comm_attr_local,
828 	[COMM_ATTR_ADDR] = &comm_attr_addr,
829 	[COMM_ATTR_ADDR_LIST] = &comm_attr_addr_list,
830 	[COMM_ATTR_MARK] = &comm_attr_mark,
831 	NULL,
832 };
833 
834 static ssize_t node_nodeid_show(struct config_item *item, char *buf)
835 {
836 	unsigned int nodeid;
837 	int rv;
838 
839 	rv = kstrtouint(config_item_name(item), 0, &nodeid);
840 	if (WARN_ON(rv))
841 		return rv;
842 
843 	return sprintf(buf, "%u\n", nodeid);
844 }
845 
846 static ssize_t node_nodeid_store(struct config_item *item, const char *buf,
847 				 size_t len)
848 {
849 	return len;
850 }
851 
852 static ssize_t node_weight_show(struct config_item *item, char *buf)
853 {
854 	return sprintf(buf, "%d\n", config_item_to_node(item)->weight);
855 }
856 
857 static ssize_t node_weight_store(struct config_item *item, const char *buf,
858 				 size_t len)
859 {
860 	struct dlm_node *node = config_item_to_node(item);
861 	int weight;
862 	int rc;
863 
864 	rc = kstrtoint(buf, 0, &weight);
865 	if (rc)
866 		return rc;
867 	if (weight < 0)
868 		return -EINVAL;
869 
870 	node->weight = weight;
871 	return len;
872 }
873 
874 static ssize_t node_release_recover_show(struct config_item *item, char *buf)
875 {
876 	struct dlm_node *n = config_item_to_node(item);
877 
878 	return sprintf(buf, "%u\n", n->release_recover);
879 }
880 
881 static ssize_t node_release_recover_store(struct config_item *item,
882 					  const char *buf, size_t len)
883 {
884 	struct dlm_node *n = config_item_to_node(item);
885 	int rc;
886 
887 	rc = kstrtouint(buf, 0, &n->release_recover);
888 	if (rc)
889 		return rc;
890 
891 	return len;
892 }
893 
894 CONFIGFS_ATTR(node_, nodeid);
895 CONFIGFS_ATTR(node_, weight);
896 CONFIGFS_ATTR(node_, release_recover);
897 
898 static struct configfs_attribute *node_attrs[] = {
899 	[NODE_ATTR_NODEID] = &node_attr_nodeid,
900 	[NODE_ATTR_WEIGHT] = &node_attr_weight,
901 	[NODE_ATTR_RELEASE_RECOVER] = &node_attr_release_recover,
902 	NULL,
903 };
904 
905 /*
906  * Functions for the dlm to get the info that's been configured
907  */
908 
909 static struct dlm_space *get_space(char *name)
910 {
911 	struct config_item *i;
912 
913 	if (!space_list)
914 		return NULL;
915 
916 	mutex_lock(&space_list->cg_subsys->su_mutex);
917 	i = config_group_find_item(space_list, name);
918 	mutex_unlock(&space_list->cg_subsys->su_mutex);
919 
920 	return config_item_to_space(i);
921 }
922 
923 static void put_space(struct dlm_space *sp)
924 {
925 	config_item_put(&sp->group.cg_item);
926 }
927 
928 static struct dlm_comm *get_comm(int nodeid)
929 {
930 	struct config_item *i;
931 	struct dlm_comm *cm = NULL;
932 	int found = 0;
933 
934 	if (!comm_list)
935 		return NULL;
936 
937 	WARN_ON_ONCE(!mutex_is_locked(&clusters_root.subsys.su_mutex));
938 
939 	list_for_each_entry(i, &comm_list->cg_children, ci_entry) {
940 		cm = config_item_to_comm(i);
941 
942 		if (cm->nodeid != nodeid)
943 			continue;
944 		found = 1;
945 		config_item_get(i);
946 		break;
947 	}
948 
949 	if (!found)
950 		cm = NULL;
951 	return cm;
952 }
953 
954 static void put_comm(struct dlm_comm *cm)
955 {
956 	config_item_put(&cm->item);
957 }
958 
959 /* caller must free mem */
960 int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out,
961 		     int *count_out)
962 {
963 	struct dlm_member_gone *mb_gone, *mb_safe;
964 	struct dlm_config_node *nodes, *node;
965 	struct dlm_space *sp;
966 	struct dlm_node *nd;
967 	int rv, count;
968 
969 	sp = get_space(lsname);
970 	if (!sp)
971 		return -EEXIST;
972 
973 	mutex_lock(&sp->members_lock);
974 	if (!sp->members_count) {
975 		rv = -EINVAL;
976 		printk(KERN_ERR "dlm: zero members_count\n");
977 		goto out;
978 	}
979 
980 	count = sp->members_count + sp->members_gone_count;
981 
982 	nodes = kzalloc_objs(struct dlm_config_node, count, GFP_NOFS);
983 	if (!nodes) {
984 		rv = -ENOMEM;
985 		goto out;
986 	}
987 
988 	node = nodes;
989 	list_for_each_entry(nd, &sp->members, list) {
990 		node->nodeid = nd->nodeid;
991 		node->weight = nd->weight;
992 		node->new = nd->new;
993 		node->comm_seq = nd->comm_seq;
994 		node++;
995 
996 		nd->new = 0;
997 	}
998 
999 	/* we delay the remove on nodes until here as configfs does
1000 	 * not support addtional attributes for rmdir().
1001 	 */
1002 	list_for_each_entry_safe(mb_gone, mb_safe, &sp->members_gone, list) {
1003 		node->nodeid = mb_gone->nodeid;
1004 		node->release_recover = mb_gone->release_recover;
1005 		node->gone = true;
1006 		node++;
1007 
1008 		list_del(&mb_gone->list);
1009 		sp->members_gone_count--;
1010 		kfree(mb_gone);
1011 	}
1012 
1013 	*count_out = count;
1014 	*nodes_out = nodes;
1015 	rv = 0;
1016  out:
1017 	mutex_unlock(&sp->members_lock);
1018 	put_space(sp);
1019 	return rv;
1020 }
1021 
1022 int dlm_comm_seq(int nodeid, uint32_t *seq, bool locked)
1023 {
1024 	struct dlm_comm *cm;
1025 
1026 	if (locked) {
1027 		cm = get_comm(nodeid);
1028 	} else {
1029 		mutex_lock(&clusters_root.subsys.su_mutex);
1030 		cm = get_comm(nodeid);
1031 		mutex_unlock(&clusters_root.subsys.su_mutex);
1032 	}
1033 	if (!cm)
1034 		return -ENOENT;
1035 
1036 	*seq = cm->seq;
1037 	put_comm(cm);
1038 	return 0;
1039 }
1040 
1041 int dlm_our_nodeid(void)
1042 {
1043 	return local_comm->nodeid;
1044 }
1045 
1046 /* num 0 is first addr, num 1 is second addr */
1047 int dlm_our_addr(struct sockaddr_storage *addr, int num)
1048 {
1049 	if (!local_comm)
1050 		return -1;
1051 	if (num + 1 > local_comm->addr_count)
1052 		return -1;
1053 	memcpy(addr, local_comm->addr[num], sizeof(*addr));
1054 	return 0;
1055 }
1056 
1057 /* Config file defaults */
1058 #define DEFAULT_TCP_PORT       21064
1059 #define DEFAULT_RSBTBL_SIZE     1024
1060 #define DEFAULT_RECOVER_TIMER      5
1061 #define DEFAULT_TOSS_SECS         10
1062 #define DEFAULT_SCAN_SECS          5
1063 #define DEFAULT_LOG_DEBUG          0
1064 #define DEFAULT_LOG_INFO           1
1065 #define DEFAULT_PROTOCOL           DLM_PROTO_TCP
1066 #define DEFAULT_MARK               0
1067 #define DEFAULT_NEW_RSB_COUNT    128
1068 #define DEFAULT_RECOVER_CALLBACKS  0
1069 #define DEFAULT_CLUSTER_NAME      ""
1070 
1071 struct dlm_config_info dlm_config = {
1072 	.ci_tcp_port = cpu_to_be16(DEFAULT_TCP_PORT),
1073 	.ci_buffer_size = DLM_MAX_SOCKET_BUFSIZE,
1074 	.ci_rsbtbl_size = DEFAULT_RSBTBL_SIZE,
1075 	.ci_recover_timer = DEFAULT_RECOVER_TIMER,
1076 	.ci_toss_secs = DEFAULT_TOSS_SECS,
1077 	.ci_scan_secs = DEFAULT_SCAN_SECS,
1078 	.ci_log_debug = DEFAULT_LOG_DEBUG,
1079 	.ci_log_info = DEFAULT_LOG_INFO,
1080 	.ci_protocol = DEFAULT_PROTOCOL,
1081 	.ci_mark = DEFAULT_MARK,
1082 	.ci_new_rsb_count = DEFAULT_NEW_RSB_COUNT,
1083 	.ci_recover_callbacks = DEFAULT_RECOVER_CALLBACKS,
1084 	.ci_cluster_name = DEFAULT_CLUSTER_NAME
1085 };
1086 
1087