阅读:2364回复:10
diskperf例子中IRP_MJ_READ/IRP_MJ_WRITE处理出错!
typedef struct {
LARGE_INTEGER dwSecBeg; DWORD dwSecCnt; }SPLIT_TAB,*PSPLIT_TAB; NTSTATUS DispatchReadWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; DWORD TotalLen = Irp->MdlAddress ? MmGetMdlByteCount(Irp->MdlAddress) : 0; if(TotalLen == 0) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION nextstack = IoGetNextIrpStackLocation(Irp); KIRQL oldirql; KeAcquireSpinLock(&pdx->RWSpinLock, &oldirql); // RWSpinLock已经初始化 int MapNum = Split(pdx->pmtst,stack->Parameters.Read.ByteOffset,TotalLen); KeReleaseSpinLock(&pdx->RWSpinLock, oldirql); if(MapNum != 1) { KeBugCheckEx(0xffff0001,0,0,0,0); } KeAcquireSpinLock(&pdx->RWSpinLock, &oldirql); LARGE_INTEGER dwBeg = pdx->pmtst[0].dwSecBeg; KeReleaseSpinLock(&pdx->RWSpinLock, oldirql); stack->Parameters.Read.ByteOffset = dwBeg; *nextstack = *stack; IoSetCompletionRoutine(Irp,DispatchIoCompletion, NULL,TRUE,TRUE,TRUE); return IoCallDriver(pdx->TargetDeviceObject,Irp); } NTSTATUS DispatchIoCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } return STATUS_SUCCESS; } DWORD Split(PSPLIT_TAB pst,LARGE_INTEGER dwSecBeg ,DWORD dwSecCnt) { pst[0].dwSecBeg = dwSecBeg; pst[0].dwSecCnt = dwSecCnt; return 1; } 粗体字部分不加上,一切正常! 粗体字部分加上后,发现数据读写错误,究竟是哪里错了? Help me! [编辑 - 9/6/04 by Leopard] |
|
沙发#
发布于:2003-01-17 09:09
我把RWSpinLock去掉,居然又一切正常!和RWSpinLock有什么关系吗?
Help Me! |
|
板凳#
发布于:2003-01-17 09:49
你为什么要把stack->Parameters.Read.ByteOffset保存起来呢?
Split返回值一定是1 if(MapNum != 1) { KeBugCheckEx(0xffff0001,0,0,0,0); } 就没有什么作用的啊! 你把stack->Parameters.Read.ByteOffset的值修改了吧! 估计问题出在Split函数里面和stack->Parameters.Read.ByteOffset = dwBeg; 这一句话 你尝试一下把 DWORD Split(PSPLIT_TAB pst,PLARGE_INTEGER pSecBeg ,DWORD dwSecCnt) { pst[0].dwSecBeg.QuadPart = pSecBeg->QuadPart ; pst[0].dwSecCnt = dwSecCnt; return 1; } LARGE_INTEGER dwBeg; dwBeg.QuadPart = pdx->pmtst[0].dwSecBeg.QuadPart; stack->Parameters.Read.ByteOffset.QuadPart = dwBeg.QuadPart ; |
|
地板#
发布于:2003-01-17 10:53
谢谢!
为何我把RWSpinLock去掉后,一切正常? 我主要是想切割请求,如何才能做到? Help Me! |
|
地下室#
发布于:2003-01-17 10:55
我试试吧,看是不是这个原因!
Thanks! |
|
5楼#
发布于:2003-01-18 17:12
虽然你没有给出正确答案,我仍然感谢你,付分为证!
其实是Split使用pdx->pmtst有错,应该用局部变量pmtst! |
|
6楼#
发布于:2003-01-20 09:35
你把以下的这些去掉就可以了啊!
KeReleaseSpinLock(&pdx->RWSpinLock, oldirql); if(MapNum != 1) { KeBugCheckEx(0xffff0001,0,0,0,0); } KeAcquireSpinLock(&pdx->RWSpinLock, &oldirql); |
|
7楼#
发布于:2003-01-20 09:46
我的意思是第一次SpinLock保护Split函数,第二次SpinLock保证
传给stack的数据的正确! if(MapNum != 1) { KeBugCheckEx(0xffff0001,0,0,0,0); } 是判断Split的返回值! 其实是Split使用pdx->pmtst有错,应该用局部变量pmtst! 换成局部变量问题就解决,这样对吗? Thanks! |
|
8楼#
发布于:2003-01-20 10:04
是的!因为你的
KIRQL oldirql; KeAcquireSpinLock(&pdx->RWSpinLock, &oldirql); // RWSpinLock已经初始化 int MapNum = Split(pdx->pmtst,stack->Parameters.Read.ByteOffset,TotalLen); KeReleaseSpinLock(&pdx->RWSpinLock, oldirql); 把pdx->pmtst修改了!假如有两个请求一前一后的到来,第一个从这部分代码过去了!到 KeAcquireSpinLock(&pdx->RWSpinLock, &oldirql); LARGE_INTEGER dwBeg = pdx->pmtst[0].dwSecBeg; KeReleaseSpinLock(&pdx->RWSpinLock, oldirql); 停住!第二个进入了上面的代码,把全局变量pdx->pmtst修改了!那么这个时候两个请求的pdx->pmtst都是一样的了 |
|
9楼#
发布于:2003-01-20 10:24
Thanks!
|
|
10楼#
发布于:2004-10-28 20:29
学习一下,顺便问一句,diskperf 是disk performance 吗,主要是干什么的?
|
|