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

Commit 768f3591 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by David S. Miller
Browse files

[NETNS]: Cleanup list walking in setup_net and cleanup_net



I proposed introducing a list_for_each_entry_continue_reverse macro
to be used in setup_net() when unrolling the failed ->init callback.

Here is the macro and some more cleanup in the setup_net() itself
to remove one variable from the stack :) The same thing is for the
cleanup_net() - the existing list_for_each_entry_reverse() is used.

Minor, but the code looks nicer.

Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
Acked-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a348ccc
Loading
Loading
Loading
Loading
+14 −0
Original line number Original line Diff line number Diff line
@@ -524,6 +524,20 @@ static inline void list_splice_init_rcu(struct list_head *list,
	     prefetch(pos->member.next), &pos->member != (head);	\
	     prefetch(pos->member.next), &pos->member != (head);	\
	     pos = list_entry(pos->member.next, typeof(*pos), member))
	     pos = list_entry(pos->member.next, typeof(*pos), member))


/**
 * list_for_each_entry_continue_reverse - iterate backwards from the given point
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_struct within the struct.
 *
 * Start to iterate over list of given type backwards, continuing after
 * the current position.
 */
#define list_for_each_entry_continue_reverse(pos, head, member)		\
	for (pos = list_entry(pos->member.prev, typeof(*pos), member);	\
	     prefetch(pos->member.prev), &pos->member != (head);	\
	     pos = list_entry(pos->member.prev, typeof(*pos), member))

/**
/**
 * list_for_each_entry_from - iterate over list of given type from the current point
 * list_for_each_entry_from - iterate over list of given type from the current point
 * @pos:	the type * to use as a loop cursor.
 * @pos:	the type * to use as a loop cursor.
+4 −8
Original line number Original line Diff line number Diff line
@@ -56,7 +56,6 @@ static void net_free(struct net *net)
static void cleanup_net(struct work_struct *work)
static void cleanup_net(struct work_struct *work)
{
{
	struct pernet_operations *ops;
	struct pernet_operations *ops;
	struct list_head *ptr;
	struct net *net;
	struct net *net;


	net = container_of(work, struct net, work);
	net = container_of(work, struct net, work);
@@ -69,8 +68,7 @@ static void cleanup_net(struct work_struct *work)
	net_unlock();
	net_unlock();


	/* Run all of the network namespace exit methods */
	/* Run all of the network namespace exit methods */
	list_for_each_prev(ptr, &pernet_list) {
	list_for_each_entry_reverse(ops, &pernet_list, list) {
		ops = list_entry(ptr, struct pernet_operations, list);
		if (ops->exit)
		if (ops->exit)
			ops->exit(net);
			ops->exit(net);
	}
	}
@@ -102,7 +100,6 @@ static int setup_net(struct net *net)
{
{
	/* Must be called with net_mutex held */
	/* Must be called with net_mutex held */
	struct pernet_operations *ops;
	struct pernet_operations *ops;
	struct list_head *ptr;
	int error;
	int error;


	memset(net, 0, sizeof(struct net));
	memset(net, 0, sizeof(struct net));
@@ -110,8 +107,7 @@ static int setup_net(struct net *net)
	atomic_set(&net->use_count, 0);
	atomic_set(&net->use_count, 0);


	error = 0;
	error = 0;
	list_for_each(ptr, &pernet_list) {
	list_for_each_entry(ops, &pernet_list, list) {
		ops = list_entry(ptr, struct pernet_operations, list);
		if (ops->init) {
		if (ops->init) {
			error = ops->init(net);
			error = ops->init(net);
			if (error < 0)
			if (error < 0)
@@ -120,12 +116,12 @@ static int setup_net(struct net *net)
	}
	}
out:
out:
	return error;
	return error;

out_undo:
out_undo:
	/* Walk through the list backwards calling the exit functions
	/* Walk through the list backwards calling the exit functions
	 * for the pernet modules whose init functions did not fail.
	 * for the pernet modules whose init functions did not fail.
	 */
	 */
	for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) {
	list_for_each_entry_continue_reverse(ops, &pernet_list, list) {
		ops = list_entry(ptr, struct pernet_operations, list);
		if (ops->exit)
		if (ops->exit)
			ops->exit(net);
			ops->exit(net);
	}
	}