[fastfat_new]
authorAleksey Bragin <aleksey@reactos.org>
Wed, 7 Oct 2009 10:45:45 +0000 (10:45 +0000)
committerAleksey Bragin <aleksey@reactos.org>
Wed, 7 Oct 2009 10:45:45 +0000 (10:45 +0000)
- Lower importance of some debug messages.
- Add FCB locking routines.
- Lock VCB and FCB in QueryInformation.

svn path=/trunk/; revision=43322

reactos/drivers/filesystems/fastfat_new/create.c
reactos/drivers/filesystems/fastfat_new/fastfat.c
reactos/drivers/filesystems/fastfat_new/fastfat.h
reactos/drivers/filesystems/fastfat_new/fatstruc.h
reactos/drivers/filesystems/fastfat_new/finfo.c
reactos/drivers/filesystems/fastfat_new/rw.c

index 730e6d1..33511ae 100644 (file)
@@ -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)
index db45392..52db0af 100644 (file)
@@ -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)
index c700278..e60b9d6 100644 (file)
@@ -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,
index 5d35883..103527b 100644 (file)
@@ -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
index 1183d72..a8005ea 100644 (file)
@@ -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);
index 10aa8f9..9fa1758 100644 (file)
@@ -111,7 +111,6 @@ FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
     /* Leave FsRtl critical region */
     FsRtlExitFileSystem();
 
-    DPRINT1("FatRead()\n");
     return Status;
 }