[PATCH] firewire: fix "kobject_add failed for fw* with -EEXIST"

From: Stefan Richter
Date: Sat Jan 26 2008 - 19:06:37 EST


There is a race between shutdown and creation of devices: fw-core may
attempt to add a device with the same name of an already existing
device. http://bugzilla.kernel.org/show_bug.cgi?id=9828

Impact of the bug: Happens rarely, forces the user to unplug and replug
the new device to get it working.

The fix is to defer the deregistration of the minor number until after
device_unregister(). This requires an adjustment of the device lookup
function though to prevent the character device from being newly opened
during shutdown.

Signed-off-by: Stefan Richter <stefanr@xxxxxxxxxxxxxxxxx>
---
drivers/firewire/fw-device.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

Index: linux/drivers/firewire/fw-device.c
===================================================================
--- linux.orig/drivers/firewire/fw-device.c
+++ linux/drivers/firewire/fw-device.c
@@ -616,6 +616,8 @@ struct fw_device *fw_device_from_devt(de

down_read(&idr_rwsem);
device = idr_find(&fw_device_idr, MINOR(devt));
+ if (fw_device_is_shutdown(device))
+ device = NULL;
up_read(&idr_rwsem);

return device;
@@ -627,13 +629,13 @@ static void fw_device_shutdown(struct wo
container_of(work, struct fw_device, work.work);
int minor = MINOR(device->device.devt);

- down_write(&idr_rwsem);
- idr_remove(&fw_device_idr, minor);
- up_write(&idr_rwsem);
-
fw_device_cdev_remove(device);
device_for_each_child(&device->device, NULL, shutdown_unit);
+
+ down_write(&idr_rwsem);
device_unregister(&device->device);
+ idr_remove(&fw_device_idr, minor);
+ up_write(&idr_rwsem);
}

static struct device_type fw_device_type = {

--
Stefan Richter
-=====-==--- ---= ==-==
http://arcgraph.de/sr/

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/