Author: pschweitzer
Date: Mon Nov 10 22:11:36 2014
New Revision: 65372

URL: http://svn.reactos.org/svn/reactos?rev=65372&view=rev
Log:
[FASTFAT]
- Implement VPB swapout in our FAT driver for dismout (see VfatCheckForDismount)
- Dereference volume handles on close (not on cleanup)
- Keep track of the VDO in our VCB
- Let VfatCheckForDismount() do the actual dismount, instead of 
VfatDismountVolume() which just initiates it

CORE-8732 #comment Can you retry?

Modified:
    trunk/reactos/drivers/filesystems/fastfat/cleanup.c
    trunk/reactos/drivers/filesystems/fastfat/close.c
    trunk/reactos/drivers/filesystems/fastfat/fsctl.c
    trunk/reactos/drivers/filesystems/fastfat/misc.c
    trunk/reactos/drivers/filesystems/fastfat/vfat.h

Modified: trunk/reactos/drivers/filesystems/fastfat/cleanup.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat/cleanup.c?rev=65372&r1=65371&r2=65372&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/cleanup.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/cleanup.c [iso-8859-1] Mon Nov 10 
22:11:36 2014
@@ -38,7 +38,6 @@
     if (pFcb->Flags & FCB_IS_VOLUME)
     {
         pFcb->OpenHandleCount--;
-        DeviceExt->OpenHandleCount--;
 
         if (pFcb->OpenHandleCount != 0)
         {
@@ -111,6 +110,11 @@
         ExReleaseResourceLite(&pFcb->MainResource);
     }
 
+    if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
+    {
+        VfatCheckForDismount(DeviceExt, FALSE);
+    }
+
     return STATUS_SUCCESS;
 }
 

Modified: trunk/reactos/drivers/filesystems/fastfat/close.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat/close.c?rev=65372&r1=65371&r2=65372&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/close.c   [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/close.c   [iso-8859-1] Mon Nov 10 
22:11:36 2014
@@ -75,10 +75,16 @@
     FileObject->FsContext2 = NULL;
     FileObject->FsContext = NULL;
     FileObject->SectionObjectPointer = NULL;
+    DeviceExt->OpenHandleCount--;
 
     if (pCcb)
     {
         vfatDestroyCCB(pCcb);
+    }
+
+    if (DeviceExt->OpenHandleCount == 0)
+    {
+        VfatCheckForDismount(DeviceExt, FALSE);
     }
 
     return Status;

Modified: trunk/reactos/drivers/filesystems/fastfat/fsctl.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat/fsctl.c?rev=65372&r1=65371&r2=65372&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/fsctl.c   [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/fsctl.c   [iso-8859-1] Mon Nov 10 
22:11:36 2014
@@ -447,6 +447,7 @@
     RtlZeroMemory(DeviceExt, ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)) 
+ sizeof(HASHENTRY*) * HashTableSize);
     DeviceExt->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + 
ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)));
     DeviceExt->HashTableSize = HashTableSize;
+    DeviceExt->VolumeDevice = DeviceObject;
 
     /* use same vpb as device disk */
     DeviceObject->Vpb = Vpb;
@@ -962,7 +963,6 @@
 
     /* Mark we're being dismounted */
     DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
-    IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
 
     ExReleaseResourceLite(&DeviceExt->FatResource);
 

Modified: trunk/reactos/drivers/filesystems/fastfat/misc.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat/misc.c?rev=65372&r1=65371&r2=65372&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/misc.c    [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/misc.c    [iso-8859-1] Mon Nov 10 
22:11:36 2014
@@ -312,3 +312,90 @@
 
     return STATUS_SUCCESS;
 }
+
+BOOLEAN
+VfatCheckForDismount(
+    IN PDEVICE_EXTENSION DeviceExt,
+    IN BOOLEAN Create)
+{
+    KIRQL OldIrql;
+    PVPB Vpb;
+    BOOLEAN Delete;
+
+    DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Create);
+
+    /* Lock VPB */
+    IoAcquireVpbSpinLock(&OldIrql);
+
+    /* Reference it and check if a create is being done */
+    Vpb = DeviceExt->IoVPB;
+    if (Vpb->ReferenceCount != Create)
+    {
+        /* Copy the VPB to our local own to prepare later dismount */
+        if (DeviceExt->SpareVPB != NULL)
+        {
+            RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
+            DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
+            DeviceExt->SpareVPB->Size = sizeof(VPB);
+            DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
+            DeviceExt->SpareVPB->DeviceObject = NULL;
+            DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & 
VPB_REMOVE_PENDING;
+            DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
+            DeviceExt->SpareVPB = NULL;
+            DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
+        }
+
+        /* Don't do anything */
+        Delete = FALSE;
+    }
+    else
+    {
+        /* Otherwise, delete the volume */
+        Delete = TRUE;
+
+        /* Check if it has a VPB and unmount it */
+        if (Vpb->RealDevice->Vpb == Vpb)
+        {
+            Vpb->DeviceObject = NULL;
+            Vpb->Flags &= ~VPB_MOUNTED;
+        }
+    }
+
+    /* Release lock and return status */
+    IoReleaseVpbSpinLock(OldIrql);
+
+    /* If we were to delete, delete volume */
+    if (Delete)
+    {
+        PVPB DelVpb;
+
+        /* If we have a local VPB, we'll have to delete it
+         * but we won't dismount us - something went bad before
+         */
+        if (DeviceExt->SpareVPB)
+        {
+            DelVpb = DeviceExt->SpareVPB;
+        }
+        /* Otherwise, dismount our device if possible */
+        else
+        {
+            if (DeviceExt->IoVPB->ReferenceCount)
+            {
+                ObfDereferenceObject(DeviceExt->StorageDevice);
+                IoDeleteDevice(DeviceExt->VolumeDevice);
+                return Delete;
+            }
+
+            DelVpb = DeviceExt->IoVPB;
+        }
+
+        /* Delete any of the available VPB and dismount */
+        ExFreePool(DelVpb);
+        ObfDereferenceObject(DeviceExt->StorageDevice);
+        IoDeleteDevice(DeviceExt->VolumeDevice);
+
+        return Delete;
+    }
+
+    return Delete;
+}        

Modified: trunk/reactos/drivers/filesystems/fastfat/vfat.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfat/vfat.h?rev=65372&r1=65371&r2=65372&view=diff
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/vfat.h    [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/vfat.h    [iso-8859-1] Mon Nov 10 
22:11:36 2014
@@ -271,6 +271,7 @@
     ULONG HashTableSize;
     struct _HASHENTRY **FcbHashTable;
 
+    PDEVICE_OBJECT VolumeDevice;
     PDEVICE_OBJECT StorageDevice;
     PFILE_OBJECT FATFileObject;
     FATINFO FatInfo;
@@ -297,7 +298,7 @@
     LIST_ENTRY NotifyList;
     PNOTIFY_SYNC NotifySync;
 
-    /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLEANUP */
+    /* Incremented on IRP_MJ_CREATE, decremented on IRP_MJ_CLOSE */
     ULONG OpenHandleCount;
 
     /* VPBs for dismount */
@@ -928,6 +929,11 @@
     IN ULONG,
     IN LOCK_OPERATION);
 
+BOOLEAN
+VfatCheckForDismount(
+    IN PDEVICE_EXTENSION DeviceExt,
+    IN BOOLEAN Create);
+
 /* pnp.c */
 
 NTSTATUS


Reply via email to