Annotation of ntddk/src/scsi/diskperf/diskperf.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1991  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     diskperf.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This driver monitors disk accesses capturing performance data.
                     12: 
                     13: Authors:
                     14: 
                     15:     Mike Glass
                     16:     Bob Rinne
                     17: 
                     18: Environment:
                     19: 
                     20:     kernel mode only
                     21: 
                     22: Notes:
                     23: 
                     24: Revision History:
                     25: 
                     26: --*/
                     27: 
                     28: #include "ntddk.h"
                     29: #include "stdarg.h"
                     30: #include "stdio.h"
                     31: #include "ntdddisk.h"
                     32: 
                     33: //
                     34: // This macro has the effect of Bit = log2(Data)
                     35: // and is used to calculate sector shifts.
                     36: //
                     37: 
                     38: #define WHICH_BIT(Data, Bit) {        \
                     39:     for (Bit = 0; Bit < 32; Bit++) {  \
                     40:         if ((Data >> Bit) == 1) {     \
                     41:             break;                    \
                     42:         }                             \
                     43:     }                                 \
                     44: }
                     45: 
                     46: //
                     47: // Device Extension
                     48: //
                     49: 
                     50: typedef struct _DEVICE_EXTENSION {
                     51: 
                     52:     //
                     53:     // Back pointer to device object
                     54:     //
                     55: 
                     56:     PDEVICE_OBJECT DeviceObject;
                     57: 
                     58:     //
                     59:     // Target Device Object
                     60:     //
                     61: 
                     62:     PDEVICE_OBJECT TargetDeviceObject;
                     63: 
                     64:     //
                     65:     // Physical Device Object
                     66:     //
                     67: 
                     68:     PDEVICE_OBJECT PhysicalDevice;
                     69: 
                     70:     //
                     71:     // Sector size
                     72:     //
                     73: 
                     74:     ULONG SectorSize;
                     75: 
                     76:     //
                     77:     // Sector Shift Count
                     78:     //
                     79: 
                     80:     ULONG SectorShift;
                     81: 
                     82:     //
                     83:     // Disk performance counters
                     84:     //
                     85: 
                     86:     DISK_PERFORMANCE DiskCounters;
                     87: 
                     88:     //
                     89:     // Spinlock for counters (physical disks only)
                     90:     //
                     91: 
                     92:     KSPIN_LOCK Spinlock;
                     93: 
                     94: } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
                     95: 
                     96: #define DEVICE_EXTENSION_SIZE sizeof(DEVICE_EXTENSION)
                     97: 
                     98: 
                     99: //
                    100: // Function declarations
                    101: //
                    102: 
                    103: NTSTATUS
                    104: DriverEntry(
                    105:     IN PDRIVER_OBJECT DriverObject,
                    106:     IN PUNICODE_STRING RegistryPath
                    107:     );
                    108: 
                    109: VOID
                    110: DiskPerfInitialize(
                    111:     IN PDRIVER_OBJECT DriverObject,
                    112:     IN PVOID NextDisk,
                    113:     IN ULONG Count
                    114:     );
                    115: 
                    116: NTSTATUS
                    117: DiskPerfCreate(
                    118:     IN PDEVICE_OBJECT DeviceObject,
                    119:     IN PIRP Irp
                    120:     );
                    121: 
                    122: NTSTATUS
                    123: DiskPerfReadWrite(
                    124:     IN PDEVICE_OBJECT DeviceObject,
                    125:     IN PIRP Irp
                    126:     );
                    127: 
                    128: NTSTATUS
                    129: DiskPerfIoCompletion(
                    130:     IN PDEVICE_OBJECT DeviceObject,
                    131:     IN PIRP Irp,
                    132:     IN PVOID Context
                    133:     );
                    134: 
                    135: NTSTATUS
                    136: DiskPerfDeviceControl(
                    137:     IN PDEVICE_OBJECT DeviceObject,
                    138:     IN PIRP Irp
                    139:     );
                    140: 
                    141: NTSTATUS
                    142: DiskPerfShutdownFlush(
                    143:     IN PDEVICE_OBJECT DeviceObject,
                    144:     IN PIRP Irp
                    145:     );
                    146: 
                    147: 
                    148: NTSTATUS
                    149: DriverEntry(
                    150:     IN PDRIVER_OBJECT DriverObject,
                    151:     IN PUNICODE_STRING RegistryPath
                    152:     )
                    153: 
                    154: /*++
                    155: 
                    156: Routine Description:
                    157: 
                    158:     This is the routine called by the system to initialize the disk
                    159:     performance driver. The driver object is set up and then the
                    160:     driver calls DiskPerfInitialize to attach to the boot devices.
                    161: 
                    162: Arguments:
                    163: 
                    164:     DriverObject - The disk performance driver object.
                    165: 
                    166: Return Value:
                    167: 
                    168:     NTSTATUS
                    169: 
                    170: --*/
                    171: 
                    172: {
                    173: 
                    174:     //
                    175:     // Set up the device driver entry points.
                    176:     //
                    177: 
                    178:     DriverObject->MajorFunction[IRP_MJ_CREATE] = DiskPerfCreate;
                    179:     DriverObject->MajorFunction[IRP_MJ_READ] = DiskPerfReadWrite;
                    180:     DriverObject->MajorFunction[IRP_MJ_WRITE] = DiskPerfReadWrite;
                    181:     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DiskPerfDeviceControl;
                    182:     DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DiskPerfShutdownFlush;
                    183:     DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DiskPerfShutdownFlush;
                    184: 
                    185:     //
                    186:     // Call the initialization routine for the first time.
                    187:     //
                    188: 
                    189:     DiskPerfInitialize(DriverObject, 0, 0);
                    190: 
                    191:     return(STATUS_SUCCESS);
                    192: 
                    193: } // DriverEntry
                    194: 
                    195: 
                    196: VOID
                    197: DiskPerfInitialize(
                    198:     IN PDRIVER_OBJECT DriverObject,
                    199:     IN PVOID NextDisk,
                    200:     IN ULONG Count
                    201:     )
                    202: 
                    203: /*++
                    204: 
                    205: Routine Description:
                    206: 
                    207:     Attach to new disk devices and partitions.
                    208:     Set up device objects for counts and times.
                    209:     If this is the first time this routine is called,
                    210:     then register with the IO system to be called
                    211:     after all other disk device drivers have initiated.
                    212: 
                    213: Arguments:
                    214: 
                    215:     DriverObject - Disk performance driver object.
                    216:     NextDisk - Starting disk for this part of the initialization.
                    217:     Count - Not used. Number of times this routine has been called.
                    218: 
                    219: Return Value:
                    220: 
                    221:     NTSTATUS
                    222: 
                    223: --*/
                    224: 
                    225: {
                    226:     PCONFIGURATION_INFORMATION configurationInformation;
                    227:     CCHAR ntNameBuffer[256];
                    228:     STRING ntNameString;
                    229:     UNICODE_STRING ntUnicodeString;
                    230:     PDEVICE_OBJECT deviceObject;
                    231:     PDEVICE_OBJECT physicalDevice;
                    232:     PDEVICE_EXTENSION deviceExtension;
                    233:     PFILE_OBJECT fileObject;
                    234:     PIRP irp;
                    235:     PDISK_GEOMETRY diskGeometry;
                    236:     PDRIVE_LAYOUT_INFORMATION  partitionInfo;
                    237:     KEVENT event;
                    238:     IO_STATUS_BLOCK ioStatusBlock;
                    239:     NTSTATUS status;
                    240:     ULONG diskNumber;
                    241:     ULONG partNumber;
                    242: 
                    243:     //
                    244:     // Get the configuration information.
                    245:     //
                    246: 
                    247:     configurationInformation = IoGetConfigurationInformation();
                    248: 
                    249:     //
                    250:     // Find disk devices.
                    251:     //
                    252: 
                    253:     for (diskNumber = (ULONG)NextDisk;
                    254:          diskNumber < configurationInformation->DiskCount;
                    255:          diskNumber++) {
                    256: 
                    257:         //
                    258:         // Create device name for the physical disk.
                    259:         //
                    260: 
                    261:         sprintf(ntNameBuffer,
                    262:                 "\\Device\\Harddisk%d\\Partition0",
                    263:                 diskNumber);
                    264: 
                    265:         RtlInitAnsiString(&ntNameString,
                    266:                           ntNameBuffer);
                    267: 
                    268:         RtlAnsiStringToUnicodeString(&ntUnicodeString,
                    269:                                      &ntNameString,
                    270:                                      TRUE);
                    271: 
                    272:         //
                    273:         // Create device object for partition 0.
                    274:         //
                    275: 
                    276:         status = IoCreateDevice(DriverObject,
                    277:                                 sizeof(DEVICE_EXTENSION),
                    278:                                 NULL,
                    279:                                 FILE_DEVICE_DISK,
                    280:                                 0,
                    281:                                 FALSE,
                    282:                                 &physicalDevice);
                    283: 
                    284:         physicalDevice->Flags |= DO_DIRECT_IO;
                    285: 
                    286:         //
                    287:         // Point device extension back at device object.
                    288:         //
                    289: 
                    290:         deviceExtension = physicalDevice->DeviceExtension;
                    291:         deviceExtension->DeviceObject = physicalDevice;
                    292: 
                    293:         //
                    294:         // This is the physical device object.
                    295:         //
                    296: 
                    297:         deviceExtension->PhysicalDevice = physicalDevice;
                    298: 
                    299:         //
                    300:         // Attach to partition0. This call links the newly created
                    301:         // device to the target device, returning the target device object.
                    302:         //
                    303: 
                    304:         status = IoAttachDevice(physicalDevice,
                    305:                                 &ntUnicodeString,
                    306:                                 &deviceExtension->TargetDeviceObject);
                    307: 
                    308:         if (!NT_SUCCESS(status)) {
                    309:             IoDeleteDevice(physicalDevice);
                    310:             break;
                    311:         }
                    312: 
                    313:         RtlFreeUnicodeString(&ntUnicodeString);
                    314: 
                    315:         //
                    316:         // Allocate buffer for drive geometry.
                    317:         //
                    318: 
                    319:         diskGeometry = ExAllocatePool(NonPagedPool,
                    320:                                       sizeof(DISK_GEOMETRY));
                    321: 
                    322:         //
                    323:         // Create IRP for get drive geometry device control.
                    324:         //
                    325: 
                    326:         irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_GEOMETRY,
                    327:                                             deviceExtension->TargetDeviceObject,
                    328:                                             NULL,
                    329:                                             0,
                    330:                                             diskGeometry,
                    331:                                             sizeof(DISK_GEOMETRY),
                    332:                                             FALSE,
                    333:                                             &event,
                    334:                                             &ioStatusBlock);
                    335: 
                    336:         //
                    337:         // Set the event object to the unsignaled state.
                    338:         // It will be used to signal request completion.
                    339:         //
                    340: 
                    341:         KeInitializeEvent(&event,
                    342:                           NotificationEvent,
                    343:                           FALSE);
                    344: 
                    345:         //
                    346:         // No need to check the following two returned statuses as
                    347:         // ioBlockStatus will have ending status.
                    348:         //
                    349: 
                    350:         IoCallDriver(deviceExtension->TargetDeviceObject,
                    351:                      irp);
                    352: 
                    353:         KeWaitForSingleObject(&event,
                    354:                               Suspended,
                    355:                               KernelMode,
                    356:                               FALSE,
                    357:                               NULL);
                    358: 
                    359:         if (!NT_SUCCESS(ioStatusBlock.Status)) {
                    360:             ExFreePool(diskGeometry);
                    361:             IoDeleteDevice(physicalDevice);
                    362:             break;
                    363:         }
                    364: 
                    365:         //
                    366:         // Store number of bytes per sector.
                    367:         //
                    368: 
                    369:         deviceExtension->SectorSize = diskGeometry->BytesPerSector;
                    370: 
                    371:         //
                    372:         // Calculate and store sector shift.
                    373:         //
                    374: 
                    375:         WHICH_BIT(deviceExtension->SectorSize, deviceExtension->SectorShift);
                    376: 
                    377:         //
                    378:         // Initialize spinlock for performance measures.
                    379:         //
                    380: 
                    381:         KeInitializeSpinLock(&deviceExtension->Spinlock);
                    382: 
                    383:         //
                    384:         // Allocate buffer for drive layout.
                    385:         //
                    386: 
                    387:         partitionInfo = ExAllocatePool(NonPagedPool,
                    388:                                        (26 * sizeof(PARTITION_INFORMATION) + 4));
                    389: 
                    390:         //
                    391:         // Create IRP for get drive layout device control.
                    392:         //
                    393: 
                    394:         irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_DRIVE_LAYOUT,
                    395:                                             deviceExtension->TargetDeviceObject,
                    396:                                             NULL,
                    397:                                             0,
                    398:                                             partitionInfo,
                    399:                                             (26 * sizeof(PARTITION_INFORMATION) + 4),
                    400:                                             FALSE,
                    401:                                             &event,
                    402:                                             &ioStatusBlock);
                    403: 
                    404:         //
                    405:         // Set the event object to the unsignaled state.
                    406:         // It will be used to signal request completion.
                    407:         //
                    408: 
                    409:         KeInitializeEvent(&event,
                    410:                           NotificationEvent,
                    411:                           FALSE);
                    412: 
                    413:         //
                    414:         // No need to check the following two returned statuses as
                    415:         // ioBlockStatus will have ending status.
                    416:         //
                    417: 
                    418:         IoCallDriver(deviceExtension->TargetDeviceObject,
                    419:                      irp);
                    420: 
                    421:         KeWaitForSingleObject(&event,
                    422:                               Suspended,
                    423:                               KernelMode,
                    424:                               FALSE,
                    425:                               NULL);
                    426: 
                    427:         if (!NT_SUCCESS(ioStatusBlock.Status)) {
                    428:             ExFreePool(partitionInfo);
                    429:             ExFreePool(diskGeometry);
                    430:             IoDeleteDevice(physicalDevice);
                    431:             break;
                    432:         }
                    433: 
                    434:         for (partNumber = 1;
                    435:              partNumber < partitionInfo->PartitionCount;
                    436:              partNumber++) {
                    437: 
                    438:             //
                    439:             // Create device name for partition.
                    440:             //
                    441: 
                    442:             sprintf(ntNameBuffer,
                    443:                     "\\Device\\Harddisk%d\\Partition%d",
                    444:                     diskNumber,
                    445:                     partNumber);
                    446: 
                    447:             RtlInitAnsiString(&ntNameString,
                    448:                               ntNameBuffer);
                    449: 
                    450:             RtlAnsiStringToUnicodeString(&ntUnicodeString,
                    451:                                          &ntNameString,
                    452:                                          TRUE);
                    453: 
                    454:             //
                    455:             // Get target device object.
                    456:             //
                    457: 
                    458:             status = IoGetDeviceObjectPointer(&ntUnicodeString,
                    459:                                               FILE_READ_ATTRIBUTES,
                    460:                                               &fileObject,
                    461:                                               &deviceObject);
                    462: 
                    463:             if (!NT_SUCCESS(status)) {
                    464:                 RtlFreeUnicodeString(&ntUnicodeString);
                    465:                 continue;
                    466:             }
                    467: 
                    468:             //
                    469:             // Check if this device is already mounted.
                    470:             //
                    471: 
                    472:             if (!deviceObject->Vpb ||
                    473:                 (deviceObject->Vpb->Flags & VPB_MOUNTED)) {
                    474: 
                    475:                 //
                    476:                 // Can't attach to a device that is already mounted.
                    477:                 //
                    478: 
                    479:                 ObDereferenceObject(fileObject);
                    480:                 RtlFreeUnicodeString(&ntUnicodeString);
                    481:                 continue;
                    482:             }
                    483: 
                    484:             ObDereferenceObject(fileObject);
                    485: 
                    486:             //
                    487:             // Create device object for this partition.
                    488:             //
                    489: 
                    490:             status = IoCreateDevice(DriverObject,
                    491:                                     sizeof(DEVICE_EXTENSION),
                    492:                                     NULL,
                    493:                                     FILE_DEVICE_DISK,
                    494:                                     0,
                    495:                                     FALSE,
                    496:                                     &deviceObject);
                    497: 
                    498:             deviceObject->Flags |= DO_DIRECT_IO;
                    499: 
                    500:             //
                    501:             // Point device extension back at device object.
                    502:             //
                    503: 
                    504:             deviceExtension = deviceObject->DeviceExtension;
                    505:             deviceExtension->DeviceObject = deviceObject;
                    506: 
                    507:             //
                    508:             // Store pointer to physical device.
                    509:             //
                    510: 
                    511:             deviceExtension->PhysicalDevice = physicalDevice;
                    512: 
                    513:             //
                    514:             // Attach to the partition. This call links the newly created
                    515:             // device to the target device, returning the target device object.
                    516:             //
                    517: 
                    518:             status = IoAttachDevice(deviceObject,
                    519:                                     &ntUnicodeString,
                    520:                                     &deviceExtension->TargetDeviceObject);
                    521: 
                    522:             RtlFreeUnicodeString(&ntUnicodeString);
                    523: 
                    524:             if (!NT_SUCCESS(status)) {
                    525:                 ExFreePool(diskGeometry);
                    526:                 IoDeleteDevice(deviceObject);
                    527:                 break;
                    528:             }
                    529:         }
                    530:     }
                    531: 
                    532:     //
                    533:     // Check if this is the first time this routine has been called.
                    534:     //
                    535: 
                    536:     if (!NextDisk) {
                    537: 
                    538:         //
                    539:         // Register with IO system to be called a second time after all
                    540:         // other device drivers have initialized.
                    541:         //
                    542: 
                    543:         IoRegisterDriverReinitialization(DriverObject,
                    544:                                          DiskPerfInitialize,
                    545:                                          (PVOID)configurationInformation->DiskCount);
                    546:     }
                    547: 
                    548:     return;
                    549: 
                    550: } // end DiskPerfInitialize()
                    551: 
                    552: 
                    553: NTSTATUS
                    554: DiskPerfCreate(
                    555:     IN PDEVICE_OBJECT DeviceObject,
                    556:     IN PIRP Irp
                    557:     )
                    558: 
                    559: /*++
                    560: 
                    561: Routine Description:
                    562: 
                    563:     This routine services open commands. It establishes
                    564:     the driver's existance by returning status success.
                    565: 
                    566: Arguments:
                    567: 
                    568:     DeviceObject - Context for the activity.
                    569:     Irp          - The device control argument block.
                    570: 
                    571: Return Value:
                    572: 
                    573:     NT Status
                    574: 
                    575: --*/
                    576: 
                    577: {
                    578:     UNREFERENCED_PARAMETER(DeviceObject);
                    579: 
                    580:     Irp->IoStatus.Status = STATUS_SUCCESS;
                    581: 
                    582:     IoCompleteRequest(Irp, 0);
                    583:     return STATUS_SUCCESS;
                    584: 
                    585: } // end DiskPerfCreate()
                    586: 
                    587: 
                    588: NTSTATUS
                    589: DiskPerfReadWrite(
                    590:     IN PDEVICE_OBJECT DeviceObject,
                    591:     IN PIRP Irp
                    592:     )
                    593: 
                    594: /*++
                    595: 
                    596: Routine Description:
                    597: 
                    598:     This is the driver entry point for read and write requests
                    599:     to disks to which the diskperf driver has attached.
                    600:     This driver collects statistics and then sets a completion
                    601:     routine so that it can collect additional information when
                    602:     the request completes. Then it calls the next driver below
                    603:     it.
                    604: 
                    605: Arguments:
                    606: 
                    607:     DeviceObject
                    608:     Irp
                    609: 
                    610: Return Value:
                    611: 
                    612:     NTSTATUS
                    613: 
                    614: --*/
                    615: 
                    616: {
                    617:     PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
                    618:     PDEVICE_EXTENSION physicalDisk =
                    619:         deviceExtension->PhysicalDevice->DeviceExtension;
                    620:     PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
                    621:     PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
                    622: 
                    623:     //
                    624:     // Increment queue depth counter.
                    625:     //
                    626: 
                    627:     ExInterlockedIncrementLong(&deviceExtension->DiskCounters.QueueDepth,
                    628:                                &physicalDisk->Spinlock);
                    629: 
                    630:     //
                    631:     // Now get the physical disk counters and increment queue depth.
                    632:     //
                    633: 
                    634:     ExInterlockedIncrementLong(&physicalDisk->DiskCounters.QueueDepth,
                    635:                                &physicalDisk->Spinlock);
                    636: 
                    637:     //
                    638:     // Copy current stack to next stack.
                    639:     //
                    640: 
                    641:     *nextIrpStack = *currentIrpStack;
                    642: 
                    643:     //
                    644:     // Time stamp current request start.
                    645:     //
                    646: 
                    647:     currentIrpStack->Parameters.Read.ByteOffset = KeQueryPerformanceCounter((PVOID)NULL);
                    648: 
                    649:     //
                    650:     // Set completion routine callback.
                    651:     //
                    652: 
                    653:     IoSetCompletionRoutine(Irp,
                    654:                            DiskPerfIoCompletion,
                    655:                            DeviceObject,
                    656:                            TRUE,
                    657:                            TRUE,
                    658:                            TRUE);
                    659: 
                    660:     //
                    661:     // Return the results of the call to the disk driver.
                    662:     //
                    663: 
                    664:     return IoCallDriver(deviceExtension->TargetDeviceObject,
                    665:                         Irp);
                    666: 
                    667: } // end DiskPerfReadWrite()
                    668: 
                    669: 
                    670: NTSTATUS
                    671: DiskPerfIoCompletion(
                    672:     IN PDEVICE_OBJECT DeviceObject,
                    673:     IN PIRP Irp,
                    674:     IN PVOID Context
                    675:     )
                    676: 
                    677: /*++
                    678: 
                    679: Routine Description:
                    680: 
                    681:     This routine will get control from the system at the completion of an IRP.
                    682:     It will calculate the difference between the time the IRP was started
                    683:     and the current time, and decrement the queue depth.
                    684: 
                    685: Arguments:
                    686: 
                    687:     DeviceObject - for the IRP.
                    688:     Irp          - The I/O request that just completed.
                    689:     Context      - Not used.
                    690: 
                    691: Return Value:
                    692: 
                    693:     The IRP status.
                    694: 
                    695: --*/
                    696: 
                    697: {
                    698:     PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
                    699:     PDEVICE_EXTENSION physicalDisk =
                    700:         deviceExtension->PhysicalDevice->DeviceExtension;
                    701:     PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
                    702:     PDISK_PERFORMANCE partitionCounters = &deviceExtension->DiskCounters;
                    703:     PDISK_PERFORMANCE diskCounters = &physicalDisk->DiskCounters;
                    704:     LARGE_INTEGER timeStampStart =
                    705:         irpStack->Parameters.Read.ByteOffset;
                    706:     LARGE_INTEGER timeStampComplete;
                    707:     KIRQL currentIrql;
                    708: 
                    709:     UNREFERENCED_PARAMETER(Context);
                    710: 
                    711:     //
                    712:     // Determine if STATUS_PENDING was returned in the dispatch routine.
                    713:     //
                    714: 
                    715:     if (Irp->PendingReturned) {
                    716:         IoMarkIrpPending(Irp);
                    717:     }
                    718:     //
                    719:     // Time stamp current request complete.
                    720:     //
                    721: 
                    722:     timeStampComplete = KeQueryPerformanceCounter((PVOID)NULL);
                    723: 
                    724:     //
                    725:     // Update counters under spinlock protection.
                    726:     //
                    727: 
                    728:     KeAcquireSpinLock(&physicalDisk->Spinlock, &currentIrql);
                    729: 
                    730:     //
                    731:     // Decrement the queue depth counters for the volume and physical disk.
                    732:     //
                    733: 
                    734:     partitionCounters->QueueDepth--;
                    735:     diskCounters->QueueDepth--;
                    736: 
                    737: #if DBG
                    738: 
                    739:     //
                    740:     // Verify that the information field, which is used to
                    741:     // return bytes transferred, is being updated by lower drivers.
                    742:     //
                    743: 
                    744:     if (NT_SUCCESS(Irp->IoStatus.Status)) {
                    745:         ASSERT(Irp->IoStatus.Information);
                    746:     }
                    747: 
                    748: #endif
                    749: 
                    750:     if (irpStack->MajorFunction == IRP_MJ_READ) {
                    751: 
                    752:         //
                    753:         // Add bytes in this request to bytes read counters.
                    754:         //
                    755: 
                    756:         partitionCounters->BytesRead = RtlLargeIntegerAdd(partitionCounters->BytesRead,
                    757:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
                    758: 
                    759:         diskCounters->BytesRead = RtlLargeIntegerAdd(diskCounters->BytesRead,
                    760:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
                    761: 
                    762:         //
                    763:         // Increment read requests processed counters.
                    764:         //
                    765: 
                    766:         partitionCounters->ReadCount++;
                    767:         diskCounters->ReadCount++;
                    768: 
                    769:         //
                    770:         // Calculate request processing time.
                    771:         //
                    772: 
                    773:         partitionCounters->ReadTime = RtlLargeIntegerAdd(partitionCounters->ReadTime,
                    774:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
                    775: 
                    776:         diskCounters->ReadTime = RtlLargeIntegerAdd(diskCounters->ReadTime,
                    777:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
                    778: 
                    779:     } else {
                    780: 
                    781:         //
                    782:         // Add bytes in this request to bytes write counters.
                    783:         //
                    784: 
                    785:         partitionCounters->BytesWritten = RtlLargeIntegerAdd(partitionCounters->BytesWritten,
                    786:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
                    787: 
                    788:         diskCounters->BytesWritten = RtlLargeIntegerAdd(diskCounters->BytesWritten,
                    789:             RtlConvertUlongToLargeInteger(Irp->IoStatus.Information));
                    790: 
                    791:         //
                    792:         // Increment write requests processed counters.
                    793:         //
                    794: 
                    795:         partitionCounters->WriteCount++;
                    796:         diskCounters->WriteCount++;
                    797: 
                    798:         //
                    799:         // Calculate request processing time.
                    800:         //
                    801: 
                    802:         partitionCounters->WriteTime = RtlLargeIntegerAdd(partitionCounters->WriteTime,
                    803:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
                    804: 
                    805:         diskCounters->WriteTime = RtlLargeIntegerAdd(diskCounters->WriteTime,
                    806:             RtlLargeIntegerSubtract(timeStampComplete, timeStampStart));
                    807:     }
                    808: 
                    809:     //
                    810:     // Release spinlock.
                    811:     //
                    812: 
                    813:     KeReleaseSpinLock(&physicalDisk->Spinlock, currentIrql);
                    814: 
                    815:     return Irp->IoStatus.Status;
                    816: 
                    817: } // DiskPerfIoCompletion
                    818: 
                    819: 
                    820: NTSTATUS
                    821: DiskPerfDeviceControl(
                    822:     PDEVICE_OBJECT DeviceObject,
                    823:     PIRP Irp
                    824:     )
                    825: 
                    826: /*++
                    827: 
                    828: Routine Description:
                    829: 
                    830:     This device control dispatcher handles only the disk performance
                    831:     device control. All others are passed down to the disk drivers.
                    832:     The disk performane device control returns a current snapshot of
                    833:     the performance data.
                    834: 
                    835: Arguments:
                    836: 
                    837:     DeviceObject - Context for the activity.
                    838:     Irp          - The device control argument block.
                    839: 
                    840: Return Value:
                    841: 
                    842:     Status is returned.
                    843: 
                    844: --*/
                    845: 
                    846: {
                    847:     PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
                    848:     PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
                    849:     KIRQL currentIrql;
                    850: 
                    851:     if (currentIrpStack->Parameters.DeviceIoControl.IoControlCode ==
                    852:         IOCTL_DISK_PERFORMANCE) {
                    853: 
                    854:         NTSTATUS status;
                    855: 
                    856:         //
                    857:         // Verify user buffer is large enough for the performance data.
                    858:         //
                    859: 
                    860:         if (currentIrpStack->Parameters.DeviceIoControl.OutputBufferLength <
                    861:             sizeof(DISK_PERFORMANCE)) {
                    862: 
                    863:             //
                    864:             // Indicate unsuccessful status and no data transferred.
                    865:             //
                    866: 
                    867:             status = STATUS_BUFFER_TOO_SMALL;
                    868:             Irp->IoStatus.Information = 0;
                    869: 
                    870:         } else {
                    871: 
                    872:             PDEVICE_EXTENSION physicalDisk =
                    873:                 deviceExtension->PhysicalDevice->DeviceExtension;
                    874: 
                    875:             //
                    876:             // Copy disk counters to buffer under spinlock protection.
                    877:             //
                    878: 
                    879:             KeAcquireSpinLock(&physicalDisk->Spinlock, &currentIrql);
                    880: 
                    881:             RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
                    882:                           &deviceExtension->DiskCounters,
                    883:                           sizeof(DISK_PERFORMANCE));
                    884: 
                    885:             KeReleaseSpinLock(&physicalDisk->Spinlock, currentIrql);
                    886: 
                    887:             //
                    888:             // Set IRP status to success and indicate bytes transferred.
                    889:             //
                    890: 
                    891:             status = STATUS_SUCCESS;
                    892:             Irp->IoStatus.Information = sizeof(DISK_PERFORMANCE);
                    893:         }
                    894: 
                    895:         //
                    896:         // Complete request.
                    897:         //
                    898: 
                    899:         Irp->IoStatus.Status = status;
                    900:         IoCompleteRequest(Irp, 0);
                    901:         return status;
                    902: 
                    903:     }  else {
                    904: 
                    905:         PIO_STACK_LOCATION nextIrpStack    = IoGetNextIrpStackLocation(Irp);
                    906: 
                    907: #if 0
                    908:         //
                    909:         // Copy stack parameters to next stack.
                    910:         //
                    911: 
                    912:         RtlMoveMemory(nextIrpStack,
                    913:                       currentIrpStack,
                    914:                       sizeof(IO_STACK_LOCATION));
                    915: 
                    916:         //
                    917:         // Set IRP so IoComplete does not call completion routine
                    918:         // for this driver.
                    919:         //
                    920: 
                    921:         IoSetCompletionRoutine(Irp,
                    922:                                NULL,
                    923:                                DeviceObject,
                    924:                                FALSE,
                    925:                                FALSE,
                    926:                                FALSE);
                    927: #endif
                    928: 
                    929:         //
                    930:         // Set current stack back one.
                    931:         //
                    932: 
                    933:         Irp->CurrentLocation++,
                    934:         Irp->Tail.Overlay.CurrentStackLocation++;
                    935: 
                    936:         //
                    937:         // Pass unrecognized device control requests
                    938:         // down to next driver layer.
                    939:         //
                    940: 
                    941:         return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
                    942:     }
                    943: 
                    944: } // end DiskPerfDeviceControl()
                    945: 
                    946: 
                    947: NTSTATUS
                    948: DiskPerfShutdownFlush(
                    949:     IN PDEVICE_OBJECT DeviceObject,
                    950:     IN PIRP Irp
                    951:     )
                    952: 
                    953: /*++
                    954: 
                    955: Routine Description:
                    956: 
                    957:     This routine is called for a shutdown and flush IRPs.  These are sent by the
                    958:     system before it actually shuts down or when the file system does a flush.
                    959: 
                    960: Arguments:
                    961: 
                    962:     DriverObject - Pointer to device object to being shutdown by system.
                    963:     Irp          - IRP involved.
                    964: 
                    965: Return Value:
                    966: 
                    967:     NT Status
                    968: 
                    969: --*/
                    970: 
                    971: {
                    972:     PDEVICE_EXTENSION  deviceExtension = DeviceObject->DeviceExtension;
                    973: 
                    974:     //
                    975:     // Set current stack back one.
                    976:     //
                    977: 
                    978:     Irp->CurrentLocation++,
                    979:     Irp->Tail.Overlay.CurrentStackLocation++;
                    980: 
                    981:     return IoCallDriver(deviceExtension->TargetDeviceObject, Irp);
                    982: 
                    983: } // end DiskPerfShutdownFlush()
                    984: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.