mirror of
https://github.com/reactos/reactos.git
synced 2024-09-27 21:16:34 +00:00
[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? svn path=/trunk/; revision=65372
This commit is contained in:
parent
545615df47
commit
0440330ea6
|
@ -38,7 +38,6 @@ VfatCleanupFile(
|
|||
if (pFcb->Flags & FCB_IS_VOLUME)
|
||||
{
|
||||
pFcb->OpenHandleCount--;
|
||||
DeviceExt->OpenHandleCount--;
|
||||
|
||||
if (pFcb->OpenHandleCount != 0)
|
||||
{
|
||||
|
@ -111,6 +110,11 @@ VfatCleanupFile(
|
|||
ExReleaseResourceLite(&pFcb->MainResource);
|
||||
}
|
||||
|
||||
if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
|
||||
{
|
||||
VfatCheckForDismount(DeviceExt, FALSE);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,12 +75,18 @@ VfatCloseFile(
|
|||
FileObject->FsContext2 = NULL;
|
||||
FileObject->FsContext = NULL;
|
||||
FileObject->SectionObjectPointer = NULL;
|
||||
DeviceExt->OpenHandleCount--;
|
||||
|
||||
if (pCcb)
|
||||
{
|
||||
vfatDestroyCCB(pCcb);
|
||||
}
|
||||
|
||||
if (DeviceExt->OpenHandleCount == 0)
|
||||
{
|
||||
VfatCheckForDismount(DeviceExt, FALSE);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -447,6 +447,7 @@ VfatMount(
|
|||
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 @@ VfatDismountVolume(
|
|||
|
||||
/* Mark we're being dismounted */
|
||||
DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
|
||||
IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
|
||||
|
||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||
|
||||
|
|
|
@ -312,3 +312,90 @@ VfatLockUserBuffer(
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -271,6 +271,7 @@ typedef struct DEVICE_EXTENSION
|
|||
ULONG HashTableSize;
|
||||
struct _HASHENTRY **FcbHashTable;
|
||||
|
||||
PDEVICE_OBJECT VolumeDevice;
|
||||
PDEVICE_OBJECT StorageDevice;
|
||||
PFILE_OBJECT FATFileObject;
|
||||
FATINFO FatInfo;
|
||||
|
@ -297,7 +298,7 @@ typedef struct DEVICE_EXTENSION
|
|||
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 @@ VfatLockUserBuffer(
|
|||
IN ULONG,
|
||||
IN LOCK_OPERATION);
|
||||
|
||||
BOOLEAN
|
||||
VfatCheckForDismount(
|
||||
IN PDEVICE_EXTENSION DeviceExt,
|
||||
IN BOOLEAN Create);
|
||||
|
||||
/* pnp.c */
|
||||
|
||||
NTSTATUS
|
||||
|
|
Loading…
Reference in a new issue