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; |
