|
@@ -941,17 +941,48 @@ int tipc_nametbl_init(void)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * tipc_purge_publications - remove all publications for a given type
|
|
|
+ *
|
|
|
+ * tipc_nametbl_lock must be held when calling this function
|
|
|
+ */
|
|
|
+static void tipc_purge_publications(struct name_seq *seq)
|
|
|
+{
|
|
|
+ struct publication *publ, *safe;
|
|
|
+ struct sub_seq *sseq;
|
|
|
+ struct name_info *info;
|
|
|
+
|
|
|
+ if (!seq->sseqs) {
|
|
|
+ nameseq_delete_empty(seq);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ sseq = seq->sseqs;
|
|
|
+ info = sseq->info;
|
|
|
+ list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) {
|
|
|
+ tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node,
|
|
|
+ publ->ref, publ->key);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
void tipc_nametbl_stop(void)
|
|
|
{
|
|
|
u32 i;
|
|
|
+ struct name_seq *seq;
|
|
|
+ struct hlist_head *seq_head;
|
|
|
+ struct hlist_node *safe;
|
|
|
|
|
|
- /* Verify name table is empty, then release it */
|
|
|
+ /* Verify name table is empty and purge any lingering
|
|
|
+ * publications, then release the name table
|
|
|
+ */
|
|
|
write_lock_bh(&tipc_nametbl_lock);
|
|
|
for (i = 0; i < TIPC_NAMETBL_SIZE; i++) {
|
|
|
if (hlist_empty(&table.types[i]))
|
|
|
continue;
|
|
|
- pr_err("nametbl_stop(): orphaned hash chain detected\n");
|
|
|
- break;
|
|
|
+ seq_head = &table.types[i];
|
|
|
+ hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) {
|
|
|
+ tipc_purge_publications(seq);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
}
|
|
|
kfree(table.types);
|
|
|
table.types = NULL;
|