[fastfat_new]

- Lower importance of some debug messages.
- Add FCB locking routines.
- Lock VCB and FCB in QueryInformation.

svn path=/trunk/; revision=43322
This commit is contained in:
Aleksey Bragin
2009-10-07 10:45:45 +00:00
parent 5cb9dffd80
commit c66ee08233
6 changed files with 160 additions and 22 deletions
@@ -163,20 +163,20 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
/* Get current IRP stack location */
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DPRINT1("FatCommonCreate\n", 0 );
DPRINT1("Irp = %08lx\n", Irp );
DPRINT1("\t->Flags = %08lx\n", Irp->Flags );
DPRINT1("\t->FileObject = %08lx\n", IrpSp->FileObject );
DPRINT1("\t->RelatedFileObject = %08lx\n", IrpSp->FileObject->RelatedFileObject );
DPRINT1("\t->FileName = %wZ\n", &IrpSp->FileObject->FileName );
DPRINT1("\t->AllocationSize.LowPart = %08lx\n", Irp->Overlay.AllocationSize.LowPart );
DPRINT1("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart );
DPRINT1("\t->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer );
DPRINT1("\t->DesiredAccess = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
DPRINT1("\t->Options = %08lx\n", IrpSp->Parameters.Create.Options );
DPRINT1("\t->FileAttributes = %04x\n", IrpSp->Parameters.Create.FileAttributes );
DPRINT1("\t->ShareAccess = %04x\n", IrpSp->Parameters.Create.ShareAccess );
DPRINT1("\t->EaLength = %08lx\n", IrpSp->Parameters.Create.EaLength );
DPRINT("FatCommonCreate\n", 0 );
DPRINT("Irp = %08lx\n", Irp );
DPRINT("\t->Flags = %08lx\n", Irp->Flags );
DPRINT("\t->FileObject = %08lx\n", IrpSp->FileObject );
DPRINT("\t->RelatedFileObject = %08lx\n", IrpSp->FileObject->RelatedFileObject );
DPRINT("\t->FileName = %wZ\n", &IrpSp->FileObject->FileName );
DPRINT("\t->AllocationSize.LowPart = %08lx\n", Irp->Overlay.AllocationSize.LowPart );
DPRINT("\t->AllocationSize.HighPart = %08lx\n", Irp->Overlay.AllocationSize.HighPart );
DPRINT("\t->SystemBuffer = %08lx\n", Irp->AssociatedIrp.SystemBuffer );
DPRINT("\t->DesiredAccess = %08lx\n", IrpSp->Parameters.Create.SecurityContext->DesiredAccess );
DPRINT("\t->Options = %08lx\n", IrpSp->Parameters.Create.Options );
DPRINT("\t->FileAttributes = %04x\n", IrpSp->Parameters.Create.FileAttributes );
DPRINT("\t->ShareAccess = %04x\n", IrpSp->Parameters.Create.ShareAccess );
DPRINT("\t->EaLength = %08lx\n", IrpSp->Parameters.Create.EaLength );
/* Apply a special hack for Win32, idea taken from FASTFAT reference driver from WDK */
if ((IrpSp->FileObject->FileName.Length > sizeof(WCHAR)) &&
@@ -359,7 +359,7 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
{
/* Not a root dir */
ParentDcb = Vcb->RootDcb;
DPRINT1("ParentDcb %p\n", ParentDcb);
DPRINT("ParentDcb %p\n", ParentDcb);
}
/* Check for backslash at the end */
@@ -515,7 +515,7 @@ FatiCreate(IN PFAT_IRP_CONTEXT IrpContext,
ASSERT(FALSE);
}
DPRINT1("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart);
DPRINT("FirstName %wZ, RemainingPart %wZ\n", &FirstName, &RemainingPart);
/* Break if came to the end */
if (!RemainingPart.Length) break;
@@ -579,8 +579,6 @@ FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
PFAT_IRP_CONTEXT IrpContext;
NTSTATUS Status;
DPRINT1("FatCreate()\n");
/* If it's called with our Disk FS device object - it's always open */
// TODO: Add check for CDROM FS device object
if (DeviceObject == FatGlobalData.DiskDeviceObject)
@@ -327,7 +327,7 @@ FatDecodeFileObject(IN PFILE_OBJECT FileObject,
TypeOfOpen = (*Ccb == NULL ? EaFile : UserFileOpen);
DPRINT1("Referencing a file: %Z\n", &(*FcbOrDcb)->FullFileName);
DPRINT("Referencing a file: %Z\n", &(*FcbOrDcb)->FullFileName);
break;
@@ -394,6 +394,95 @@ FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext,
ExReleaseResourceLite(&Vcb->Resource);
}
BOOLEAN
NTAPI
FatAcquireExclusiveFcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PFCB Fcb)
{
RetryLockingE:
/* Try to acquire the exclusive lock*/
if (ExAcquireResourceExclusiveLite(Fcb->Header.Resource,
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
{
/* Wait same way MS's FASTFAT wait, i.e.
checking that there are outstanding async writes,
or someone is waiting on it*/
if (Fcb->OutstandingAsyncWrites &&
((IrpContext->MajorFunction != IRP_MJ_WRITE) ||
!FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) ||
ExGetSharedWaiterCount(Fcb->Header.Resource) ||
ExGetExclusiveWaiterCount(Fcb->Header.Resource)))
{
KeWaitForSingleObject(Fcb->OutstandingAsyncEvent,
Executive,
KernelMode,
FALSE,
NULL);
/* Release the lock */
FatReleaseFcb(IrpContext, Fcb);
/* Retry */
goto RetryLockingE;
}
/* Return success */
return TRUE;
}
/* Return failure */
return FALSE;
}
BOOLEAN
NTAPI
FatAcquireSharedFcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PFCB Fcb)
{
RetryLockingS:
/* Try to acquire the shared lock*/
if (ExAcquireResourceSharedLite(Fcb->Header.Resource,
BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
{
/* Wait same way MS's FASTFAT wait, i.e.
checking that there are outstanding async writes,
or someone is waiting on it*/
if (Fcb->OutstandingAsyncWrites &&
((IrpContext->MajorFunction != IRP_MJ_WRITE) ||
!FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) ||
ExGetSharedWaiterCount(Fcb->Header.Resource) ||
ExGetExclusiveWaiterCount(Fcb->Header.Resource)))
{
KeWaitForSingleObject(Fcb->OutstandingAsyncEvent,
Executive,
KernelMode,
FALSE,
NULL);
/* Release the lock */
FatReleaseFcb(IrpContext, Fcb);
/* Retry */
goto RetryLockingS;
}
/* Return success */
return TRUE;
}
/* Return failure */
return FALSE;
}
VOID
NTAPI
FatReleaseFcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PFCB Fcb)
{
/* Release FCB's resource */
ExReleaseResourceLite(Fcb->Header.Resource);
}
PVOID
FASTCALL
FatMapUserBuffer(PIRP Irp)
@@ -147,6 +147,18 @@ VOID NTAPI
FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PVCB Vcb);
BOOLEAN NTAPI
FatAcquireExclusiveFcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PFCB Fcb);
BOOLEAN NTAPI
FatAcquireSharedFcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PFCB Fcb);
VOID NTAPI
FatReleaseFcb(IN PFAT_IRP_CONTEXT IrpContext,
IN PFCB Fcb);
TYPE_OF_OPEN
NTAPI
FatDecodeFileObject(IN PFILE_OBJECT FileObject,
@@ -283,6 +283,10 @@ typedef struct _FCB
FILE_BASIC_INFORMATION BasicInfo;
/* FullFAT file handle */
FF_FILE *FatHandle;
/* The file has outstanding async writes */
ULONG OutstandingAsyncWrites;
/* The outstanding async writes sync event */
PKEVENT OutstandingAsyncEvent;
union
{
struct
@@ -56,6 +56,17 @@ FatiQueryInternalInformation(IN PFAT_IRP_CONTEXT IrpContext,
UNIMPLEMENTED;
}
VOID
NTAPI
FatiQueryNameInformation(IN PFAT_IRP_CONTEXT IrpContext,
IN PFCB Fcb,
IN PFILE_OBJECT FileObject,
IN OUT PFILE_INTERNAL_INFORMATION Buffer,
IN OUT PLONG Length)
{
UNIMPLEMENTED;
}
NTSTATUS
NTAPI
FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext,
@@ -70,6 +81,7 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext,
PCCB Ccb;
LONG Length;
PVOID Buffer;
BOOLEAN VcbLocked = FALSE, FcbLocked = FALSE;
NTSTATUS Status = STATUS_SUCCESS;
/* Get IRP stack location */
@@ -93,7 +105,26 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext,
DPRINT1("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType);
// TODO: Acquire FCB locks
/* Acquire VCB lock */
if (InfoClass == FileNameInformation ||
InfoClass == FileAllInformation)
{
if (!FatAcquireExclusiveVcb(IrpContext, Vcb))
{
ASSERT(FALSE);
}
/* Remember we locked the VCB */
VcbLocked = TRUE;
}
/* Acquire FCB lock */
// FIXME: If not paging file
if (!FatAcquireSharedFcb(IrpContext, Fcb))
{
ASSERT(FALSE);
}
FcbLocked = TRUE;
switch (InfoClass)
{
@@ -103,6 +134,9 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext,
case FileInternalInformation:
FatiQueryInternalInformation(IrpContext, Fcb, FileObject, Buffer, &Length);
break;
case FileNameInformation:
FatiQueryNameInformation(IrpContext, Fcb, FileObject, Buffer, &Length);
break;
default:
DPRINT1("Unimplemented information class %d requested\n", InfoClass);
Status = STATUS_INVALID_PARAMETER;
@@ -118,7 +152,9 @@ FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext,
/* Set IoStatus.Information to amount of filled bytes */
Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;
// TODO: Release FCB locks
/* Release FCB locks */
if (FcbLocked) FatReleaseFcb(IrpContext, Fcb);
if (VcbLocked) FatReleaseVcb(IrpContext, Vcb);
/* Complete request and return status */
FatCompleteRequest(IrpContext, Irp, Status);
@@ -111,7 +111,6 @@ FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
/* Leave FsRtl critical region */
FsRtlExitFileSystem();
DPRINT1("FatRead()\n");
return Status;
}