[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:
Pierre Schweitzer 2014-11-10 22:11:36 +00:00
parent 545615df47
commit 0440330ea6
5 changed files with 106 additions and 3 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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