diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-18 16:45:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-18 16:45:01 -0700 |
commit | 2e0c17d100c35e843dac1e99daf19b5e2b3fe168 (patch) | |
tree | 5bb58364fb453298819fe479cad95f5fcfeb8edf /net/tipc | |
parent | 7de4a9a73563e5f6f3c153015fadee433a443241 (diff) | |
parent | 22001a13d09d82772e831dcdac0553994a4bac5d (diff) | |
download | kernel-crypto-2e0c17d100c35e843dac1e99daf19b5e2b3fe168.tar.gz kernel-crypto-2e0c17d100c35e843dac1e99daf19b5e2b3fe168.tar.xz kernel-crypto-2e0c17d100c35e843dac1e99daf19b5e2b3fe168.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (39 commits)
gigaset: fix build failure
bridge: Make first arg to deliver_clone const.
bridge br_multicast: Don't refer to BR_INPUT_SKB_CB(skb)->mrouters_only without IGMP snooping.
route: Fix caught BUG_ON during rt_secret_rebuild_oneshot()
bridge br_multicast: Fix skb leakage in error path.
bridge br_multicast: Fix handling of Max Response Code in IGMPv3 message.
NET: netpoll, fix potential NULL ptr dereference
tipc: fix lockdep warning on address assignment
l2tp: Fix UDP socket reference count bugs in the pppol2tp driver
smsc95xx: wait for PHY to complete reset during init
l2tp: Fix oops in pppol2tp_xmit
smsc75xx: SMSC LAN75xx USB gigabit ethernet adapter driver
ne: Do not use slashes in irq name string
NET: ksz884x, fix lock imbalance
gigaset: correct range checking off by one error
bridge: Fix br_forward crash in promiscuous mode
bridge: Move NULL mdb check into br_mdb_ip_get
ISDN: Add PCI ID for HFC-2S/4S Beronet Card PCIe
net-2.6 [Bug-Fix][dccp]: fix oops caused after failed initialisation
myri: remove dead code
...
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/ref.c | 26 |
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; } |