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

Commit 10c3c022 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'tipc-fixes'



Jon Maloy says:

====================
tipc: name distributor pernet queue

Commit #1 fixes a potential issue with deferred binding table
updates being pushed to the wrong namespace.

Commit #2 solves a problem with deferred binding table updates
remaining in the the defer queue after the issuing node has gone
down.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ebf4dc2b ddb1d339
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ static int __net_init tipc_init_net(struct net *net)
	if (err)
		goto out_nametbl;

	INIT_LIST_HEAD(&tn->dist_queue);
	err = tipc_topsrv_start(net);
	if (err)
		goto out_subscr;
+3 −0
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ struct tipc_net {
	spinlock_t nametbl_lock;
	struct name_table *nametbl;

	/* Name dist queue */
	struct list_head dist_queue;

	/* Topology subscription server */
	struct tipc_server *topsrv;
	atomic_t subscription_count;
+26 −9
Original line number Diff line number Diff line
@@ -40,11 +40,6 @@

int sysctl_tipc_named_timeout __read_mostly = 2000;

/**
 * struct tipc_dist_queue - queue holding deferred name table updates
 */
static struct list_head tipc_dist_queue = LIST_HEAD_INIT(tipc_dist_queue);

struct distr_queue_item {
	struct distr_item i;
	u32 dtype;
@@ -229,12 +224,31 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
	kfree_rcu(p, rcu);
}

/**
 * tipc_dist_queue_purge - remove deferred updates from a node that went down
 */
static void tipc_dist_queue_purge(struct net *net, u32 addr)
{
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	struct distr_queue_item *e, *tmp;

	spin_lock_bh(&tn->nametbl_lock);
	list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) {
		if (e->node != addr)
			continue;
		list_del(&e->next);
		kfree(e);
	}
	spin_unlock_bh(&tn->nametbl_lock);
}

void tipc_publ_notify(struct net *net, struct list_head *nsub_list, u32 addr)
{
	struct publication *publ, *tmp;

	list_for_each_entry_safe(publ, tmp, nsub_list, nodesub_list)
		tipc_publ_purge(net, publ, addr);
	tipc_dist_queue_purge(net, addr);
}

/**
@@ -279,9 +293,11 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
 * tipc_named_add_backlog - add a failed name table update to the backlog
 *
 */
static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node)
static void tipc_named_add_backlog(struct net *net, struct distr_item *i,
				   u32 type, u32 node)
{
	struct distr_queue_item *e;
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	unsigned long now = get_jiffies_64();

	e = kzalloc(sizeof(*e), GFP_ATOMIC);
@@ -291,7 +307,7 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node)
	e->node = node;
	e->expires = now + msecs_to_jiffies(sysctl_tipc_named_timeout);
	memcpy(e, i, sizeof(*i));
	list_add_tail(&e->next, &tipc_dist_queue);
	list_add_tail(&e->next, &tn->dist_queue);
}

/**
@@ -301,10 +317,11 @@ static void tipc_named_add_backlog(struct distr_item *i, u32 type, u32 node)
void tipc_named_process_backlog(struct net *net)
{
	struct distr_queue_item *e, *tmp;
	struct tipc_net *tn = net_generic(net, tipc_net_id);
	char addr[16];
	unsigned long now = get_jiffies_64();

	list_for_each_entry_safe(e, tmp, &tipc_dist_queue, next) {
	list_for_each_entry_safe(e, tmp, &tn->dist_queue, next) {
		if (time_after(e->expires, now)) {
			if (!tipc_update_nametbl(net, &e->i, e->node, e->dtype))
				continue;
@@ -344,7 +361,7 @@ void tipc_named_rcv(struct net *net, struct sk_buff_head *inputq)
		node = msg_orignode(msg);
		while (count--) {
			if (!tipc_update_nametbl(net, item, node, mtype))
				tipc_named_add_backlog(item, mtype, node);
				tipc_named_add_backlog(net, item, mtype, node);
			item++;
		}
		kfree_skb(skb);