]> git.baikalelectronics.ru Git - kernel.git/commit
firewire: fw-sbp2: fix refcounting
authorStefan Richter <stefanr@s5r6.in-berlin.de>
Wed, 7 Nov 2007 00:11:56 +0000 (01:11 +0100)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Wed, 7 Nov 2007 00:59:28 +0000 (01:59 +0100)
commit0a45b8252e5a1e626494fd9098e0872a872b45f2
tree49a6bd70e0d221ba6456d6a3c2e403e7d5f5bfaf
parent8bb901a4e7b5aea2c4b19b9476bf2ec825d5770e
firewire: fw-sbp2: fix refcounting

Since patch "fw-sbp2: use an own workqueue (fix system responsiveness)"
increased parallelism between fw-sbp2 and fw-core, it was possible that
fw-sbp2 didn't release the SCSI device when the FireWire device was
disconnected.

This happened if sbp2_update() ran during sbp2_login(), because a bus
reset occurred during sbp2_login().  The sbp2_login() work would [try
to] reschedule itself because it failed due to the bus reset, and it
would _not_ drop its reference on the target.  However, sbp2_update()
would schedule sbp2_login() too before sbp2_login() rescheduled itself
and hence sbp2_update() would take an additional reference.  And then
we would have one reference too many.

The fix is to _always_ drop the reference when leaving the sbp2_login()
work.  If the sbp2_login() work reschedules itself, it takes a
reference, but only if it wasn't already rescheduled by sbp2_update().

Ditto in the sbp2_reconnect() work.

The resulting code is actually simpler than before:  We _always_ take
a reference when successfully scheduling work.  And we _always_ drop
a reference when leaving a workqueue job.  No exceptions.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
drivers/firewire/fw-sbp2.c