Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
阅读:2365回复:10

diskperf例子中IRP_MJ_READ/IRP_MJ_WRITE处理出错!

楼主#
更多 发布于:2003-01-16 15:12
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]
Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
沙发#
发布于: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 ;
Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
地板#
发布于:2003-01-17 10:53
谢谢!
为何我把RWSpinLock去掉后,一切正常?
我主要是想切割请求,如何才能做到?
Help Me!

Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
地下室#
发布于:2003-01-17 10:55
我试试吧,看是不是这个原因!
Thanks!
Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
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);
Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
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都是一样的了
Leopard
驱动老牛
驱动老牛
  • 注册日期2001-07-13
  • 最后登录2021-12-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望53点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
  • 社区居民
  • 忠实会员
9楼#
发布于:2003-01-20 10:24
Thanks!
kevin73
驱动牛犊
驱动牛犊
  • 注册日期2004-10-27
  • 最后登录2005-06-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-10-28 20:29
学习一下,顺便问一句,diskperf 是disk performance 吗,主要是干什么的?
游客

返回顶部