diff options
Diffstat (limited to 'net/tipc/ref.c')
| -rw-r--r-- | net/tipc/ref.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 33bbf5095094..e6d6ae22ea49 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c | |||
| @@ -63,7 +63,7 @@ | |||
| 63 | 63 | ||
| 64 | struct ref_table tipc_ref_table = { NULL }; | 64 | struct ref_table tipc_ref_table = { NULL }; |
| 65 | 65 | ||
| 66 | static rwlock_t ref_table_lock = RW_LOCK_UNLOCKED; | 66 | static DEFINE_RWLOCK(ref_table_lock); |
| 67 | 67 | ||
| 68 | /** | 68 | /** |
| 69 | * tipc_ref_table_init - create reference table for objects | 69 | * tipc_ref_table_init - create reference table for objects |
| @@ -79,7 +79,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start) | |||
| 79 | while (sz < requested_size) { | 79 | while (sz < requested_size) { |
| 80 | sz <<= 1; | 80 | sz <<= 1; |
| 81 | } | 81 | } |
| 82 | table = (struct reference *)vmalloc(sz * sizeof(struct reference)); | 82 | table = vmalloc(sz * sizeof(*table)); |
| 83 | if (table == NULL) | 83 | if (table == NULL) |
| 84 | return -ENOMEM; | 84 | return -ENOMEM; |
| 85 | 85 | ||
| @@ -87,7 +87,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start) | |||
| 87 | index_mask = sz - 1; | 87 | index_mask = sz - 1; |
| 88 | for (i = sz - 1; i >= 0; i--) { | 88 | for (i = sz - 1; i >= 0; i--) { |
| 89 | table[i].object = NULL; | 89 | table[i].object = NULL; |
| 90 | table[i].lock = SPIN_LOCK_UNLOCKED; | 90 | spin_lock_init(&table[i].lock); |
| 91 | table[i].data.next_plus_upper = (start & ~index_mask) + i - 1; | 91 | table[i].data.next_plus_upper = (start & ~index_mask) + i - 1; |
| 92 | } | 92 | } |
| 93 | tipc_ref_table.entries = table; | 93 | tipc_ref_table.entries = table; |
| @@ -127,7 +127,14 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) | |||
| 127 | u32 next_plus_upper; | 127 | u32 next_plus_upper; |
| 128 | u32 reference = 0; | 128 | u32 reference = 0; |
| 129 | 129 | ||
| 130 | assert(tipc_ref_table.entries && object); | 130 | if (!object) { |
| 131 | err("Attempt to acquire reference to non-existent object\n"); | ||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | if (!tipc_ref_table.entries) { | ||
| 135 | err("Reference table not found during acquisition attempt\n"); | ||
| 136 | return 0; | ||
| 137 | } | ||
| 131 | 138 | ||
| 132 | write_lock_bh(&ref_table_lock); | 139 | write_lock_bh(&ref_table_lock); |
| 133 | if (tipc_ref_table.first_free) { | 140 | if (tipc_ref_table.first_free) { |
| @@ -162,15 +169,28 @@ void tipc_ref_discard(u32 ref) | |||
| 162 | u32 index; | 169 | u32 index; |
| 163 | u32 index_mask; | 170 | u32 index_mask; |
| 164 | 171 | ||
| 165 | assert(tipc_ref_table.entries); | 172 | if (!ref) { |
| 166 | assert(ref != 0); | 173 | err("Attempt to discard reference 0\n"); |
| 174 | return; | ||
| 175 | } | ||
| 176 | if (!tipc_ref_table.entries) { | ||
| 177 | err("Reference table not found during discard attempt\n"); | ||
| 178 | return; | ||
| 179 | } | ||
| 167 | 180 | ||
| 168 | write_lock_bh(&ref_table_lock); | 181 | write_lock_bh(&ref_table_lock); |
| 169 | index_mask = tipc_ref_table.index_mask; | 182 | index_mask = tipc_ref_table.index_mask; |
| 170 | index = ref & index_mask; | 183 | index = ref & index_mask; |
| 171 | entry = &(tipc_ref_table.entries[index]); | 184 | entry = &(tipc_ref_table.entries[index]); |
| 172 | assert(entry->object != 0); | 185 | |
| 173 | assert(entry->data.reference == ref); | 186 | if (!entry->object) { |
| 187 | err("Attempt to discard reference to non-existent object\n"); | ||
| 188 | goto exit; | ||
| 189 | } | ||
| 190 | if (entry->data.reference != ref) { | ||
| 191 | err("Attempt to discard non-existent reference\n"); | ||
| 192 | goto exit; | ||
| 193 | } | ||
| 174 | 194 | ||
| 175 | /* mark entry as unused */ | 195 | /* mark entry as unused */ |
| 176 | entry->object = NULL; | 196 | entry->object = NULL; |
| @@ -184,6 +204,7 @@ void tipc_ref_discard(u32 ref) | |||
| 184 | 204 | ||
| 185 | /* increment upper bits of entry to invalidate subsequent references */ | 205 | /* increment upper bits of entry to invalidate subsequent references */ |
| 186 | entry->data.next_plus_upper = (ref & ~index_mask) + (index_mask + 1); | 206 | entry->data.next_plus_upper = (ref & ~index_mask) + (index_mask + 1); |
| 207 | exit: | ||
| 187 | write_unlock_bh(&ref_table_lock); | 208 | write_unlock_bh(&ref_table_lock); |
| 188 | } | 209 | } |
| 189 | 210 | ||
