IN LONGLONG SectorCount)
{
BOOLEAN Result = TRUE;
+ BOOLEAN IntResult;
PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb;
LARGE_MCB_MAPPING_ENTRY Node, NeedleRun;
PLARGE_MCB_MAPPING_ENTRY LowerRun, HigherRun;
BOOLEAN NewElement;
+ LONGLONG IntLbn;
DPRINT("FsRtlAddBaseMcbEntry(%p, %I64d, %I64d, %I64d)\n", OpaqueMcb, Vbn, Lbn, SectorCount);
goto quit;
}
+ IntResult = FsRtlLookupBaseMcbEntry(OpaqueMcb, Vbn, &IntLbn, NULL, NULL, NULL, NULL);
+ if (IntResult)
+ {
+ if (IntLbn != -1 && IntLbn != Lbn)
+ {
+ Result = FALSE;
+ goto quit;
+ }
+ }
+
/* clean any possible previous entries in our range */
FsRtlRemoveBaseMcbEntry(OpaqueMcb, Vbn, SectorCount);
NeedleRun.RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart + 1;
NeedleRun.StartingLbn.QuadPart = ~0ULL;
Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
- if ((LowerRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun)))
+ if ((LowerRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun)) &&
+ (LowerRun->StartingLbn.QuadPart + (LowerRun->RunEndVbn.QuadPart - LowerRun->RunStartVbn.QuadPart) == Node.StartingLbn.QuadPart))
{
ASSERT(LowerRun->RunEndVbn.QuadPart == Node.RunStartVbn.QuadPart);
Node.RunStartVbn.QuadPart = LowerRun->RunStartVbn.QuadPart;
Node.StartingLbn.QuadPart = LowerRun->StartingLbn.QuadPart;
Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
RtlDeleteElementGenericTable(&Mcb->Mapping->Table, LowerRun);
+ --Mcb->PairCount;
DPRINT("Intersecting lower run found (%I64d,%I64d) Lbn: %I64d\n", LowerRun->RunStartVbn.QuadPart, LowerRun->RunEndVbn.QuadPart, LowerRun->StartingLbn.QuadPart);
}
NeedleRun.RunStartVbn.QuadPart = Node.RunEndVbn.QuadPart;
NeedleRun.RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart + 1;
Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
- if ((HigherRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun)))
+ if ((HigherRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun)) &&
+ (Node.StartingLbn.QuadPart <= HigherRun->StartingLbn.QuadPart))
{
ASSERT(HigherRun->RunStartVbn.QuadPart == Node.RunEndVbn.QuadPart);
Node.RunEndVbn.QuadPart = HigherRun->RunEndVbn.QuadPart;
Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
RtlDeleteElementGenericTable(&Mcb->Mapping->Table, HigherRun);
+ --Mcb->PairCount;
DPRINT("Intersecting higher run found (%I64d,%I64d) Lbn: %I64d\n", HigherRun->RunStartVbn.QuadPart, HigherRun->RunEndVbn.QuadPart, HigherRun->StartingLbn.QuadPart);
}
Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
/* finally insert the resulting run */
RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Node, sizeof(Node), &NewElement);
+ ++Mcb->PairCount
ASSERT(NewElement);
// NB: Two consecutive runs can only be merged, if actual LBNs also match!
{
PBASE_MCB_INTERNAL Mcb = (PBASE_MCB_INTERNAL)OpaqueMcb;
LONGLONG LbnAtVbn0 = -1;
- ULONG Nodes = RtlNumberGenericTableElements(&Mcb->Mapping->Table);
ULONG NumberOfRuns = 0;
DPRINT("FsRtlNumberOfRunsInBaseMcb(%p)\n", OpaqueMcb);
- if (Nodes == 0) goto quit;
+ if (Mcb->PairCount == 0) goto quit;
FsRtlLookupBaseMcbEntry(OpaqueMcb,
0, /* Vbn */
/* Return the number of 'real' and 'hole' runs.
* If we do not have sector 0 as 'real' emulate a 'hole' there.
*/
- NumberOfRuns = Nodes * 2 - (LbnAtVbn0 != -1 ? 1 : 0); /* include holes as runs */
+ NumberOfRuns = Mcb->PairCount * 2 - (LbnAtVbn0 != -1 ? 1 : 0); /* include holes as runs */
quit:
DPRINT("FsRtlNumberOfRunsInBaseMcb(%p) = %d\n", OpaqueMcb, NumberOfRuns);
//ASSERT(NeedleRun.RunEndVbn.QuadPart <= HaystackRun->RunEndVbn.QuadPart);
Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
RtlDeleteElementGenericTable(&Mcb->Mapping->Table, HaystackRun);
+ --Mcb->PairCount;
Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
}
}
}
if (InsertLowerRun)
+ {
ExistingRun = RtlInsertElementGenericTable(&Mcb->Mapping->Table, InsertLowerRun, sizeof(*InsertLowerRun), &NewElement);
+ ++Mcb->PairCount;
+ }
ASSERT(ExistingRun == NULL);