summaryrefslogtreecommitdiff
path: root/debian/patches/10_cdromlock.patch
blob: 6401fc8af4936dfaa093f1d206d8cacd8c577afb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
merged upstream

Index: b/linux/dev/glue/block.c
===================================================================
--- a/linux/dev/glue/block.c
+++ b/linux/dev/glue/block.c
@@ -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,17 @@ device_get_status (void *d, dev_flavor_t
   return D_INVALID_OPERATION;
 }
 
+
+static void
+device_no_senders (mach_no_senders_notification_t *ns)
+{
+  device_t dev;
+
+  dev = dev_port_lookup((ipc_port_t) ns->not_header.msgh_remote_port);
+  assert(dev);
+  device_close_forced (dev->emul_data, 1);
+}
+
 struct device_emulation_ops linux_block_emulation_ops =
 {
   NULL,
@@ -1719,7 +1737,7 @@ struct device_emulation_ops linux_block_
   device_get_status,
   NULL,
   NULL,
-  NULL,
+  device_no_senders,
   NULL,
   NULL
 };