Commit 8418cb40 authored by Guvenc Gulce's avatar Guvenc Gulce Committed by David S. Miller
Browse files

net/smc: use the retry mechanism for netlink messages



When the netlink messages to be sent to the userspace
are too big for a single netlink message, send them in
chunks using the netlink_dump infrastructure. Modify the
smc diag dump code so that it can signal to the netlink_dump
infrastructure that it needs to send more data.

Signed-off-by: default avatarGuvenc Gulce <guvenc@linux.ibm.com>
Signed-off-by: default avatarKarsten Graul <kgraul@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 219d9aef
Loading
Loading
Loading
Loading
+23 −7
Original line number Diff line number Diff line
@@ -22,6 +22,15 @@
#include "smc.h"
#include "smc_core.h"

struct smc_diag_dump_ctx {
	int pos[2];
};

static struct smc_diag_dump_ctx *smc_dump_context(struct netlink_callback *cb)
{
	return (struct smc_diag_dump_ctx *)cb->ctx;
}

static void smc_gid_be16_convert(__u8 *buf, u8 *gid_raw)
{
	sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
@@ -193,13 +202,15 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
}

static int smc_diag_dump_proto(struct proto *prot, struct sk_buff *skb,
			       struct netlink_callback *cb)
			       struct netlink_callback *cb, int p_type)
{
	struct smc_diag_dump_ctx *cb_ctx = smc_dump_context(cb);
	struct net *net = sock_net(skb->sk);
	int snum = cb_ctx->pos[p_type];
	struct nlattr *bc = NULL;
	struct hlist_head *head;
	int rc = 0, num = 0;
	struct sock *sk;
	int rc = 0;

	read_lock(&prot->h.smc_hash->lock);
	head = &prot->h.smc_hash->ht;
@@ -209,13 +220,18 @@ static int smc_diag_dump_proto(struct proto *prot, struct sk_buff *skb,
	sk_for_each(sk, head) {
		if (!net_eq(sock_net(sk), net))
			continue;
		if (num < snum)
			goto next;
		rc = __smc_diag_dump(sk, skb, cb, nlmsg_data(cb->nlh), bc);
		if (rc)
			break;
		if (rc < 0)
			goto out;
next:
		num++;
	}

out:
	read_unlock(&prot->h.smc_hash->lock);
	cb_ctx->pos[p_type] = num;
	return rc;
}

@@ -223,10 +239,10 @@ static int smc_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
	int rc = 0;

	rc = smc_diag_dump_proto(&smc_proto, skb, cb);
	rc = smc_diag_dump_proto(&smc_proto, skb, cb, SMCPROTO_SMC);
	if (!rc)
		rc = smc_diag_dump_proto(&smc_proto6, skb, cb);
	return rc;
		smc_diag_dump_proto(&smc_proto6, skb, cb, SMCPROTO_SMC6);
	return skb->len;
}

static int smc_diag_handler_dump(struct sk_buff *skb, struct nlmsghdr *h)