]> xenbits.xensource.com Git - pvdrivers/win/xenvbd.git/commitdiff
Fix target enumeration
authorOwen Smith <owen.smith@citrix.com>
Mon, 29 Jun 2015 10:13:50 +0000 (11:13 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Fri, 10 Jul 2015 16:42:31 +0000 (17:42 +0100)
Issues were found when enumeration races with plug/unplug. This patch
should fix these problems.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Signed-off-by: Owen Smith <owen.smith@citrix.com>
src/xenvbd/fdo.c
src/xenvbd/pdo.c

index f240a97b1d3e3559a914dc73262930b9673a1221..b146f7c835e4cd585aa3169271ebb52d925cd4f5 100644 (file)
@@ -619,31 +619,29 @@ __FdoEnumerate(
     *NeedReboot = FALSE;
 
     for (TargetId = 0; TargetId < XENVBD_MAX_TARGETS; ++TargetId) {
+        BOOLEAN     Missing = TRUE;
+
         Pdo = __FdoGetPdo(Fdo, TargetId);
         if (Pdo == NULL)
             continue;
 
-        if (!PdoIsMissing(Pdo)) {
-            BOOLEAN Missing = TRUE;
-            for (Device = Devices; *Device; Device = __NextSz(Device)) {
-                ULONG DeviceTargetId = __ParseVbd(Device);
-                if (TargetId == DeviceTargetId) {
-                    Missing = FALSE;
-                    break;
-                }
-            }
-            if (Missing) {
-                PdoSetMissing(Pdo, "Device Dissappeared");
-                if (PdoGetDevicePnpState(Pdo) == Present)
-                    PdoSetDevicePnpState(Pdo, Deleted);
-                else
-                    *NeedInvalidate = TRUE;
+        for (Device = Devices; *Device; Device = __NextSz(Device)) {
+            ULONG DeviceTargetId = __ParseVbd(Device);
+            if (TargetId == DeviceTargetId) {
+                Missing = FALSE;
+                break;
             }
         }
-        
-        if (PdoIsMissing(Pdo) && 
-            PdoGetDevicePnpState(Pdo) == Deleted) {
-            // drop reference count before destroying
+
+        if (Missing && !PdoIsMissing(Pdo)) {
+            PdoSetMissing(Pdo, "Device Disappeared");
+            if (PdoGetDevicePnpState(Pdo) == Present)
+                PdoSetDevicePnpState(Pdo, Deleted);
+            else
+                *NeedInvalidate = TRUE;
+        }
+
+        if (PdoGetDevicePnpState(Pdo) == Deleted) {
             PdoDereference(Pdo);
             PdoDestroy(Pdo);
         } else {
index c5ec9b6bf463fa04cd737b5a4763e749d0fcbc3e..89bfc5af0885f13b6f23e1fec184cf90dd3ca030 100644 (file)
@@ -415,8 +415,16 @@ PdoSetDevicePnpState(
     __in DEVICE_PNP_STATE        State
     )
 {
-    ASSERT(Pdo->DevicePnpState != Deleted || State == Deleted);
-    Verbose("Target[%d] : PNP %s to %s\n", PdoGetTargetId(Pdo), __PnpStateName(Pdo->DevicePnpState), __PnpStateName(State));
+    Verbose("Target[%d] : PNP %s to %s\n",
+            PdoGetTargetId(Pdo),
+            __PnpStateName(Pdo->DevicePnpState),
+            __PnpStateName(State));
+
+    if (Pdo->DevicePnpState == Deleted) {
+        ASSERT(State == Deleted);
+        return;
+    }
+
     Pdo->PrevPnpState = Pdo->DevicePnpState;
     Pdo->DevicePnpState = State;
 }