|
@@ -153,11 +153,11 @@ void tipc_ref_table_stop(void)
|
|
|
|
|
|
u32 tipc_ref_acquire(void *object, spinlock_t **lock)
|
|
|
{
|
|
|
- struct reference *entry;
|
|
|
u32 index;
|
|
|
u32 index_mask;
|
|
|
u32 next_plus_upper;
|
|
|
u32 ref;
|
|
|
+ struct reference *entry = NULL;
|
|
|
|
|
|
if (!object) {
|
|
|
err("Attempt to acquire reference to non-existent object\n");
|
|
@@ -175,30 +175,36 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
|
|
|
index = tipc_ref_table.first_free;
|
|
|
entry = &(tipc_ref_table.entries[index]);
|
|
|
index_mask = tipc_ref_table.index_mask;
|
|
|
- /* take lock in case a previous user of entry still holds it */
|
|
|
- spin_lock_bh(&entry->lock);
|
|
|
next_plus_upper = entry->ref;
|
|
|
tipc_ref_table.first_free = next_plus_upper & index_mask;
|
|
|
ref = (next_plus_upper & ~index_mask) + index;
|
|
|
- entry->ref = ref;
|
|
|
- entry->object = object;
|
|
|
- *lock = &entry->lock;
|
|
|
}
|
|
|
else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
|
|
|
index = tipc_ref_table.init_point++;
|
|
|
entry = &(tipc_ref_table.entries[index]);
|
|
|
spin_lock_init(&entry->lock);
|
|
|
- spin_lock_bh(&entry->lock);
|
|
|
ref = tipc_ref_table.start_mask + index;
|
|
|
- entry->ref = ref;
|
|
|
- entry->object = object;
|
|
|
- *lock = &entry->lock;
|
|
|
}
|
|
|
else {
|
|
|
ref = 0;
|
|
|
}
|
|
|
write_unlock_bh(&ref_table_lock);
|
|
|
|
|
|
+ /*
|
|
|
+ * Grab the lock so no one else can modify this entry
|
|
|
+ * While we assign its ref value & object pointer
|
|
|
+ */
|
|
|
+ if (entry) {
|
|
|
+ spin_lock_bh(&entry->lock);
|
|
|
+ entry->ref = ref;
|
|
|
+ entry->object = object;
|
|
|
+ *lock = &entry->lock;
|
|
|
+ /*
|
|
|
+ * keep it locked, the caller is responsible
|
|
|
+ * for unlocking this when they're done with it
|
|
|
+ */
|
|
|
+ }
|
|
|
+
|
|
|
return ref;
|
|
|
}
|
|
|
|