Index: linux/dev/glue/block.c =================================================================== --- linux/dev/glue/block.c.orig 2006-10-15 20:39:24.000000000 +0300 +++ linux/dev/glue/block.c 2006-11-14 04:15:19.000000000 +0200 @@ -789,6 +789,7 @@ static struct block_data *open_list; extern struct device_emulation_ops linux_block_emulation_ops; static io_return_t device_close (void *); +static io_return_t device_close_forced (void *, int); /* Return a send right for block device BD. */ static ipc_port_t @@ -1164,6 +1165,7 @@ out: { ipc_kobject_set (bd->port, IKO_NULL, IKOT_NONE); ipc_port_dealloc_kernel (bd->port); + *devp = IP_NULL; } kfree ((vm_offset_t) bd, sizeof (struct block_data)); bd = NULL; @@ -1174,18 +1176,16 @@ out: bd->open_count = 1; bd->next = open_list; open_list = bd; + *devp = &bd -> device; } - if (IP_VALID (reply_port)) - ds_device_open_reply (reply_port, reply_port_type, err, dev_to_port (bd)); - else if (! err) + if (!IP_VALID (reply_port) && ! err) device_close (bd); - - return MIG_NO_REPLY; + return err; } static io_return_t -device_close (void *d) +device_close_forced (void *d, int force) { struct block_data *bd = d, *bdp, **prev; struct device_struct *ds = bd->ds; @@ -1202,7 +1202,7 @@ device_close (void *d) } ds->busy = 1; - if (--bd->open_count == 0) + if (force || --bd->open_count == 0) { /* Wait for pending I/O to complete. */ while (bd->iocount > 0) @@ -1245,6 +1245,13 @@ device_close (void *d) return D_SUCCESS; } +static io_return_t +device_close (void *d) +{ + return device_close_forced (d, 0); +} + + #define MAX_COPY (VM_MAP_COPY_PAGE_LIST_MAX << PAGE_SHIFT) /* Check block BN and size COUNT for I/O validity @@ -1704,6 +1711,16 @@ device_get_status (void *d, dev_flavor_t return D_SUCCESS; } + +static void +device_no_senders (mach_no_senders_notification_t *ns) +{ + device_t dev; + + dev = (device_t) ((ipc_port_t) ns->not_header.msgh_remote_port) -> ip_kobject; + device_close_forced (dev->emul_data, 1); +} + struct device_emulation_ops linux_block_emulation_ops = { NULL, @@ -1719,7 +1736,7 @@ struct device_emulation_ops linux_block_ device_get_status, NULL, NULL, - NULL, + device_no_senders, NULL, NULL }; Index: i386/i386at/i386at_ds_routines.c =================================================================== --- i386/i386at/i386at_ds_routines.c.orig 2006-11-14 03:58:56.000000000 +0200 +++ i386/i386at/i386at_ds_routines.c 2006-11-14 04:15:19.000000000 +0200 @@ -232,7 +232,8 @@ ds_notify (mach_msg_header_t *msg) mach_no_senders_notification_t *ns; ns = (mach_no_senders_notification_t *) msg; - dev = (device_t) ns->not_header.msgh_remote_port; + dev = (device_t) ((ipc_port_t) ns->not_header.msgh_remote_port) + -> ip_kobject; if (dev->emul_ops->no_senders) (*dev->emul_ops->no_senders) (ns); return TRUE;