* Updating device->removed must be protected by the device lock

* Also updating device->open_count must be protected by the device list lock

This fixes the (unlikely) case where a device was removed from usb_disk
standpoint while it still had an open read/write/ioctl operation.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24811 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2008-04-05 16:42:34 +00:00
parent b6b5de0741
commit 86dd3875cd
1 changed files with 27 additions and 22 deletions

View File

@ -632,12 +632,14 @@ usb_disk_device_removed(void *cookie)
}
gLunCount -= device->lun_count;
gDeviceCount--;
benaphore_unlock(&gDeviceListLock);
device->device = 0;
benaphore_lock(&device->lock);
device->removed = true;
benaphore_unlock(&device->lock);
if (device->open_count == 0)
usb_disk_free_device_and_luns(device);
benaphore_unlock(&gDeviceListLock);
return B_OK;
}
@ -799,12 +801,13 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
{
device_lun *lun = (device_lun *)cookie;
disk_device *device = lun->device;
if (device->removed)
return B_DEV_NOT_READY;
benaphore_lock(&device->lock);
status_t result = B_DEV_INVALID_IOCTL;
if (device->removed) {
benaphore_unlock(&device->lock);
return B_DEV_NOT_READY;
}
status_t result = B_DEV_INVALID_IOCTL;
switch (op) {
case B_GET_MEDIA_STATUS: {
*(status_t *)buffer = usb_disk_test_unit_ready(lun);
@ -852,18 +855,19 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
static status_t
usb_disk_read(void *cookie, off_t position, void *buffer, size_t *length)
{
TRACE("read(%lld, %ld)\n", position, *length);
device_lun *lun = (device_lun *)cookie;
disk_device *device = lun->device;
if (device->removed) {
*length = 0;
return B_DEV_NOT_READY;
}
if (buffer == NULL || length == NULL)
return B_BAD_VALUE;
TRACE("read(%lld, %ld)\n", position, *length);
device_lun *lun = (device_lun *)cookie;
disk_device *device = lun->device;
benaphore_lock(&device->lock);
if (device->removed) {
*length = 0;
benaphore_unlock(&device->lock);
return B_DEV_NOT_READY;
}
status_t result = B_ERROR;
uint32 blockPosition = 0;
uint16 blockCount = 0;
@ -899,18 +903,19 @@ static status_t
usb_disk_write(void *cookie, off_t position, const void *buffer,
size_t *length)
{
TRACE("write(%lld, %ld)\n", position, *length);
device_lun *lun = (device_lun *)cookie;
disk_device *device = lun->device;
if (device->removed) {
*length = 0;
return B_DEV_NOT_READY;
}
if (buffer == NULL || length == NULL)
return B_BAD_VALUE;
TRACE("write(%lld, %ld)\n", position, *length);
device_lun *lun = (device_lun *)cookie;
disk_device *device = lun->device;
benaphore_lock(&device->lock);
if (device->removed) {
*length = 0;
benaphore_unlock(&device->lock);
return B_DEV_NOT_READY;
}
status_t result = B_ERROR;
uint32 blockPosition = 0;
uint16 blockCount = 0;