Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ba169cc authored by Sunil Mushran's avatar Sunil Mushran
Browse files

ocfs2/cluster: Add new function o2net_fill_node_map()



Patch adds function o2net_fill_node_map() to return the bitmap of nodes that
it is connected to. This bitmap is also accessible by the user via the debugfs
file, /sys/kernel/debug/o2net/connected_nodes.

Signed-off-by: default avatarSunil Mushran <sunil.mushran@oracle.com>
parent bb570a5d
Loading
Loading
Loading
Loading
+69 −33
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#define SC_DEBUG_NAME		"sock_containers"
#define NST_DEBUG_NAME		"send_tracking"
#define STATS_DEBUG_NAME	"stats"
#define NODES_DEBUG_NAME	"connected_nodes"

#define SHOW_SOCK_CONTAINERS	0
#define SHOW_SOCK_STATS		1
@@ -55,6 +56,7 @@ static struct dentry *o2net_dentry;
static struct dentry *sc_dentry;
static struct dentry *nst_dentry;
static struct dentry *stats_dentry;
static struct dentry *nodes_dentry;

static DEFINE_SPINLOCK(o2net_debug_lock);

@@ -491,53 +493,87 @@ static const struct file_operations sc_seq_fops = {
	.release = sc_fop_release,
};

int o2net_debugfs_init(void)
static int o2net_fill_bitmap(char *buf, int len)
{
	o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
	if (!o2net_dentry) {
		mlog_errno(-ENOMEM);
		goto bail;
	}
	unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)];
	int i = -1, out = 0;

	nst_dentry = debugfs_create_file(NST_DEBUG_NAME, S_IFREG|S_IRUSR,
					 o2net_dentry, NULL,
					 &nst_seq_fops);
	if (!nst_dentry) {
		mlog_errno(-ENOMEM);
		goto bail;
	}
	o2net_fill_node_map(map, sizeof(map));

	sc_dentry = debugfs_create_file(SC_DEBUG_NAME, S_IFREG|S_IRUSR,
					o2net_dentry, NULL,
					&sc_seq_fops);
	if (!sc_dentry) {
		mlog_errno(-ENOMEM);
		goto bail;
	while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES)
		out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i);
	out += snprintf(buf + out, PAGE_SIZE - out, "\n");

	return out;
}

	stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR,
					   o2net_dentry, NULL,
					   &stats_seq_fops);
	if (!stats_dentry) {
		mlog_errno(-ENOMEM);
		goto bail;
static int nodes_fop_open(struct inode *inode, struct file *file)
{
	char *buf;

	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	i_size_write(inode, o2net_fill_bitmap(buf, PAGE_SIZE));

	file->private_data = buf;

	return 0;
}

static int o2net_debug_release(struct inode *inode, struct file *file)
{
	kfree(file->private_data);
	return 0;
bail:
	debugfs_remove(stats_dentry);
	debugfs_remove(sc_dentry);
	debugfs_remove(nst_dentry);
	debugfs_remove(o2net_dentry);
	return -ENOMEM;
}

static ssize_t o2net_debug_read(struct file *file, char __user *buf,
				size_t nbytes, loff_t *ppos)
{
	return simple_read_from_buffer(buf, nbytes, ppos, file->private_data,
				       i_size_read(file->f_mapping->host));
}

static const struct file_operations nodes_fops = {
	.open		= nodes_fop_open,
	.release	= o2net_debug_release,
	.read		= o2net_debug_read,
	.llseek		= generic_file_llseek,
};

void o2net_debugfs_exit(void)
{
	debugfs_remove(nodes_dentry);
	debugfs_remove(stats_dentry);
	debugfs_remove(sc_dentry);
	debugfs_remove(nst_dentry);
	debugfs_remove(o2net_dentry);
}

int o2net_debugfs_init(void)
{
	mode_t mode = S_IFREG|S_IRUSR;

	o2net_dentry = debugfs_create_dir(O2NET_DEBUG_DIR, NULL);
	if (o2net_dentry)
		nst_dentry = debugfs_create_file(NST_DEBUG_NAME, mode,
					o2net_dentry, NULL, &nst_seq_fops);
	if (nst_dentry)
		sc_dentry = debugfs_create_file(SC_DEBUG_NAME, mode,
					o2net_dentry, NULL, &sc_seq_fops);
	if (sc_dentry)
		stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, mode,
					o2net_dentry, NULL, &stats_seq_fops);
	if (stats_dentry)
		nodes_dentry = debugfs_create_file(NODES_DEBUG_NAME, mode,
					o2net_dentry, NULL, &nodes_fops);
	if (nodes_dentry)
		return 0;

	o2net_debugfs_exit();
	mlog_errno(-ENOMEM);
	return -ENOMEM;
}

#endif	/* CONFIG_DEBUG_FS */
+19 −0
Original line number Diff line number Diff line
@@ -1034,6 +1034,25 @@ static int o2net_tx_can_proceed(struct o2net_node *nn,
	return ret;
}

/* Get a map of all nodes to which this node is currently connected to */
void o2net_fill_node_map(unsigned long *map, unsigned bytes)
{
	struct o2net_sock_container *sc;
	int node, ret;

	BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long)));

	memset(map, 0, bytes);
	for (node = 0; node < O2NM_MAX_NODES; ++node) {
		o2net_tx_can_proceed(o2net_nn_from_num(node), &sc, &ret);
		if (!ret) {
			set_bit(node, map);
			sc_put(sc);
		}
	}
}
EXPORT_SYMBOL_GPL(o2net_fill_node_map);

int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
			   size_t caller_veclen, u8 target_node, int *status)
{
+2 −0
Original line number Diff line number Diff line
@@ -106,6 +106,8 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
			   struct list_head *unreg_list);
void o2net_unregister_handler_list(struct list_head *list);

void o2net_fill_node_map(unsigned long *map, unsigned bytes);

struct o2nm_node;
int o2net_register_hb_callbacks(void);
void o2net_unregister_hb_callbacks(void);