diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2007-09-18 16:20:41 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:51:35 -0400 |
commit | 768f3591e2b1cc309fd6f10d6579b216026d7817 (patch) | |
tree | 0328abd6a6a306e648120ac2ef20332954e852e0 | |
parent | 1a348ccc1047a00507e554826775a3d81f7f3437 (diff) |
[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: Pavel Emelyanov <xemul@openvz.org>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/list.h | 14 | ||||
-rw-r--r-- | net/core/net_namespace.c | 12 |
2 files changed, 18 insertions, 8 deletions
diff --git a/include/linux/list.h b/include/linux/list.h index f29fc9c1a964..ad9dcb9e3375 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -525,6 +525,20 @@ static inline void list_splice_init_rcu(struct list_head *list, | |||
525 | pos = list_entry(pos->member.next, typeof(*pos), member)) | 525 | pos = list_entry(pos->member.next, typeof(*pos), member)) |
526 | 526 | ||
527 | /** | 527 | /** |
528 | * list_for_each_entry_continue_reverse - iterate backwards from the given point | ||
529 | * @pos: the type * to use as a loop cursor. | ||
530 | * @head: the head for your list. | ||
531 | * @member: the name of the list_struct within the struct. | ||
532 | * | ||
533 | * Start to iterate over list of given type backwards, continuing after | ||
534 | * the current position. | ||
535 | */ | ||
536 | #define list_for_each_entry_continue_reverse(pos, head, member) \ | ||
537 | for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ | ||
538 | prefetch(pos->member.prev), &pos->member != (head); \ | ||
539 | pos = list_entry(pos->member.prev, typeof(*pos), member)) | ||
540 | |||
541 | /** | ||
528 | * list_for_each_entry_from - iterate over list of given type from the current point | 542 | * list_for_each_entry_from - iterate over list of given type from the current point |
529 | * @pos: the type * to use as a loop cursor. | 543 | * @pos: the type * to use as a loop cursor. |
530 | * @head: the head for your list. | 544 | * @head: the head for your list. |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 1fc513c4c79e..0e6cb02d7b77 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -56,7 +56,6 @@ static void net_free(struct net *net) | |||
56 | static void cleanup_net(struct work_struct *work) | 56 | static void cleanup_net(struct work_struct *work) |
57 | { | 57 | { |
58 | struct pernet_operations *ops; | 58 | struct pernet_operations *ops; |
59 | struct list_head *ptr; | ||
60 | struct net *net; | 59 | struct net *net; |
61 | 60 | ||
62 | net = container_of(work, struct net, work); | 61 | net = container_of(work, struct net, work); |
@@ -69,8 +68,7 @@ static void cleanup_net(struct work_struct *work) | |||
69 | net_unlock(); | 68 | net_unlock(); |
70 | 69 | ||
71 | /* Run all of the network namespace exit methods */ | 70 | /* Run all of the network namespace exit methods */ |
72 | list_for_each_prev(ptr, &pernet_list) { | 71 | list_for_each_entry_reverse(ops, &pernet_list, list) { |
73 | ops = list_entry(ptr, struct pernet_operations, list); | ||
74 | if (ops->exit) | 72 | if (ops->exit) |
75 | ops->exit(net); | 73 | ops->exit(net); |
76 | } | 74 | } |
@@ -102,7 +100,6 @@ static int setup_net(struct net *net) | |||
102 | { | 100 | { |
103 | /* Must be called with net_mutex held */ | 101 | /* Must be called with net_mutex held */ |
104 | struct pernet_operations *ops; | 102 | struct pernet_operations *ops; |
105 | struct list_head *ptr; | ||
106 | int error; | 103 | int error; |
107 | 104 | ||
108 | memset(net, 0, sizeof(struct net)); | 105 | memset(net, 0, sizeof(struct net)); |
@@ -110,8 +107,7 @@ static int setup_net(struct net *net) | |||
110 | atomic_set(&net->use_count, 0); | 107 | atomic_set(&net->use_count, 0); |
111 | 108 | ||
112 | error = 0; | 109 | error = 0; |
113 | list_for_each(ptr, &pernet_list) { | 110 | list_for_each_entry(ops, &pernet_list, list) { |
114 | ops = list_entry(ptr, struct pernet_operations, list); | ||
115 | if (ops->init) { | 111 | if (ops->init) { |
116 | error = ops->init(net); | 112 | error = ops->init(net); |
117 | if (error < 0) | 113 | if (error < 0) |
@@ -120,12 +116,12 @@ static int setup_net(struct net *net) | |||
120 | } | 116 | } |
121 | out: | 117 | out: |
122 | return error; | 118 | return error; |
119 | |||
123 | out_undo: | 120 | out_undo: |
124 | /* Walk through the list backwards calling the exit functions | 121 | /* Walk through the list backwards calling the exit functions |
125 | * for the pernet modules whose init functions did not fail. | 122 | * for the pernet modules whose init functions did not fail. |
126 | */ | 123 | */ |
127 | for (ptr = ptr->prev; ptr != &pernet_list; ptr = ptr->prev) { | 124 | list_for_each_entry_continue_reverse(ops, &pernet_list, list) { |
128 | ops = list_entry(ptr, struct pernet_operations, list); | ||
129 | if (ops->exit) | 125 | if (ops->exit) |
130 | ops->exit(net); | 126 | ops->exit(net); |
131 | } | 127 | } |