mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:37:12 +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
5 changed files with 106 additions and 3 deletions
|
@ -38,7 +38,6 @@ VfatCleanupFile(
|
||||||
if (pFcb->Flags & FCB_IS_VOLUME)
|
if (pFcb->Flags & FCB_IS_VOLUME)
|
||||||
{
|
{
|
||||||
pFcb->OpenHandleCount--;
|
pFcb->OpenHandleCount--;
|
||||||
DeviceExt->OpenHandleCount--;
|
|
||||||
|
|
||||||
if (pFcb->OpenHandleCount != 0)
|
if (pFcb->OpenHandleCount != 0)
|
||||||
{
|
{
|
||||||
|
@ -111,6 +110,11 @@ VfatCleanupFile(
|
||||||
ExReleaseResourceLite(&pFcb->MainResource);
|
ExReleaseResourceLite(&pFcb->MainResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DeviceExt->Flags & VCB_DISMOUNT_PENDING)
|
||||||
|
{
|
||||||
|
VfatCheckForDismount(DeviceExt, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,12 +75,18 @@ VfatCloseFile(
|
||||||
FileObject->FsContext2 = NULL;
|
FileObject->FsContext2 = NULL;
|
||||||
FileObject->FsContext = NULL;
|
FileObject->FsContext = NULL;
|
||||||
FileObject->SectionObjectPointer = NULL;
|
FileObject->SectionObjectPointer = NULL;
|
||||||
|
DeviceExt->OpenHandleCount--;
|
||||||
|
|
||||||
if (pCcb)
|
if (pCcb)
|
||||||
{
|
{
|
||||||
vfatDestroyCCB(pCcb);
|
vfatDestroyCCB(pCcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (DeviceExt->OpenHandleCount == 0)
|
||||||
|
{
|
||||||
|
VfatCheckForDismount(DeviceExt, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -447,6 +447,7 @@ VfatMount(
|
||||||
RtlZeroMemory(DeviceExt, ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)) + sizeof(HASHENTRY*) * HashTableSize);
|
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->FcbHashTable = (HASHENTRY**)((ULONG_PTR)DeviceExt + ROUND_UP(sizeof(DEVICE_EXTENSION), sizeof(ULONG)));
|
||||||
DeviceExt->HashTableSize = HashTableSize;
|
DeviceExt->HashTableSize = HashTableSize;
|
||||||
|
DeviceExt->VolumeDevice = DeviceObject;
|
||||||
|
|
||||||
/* use same vpb as device disk */
|
/* use same vpb as device disk */
|
||||||
DeviceObject->Vpb = Vpb;
|
DeviceObject->Vpb = Vpb;
|
||||||
|
@ -962,7 +963,6 @@ VfatDismountVolume(
|
||||||
|
|
||||||
/* Mark we're being dismounted */
|
/* Mark we're being dismounted */
|
||||||
DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
|
DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
|
||||||
IrpContext->DeviceObject->Vpb->Flags &= ~VPB_MOUNTED;
|
|
||||||
|
|
||||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
ExReleaseResourceLite(&DeviceExt->FatResource);
|
||||||
|
|
||||||
|
|
|
@ -312,3 +312,90 @@ VfatLockUserBuffer(
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
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;
|
ULONG HashTableSize;
|
||||||
struct _HASHENTRY **FcbHashTable;
|
struct _HASHENTRY **FcbHashTable;
|
||||||
|
|
||||||
|
PDEVICE_OBJECT VolumeDevice;
|
||||||
PDEVICE_OBJECT StorageDevice;
|
PDEVICE_OBJECT StorageDevice;
|
||||||
PFILE_OBJECT FATFileObject;
|
PFILE_OBJECT FATFileObject;
|
||||||
FATINFO FatInfo;
|
FATINFO FatInfo;
|
||||||
|
@ -297,7 +298,7 @@ typedef struct DEVICE_EXTENSION
|
||||||
LIST_ENTRY NotifyList;
|
LIST_ENTRY NotifyList;
|
||||||
PNOTIFY_SYNC NotifySync;
|
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;
|
ULONG OpenHandleCount;
|
||||||
|
|
||||||
/* VPBs for dismount */
|
/* VPBs for dismount */
|
||||||
|
@ -928,6 +929,11 @@ VfatLockUserBuffer(
|
||||||
IN ULONG,
|
IN ULONG,
|
||||||
IN LOCK_OPERATION);
|
IN LOCK_OPERATION);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
VfatCheckForDismount(
|
||||||
|
IN PDEVICE_EXTENSION DeviceExt,
|
||||||
|
IN BOOLEAN Create);
|
||||||
|
|
||||||
/* pnp.c */
|
/* pnp.c */
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue