Skip to content

Commit accda73

Browse files
committed
When issuing IO handle broken, missing devices and failures
Previously we would issue the IO and assume everything is going according to plan, this meant in the case of failure to issue IO, we would hang forever. For example if the device is removed. Now we check the return code of IoCallDriver(), and handle both direct failures, or sync calls (instead of expected async call). This gives us a better chance of detecting ejected, removed or failed devices. Signed-off-by: Jorgen Lundman <lundman@lundman.net>
1 parent 9d3c72a commit accda73

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

include/os/windows/zfs/sys/zfs_context_os.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
IRP *irp; \
3535
void *b_addr; \
3636
IO_STATUS_BLOCK IoStatus; \
37+
boolean_t completion_called; \
3738
PIO_WORKITEM work_item; \
3839
} windows;
3940

module/os/windows/zfs/vdev_disk.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,8 @@ vdev_disk_io_intr(PDEVICE_OBJECT DeviceObject, PIRP irp, PVOID Context)
753753
*/
754754

755755
VERIFY3P(zio->windows.work_item, !=, NULL);
756+
zio->windows.completion_called = B_TRUE;
757+
756758
IoQueueWorkItem(zio->windows.work_item,
757759
(PIO_WORKITEM_ROUTINE)vdev_disk_io_start_done,
758760
DelayedWorkQueue, zio);
@@ -924,6 +926,7 @@ vdev_disk_io_start(zio_t *zio)
924926
}
925927

926928
zio->windows.irp = irp;
929+
zio->windows.completion_called = B_FALSE;
927930

928931
irpStack = IoGetNextIrpStackLocation(irp);
929932

@@ -937,8 +940,18 @@ vdev_disk_io_start(zio_t *zio)
937940
TRUE, // On Error
938941
TRUE); // On Cancel
939942

940-
IoCallDriver(dvd->vd_DeviceObject, irp);
943+
NTSTATUS Status;
944+
Status = IoCallDriver(dvd->vd_DeviceObject, irp);
945+
946+
// IO is in progress asynchronously...
947+
if (Status == STATUS_PENDING)
948+
return;
941949

950+
// IO completed synchronously or failed to start
951+
// we clean up manually, assuming the completion
952+
// callback was not called.
953+
if (!zio->windows.completion_called)
954+
vdev_disk_io_start_done(NULL, zio);
942955
}
943956

944957
static void

0 commit comments

Comments
 (0)