aboutsummaryrefslogtreecommitdiff
path: root/net/tipc/ref.c
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2010-10-28 00:15:57 +0200
committerMichal Marek <mmarek@suse.cz>2010-10-28 00:15:57 +0200
commitb74b953b998bcc2db91b694446f3a2619ec32de6 (patch)
tree6ce24caabd730f6ae9287ed0676ec32e6ff31e9d /net/tipc/ref.c
parentabb438526201c6a79949ad45375c051b6681c253 (diff)
parentf6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff)
Merge commit 'v2.6.36' into kbuild/misc
Update to be able to fix a recent change to scripts/basic/docproc.c (commit eda603f).
Diffstat (limited to 'net/tipc/ref.c')
-rw-r--r--net/tipc/ref.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 414fc34b8be..8dea66500cf 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -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;
}