Store a pointer to the parent in the fcb structure and

reference/dereference the parent fcb on create/destroy.

svn path=/trunk/; revision=3984
This commit is contained in:
Hartmut Birr 2003-01-11 15:59:07 +00:00
parent a2aa04440b
commit 3e3f697064

View file

@ -1,4 +1,4 @@
/* $Id: fcb.c,v 1.24 2003/01/02 16:03:56 hbirr Exp $ /* $Id: fcb.c,v 1.25 2003/01/11 15:59:07 hbirr Exp $
* *
* *
* FILE: fcb.c * FILE: fcb.c
@ -104,64 +104,73 @@ vfatReleaseFCB(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
HASHENTRY* entry; HASHENTRY* entry;
ULONG Index; ULONG Index;
ULONG ShortIndex; ULONG ShortIndex;
PVFATFCB tmpFcb;
DPRINT ("releasing FCB at %x: %S, refCount:%d\n", DPRINT ("releasing FCB at %x: %S, refCount:%d\n",
pFCB, pFCB,
pFCB->PathName, pFCB->PathName,
pFCB->RefCount); pFCB->RefCount);
Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE; while (pFCB)
ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE;
KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
pFCB->RefCount--;
if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
{ {
RemoveEntryList (&pFCB->FcbListEntry); Index = pFCB->Hash.Hash % FCB_HASH_TABLE_SIZE;
if (pFCB->Hash.Hash != pFCB->ShortHash.Hash) ShortIndex = pFCB->ShortHash.Hash % FCB_HASH_TABLE_SIZE;
{ KeAcquireSpinLock (&pVCB->FcbListLock, &oldIrql);
entry = pVCB->FcbHashTable[ShortIndex]; pFCB->RefCount--;
if (entry->self == pFCB) if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
{ {
pVCB->FcbHashTable[ShortIndex] = entry->next; tmpFcb = pFCB->parentFcb;
} RemoveEntryList (&pFCB->FcbListEntry);
else if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->ShortHash.next;
}
}
entry = pVCB->FcbHashTable[Index];
if (entry->self == pFCB)
{
pVCB->FcbHashTable[Index] = entry->next;
}
else
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->Hash.next;
}
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
if (vfatFCBIsDirectory(pFCB))
{
/* Uninitialize file cache if initialized for this file object. */
if (pFCB->RFCB.Bcb != NULL)
{ {
CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb); entry = pVCB->FcbHashTable[ShortIndex];
if (entry->self == pFCB)
{
pVCB->FcbHashTable[ShortIndex] = entry->next;
}
else
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->ShortHash.next;
}
} }
vfatDestroyCCB(pFCB->FileObject->FsContext2); entry = pVCB->FcbHashTable[Index];
pFCB->FileObject->FsContext2 = NULL; if (entry->self == pFCB)
ObDereferenceObject(pFCB->FileObject); {
} pVCB->FcbHashTable[Index] = entry->next;
vfatDestroyFCB (pFCB); }
else
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->Hash.next;
}
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
if (vfatFCBIsDirectory(pFCB))
{
/* Uninitialize file cache if initialized for this file object. */
if (pFCB->RFCB.Bcb != NULL)
{
CcRosReleaseFileCache(pFCB->FileObject, pFCB->RFCB.Bcb);
}
vfatDestroyCCB(pFCB->FileObject->FsContext2);
pFCB->FileObject->FsContext2 = NULL;
ObDereferenceObject(pFCB->FileObject);
}
vfatDestroyFCB (pFCB);
}
else
{
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
tmpFcb = NULL;
}
pFCB = tmpFcb;
} }
else
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
} }
VOID VOID
@ -184,6 +193,10 @@ vfatAddFCBToTable(PDEVICE_EXTENSION pVCB, PVFATFCB pFCB)
pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex]; pFCB->ShortHash.next = pVCB->FcbHashTable[ShortIndex];
pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash; pVCB->FcbHashTable[ShortIndex] = &pFCB->ShortHash;
} }
if (pFCB->parentFcb)
{
pFCB->parentFcb->RefCount++;
}
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql); KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
} }
@ -429,6 +442,7 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
{ {
vfatFCBInitializeCacheFromVolume(vcb, rcFCB); vfatFCBInitializeCacheFromVolume(vcb, rcFCB);
} }
rcFCB->parentFcb = directoryFCB;
vfatAddFCBToTable (vcb, rcFCB); vfatAddFCBToTable (vcb, rcFCB);
*fileFCB = rcFCB; *fileFCB = rcFCB;