diff options
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r-- | net/tipc/name_table.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 09dcd54b04e1..042e8e3cabc0 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -148,8 +148,7 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, | |||
148 | */ | 148 | */ |
149 | static struct sub_seq *tipc_subseq_alloc(u32 cnt) | 149 | static struct sub_seq *tipc_subseq_alloc(u32 cnt) |
150 | { | 150 | { |
151 | struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC); | 151 | return kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC); |
152 | return sseq; | ||
153 | } | 152 | } |
154 | 153 | ||
155 | /** | 154 | /** |
@@ -942,20 +941,48 @@ int tipc_nametbl_init(void) | |||
942 | return 0; | 941 | return 0; |
943 | } | 942 | } |
944 | 943 | ||
945 | void tipc_nametbl_stop(void) | 944 | /** |
945 | * tipc_purge_publications - remove all publications for a given type | ||
946 | * | ||
947 | * tipc_nametbl_lock must be held when calling this function | ||
948 | */ | ||
949 | static void tipc_purge_publications(struct name_seq *seq) | ||
946 | { | 950 | { |
947 | u32 i; | 951 | struct publication *publ, *safe; |
952 | struct sub_seq *sseq; | ||
953 | struct name_info *info; | ||
948 | 954 | ||
949 | if (!table.types) | 955 | if (!seq->sseqs) { |
956 | nameseq_delete_empty(seq); | ||
950 | return; | 957 | return; |
958 | } | ||
959 | sseq = seq->sseqs; | ||
960 | info = sseq->info; | ||
961 | list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) { | ||
962 | tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node, | ||
963 | publ->ref, publ->key); | ||
964 | } | ||
965 | } | ||
966 | |||
967 | void tipc_nametbl_stop(void) | ||
968 | { | ||
969 | u32 i; | ||
970 | struct name_seq *seq; | ||
971 | struct hlist_head *seq_head; | ||
972 | struct hlist_node *safe; | ||
951 | 973 | ||
952 | /* Verify name table is empty, then release it */ | 974 | /* Verify name table is empty and purge any lingering |
975 | * publications, then release the name table | ||
976 | */ | ||
953 | write_lock_bh(&tipc_nametbl_lock); | 977 | write_lock_bh(&tipc_nametbl_lock); |
954 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { | 978 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { |
955 | if (hlist_empty(&table.types[i])) | 979 | if (hlist_empty(&table.types[i])) |
956 | continue; | 980 | continue; |
957 | pr_err("nametbl_stop(): orphaned hash chain detected\n"); | 981 | seq_head = &table.types[i]; |
958 | break; | 982 | hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) { |
983 | tipc_purge_publications(seq); | ||
984 | } | ||
985 | continue; | ||
959 | } | 986 | } |
960 | kfree(table.types); | 987 | kfree(table.types); |
961 | table.types = NULL; | 988 | table.types = NULL; |